芯片为EP2C8Q208C8,晶振50M。
SOPC配置为经济型nios ii core(与延迟函数有关),4k片上rom(放程序),4k片上ram(放数据),一个8位的输出io:lcd_d,3个一位的输出io,分别为e,rs,rw。一个三态IO口onewire。
代码已在硬件平台上测试通过。
nios ii源码(1602显示程序其它文章中有就不贴了)如下:
delay.h
void delay_ms(alt_u8 ms)
{
alt_u16 i;
while(ms--)
for(i=0;i<1000;i++);
}
//微秒延迟
void delay_us(alt_u16 us)
{
alt_16 i;
for(i=0;i<us;i++);
}
Ds18b20.c
/********************************************************
* file name:ds18b20.h
* designer:kang
* date:2010-11-05
* version:v1.00
* ******************************************************/
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "delay.h"
unsigned char ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
/**********************************************************/
unsigned char Init_DS18B20(void)//初始化ds1820
{
unsigned char presence;
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1); //DQ复位
delay_us(40); //稍做延时
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,0); //单片机将DQ拉低
delay_us(550); //精确延时 大于 480us
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1); //拉高总线
delay_us(30);
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,0); //输入
delay_us(60);
presence = IORD_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE); //如果=0则初始化成功 =1则初始化失败
delay_us(480);
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1); //拉高
return(presence); //返回信号,0=presence,1= no presence
}
/**********************************************************/
unsigned char ReadOneChar(void)//读一个字节
{
unsigned char i = 0;
unsigned char dat = 0;
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1);
delay_us(10);
for (i = 8; i > 0; i--)
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,0); // 给脉冲信号
delay_us(2);
dat >>= 1;
// IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1); // 给脉冲信号
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,0); //输入
delay_us(2);
if(IORD_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE)) dat|=0x80;
delay_us(40);
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1);
delay_us(10);
}
return (dat);
}
/**********************************************************/
void WriteOneChar(unsigned char dat)//写一个字节
{
unsigned char i = 0;
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1);
delay_us(10);
for (i = 8; i > 0; i--)
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(ONEWIRE_BASE,1); //输出
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,0);
delay_us(2);
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,(dat&0x01));
delay_us(40);
IOWR_ALTERA_AVALON_PIO_DATA(ONEWIRE_BASE,1);
dat>>=1;
delay_us(10);
}
}
/*********************************************************/
unsigned char Read_Temperature(unsigned char *temp_data)//读取温度
{
if(Init_DS18B20()) return(1);
//DS18B20不正常
else{
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
while(ReadOneChar()!=0xff);
if(Init_DS18B20()) return(1);
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
temp_data[0] = ReadOneChar(); //温度低8位
temp_data[1] = ReadOneChar(); //温度高8位
Init_DS18B20();
}
return(0);
}
//返回ds18b20数据
unsigned char ds18b20(unsigned char *temp)
{
unsigned char temp_data[2];
unsigned char a;
if(Read_Temperature(temp_data))
return(1);
else {
a=temp_data[0]&0x0f;
temp[0]=ditab[a]; //查表得小数位的值
a=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
temp[3]=a/100;
temp[1]=a%100;
temp[2]=temp[1]/10;
temp[1]=temp[1]%10;
}
return(0);
}
/*********************************************************/
Main.c
/********************************************************
* file name:main.c
* designer:kang
* date:2010-11-05
* version:v1.00
* ******************************************************/
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "lcd1602.h"
#include "ds18b20.h"
void init()
{
delay_ms(20);
lcd_init();
lcd_pos(0x80);
lcd_disp("temp:",5);
lcd_pos(0xc4);
lcd_disp("made by kang",12);
}
int alt_main()
{
unsigned char temp[4];
init();
while(1)
{
if(ds18b20(temp))
{
lcd_pos(0x85);
lcd_disp("error!",6);
}
else {
lcd_pos(0x85);
lcd_wdat(temp[3]+0x30);
lcd_wdat(temp[2]+0x30);
lcd_wdat(temp[1]+0x30);
lcd_wdat('.');
lcd_wdat(temp[0]+0x30);
}
}
}
用户446166 2015-10-20 10:46
用户377235 2013-6-20 18:14