原创 nios ii下ds18b20程序

2010-11-5 21:41 2847 8 9 分类: FPGA/CPLD

芯片为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);


    }


    }


}


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户446166 2015-10-20 10:46

我也遇到了这种问题,jtag下载sof可以,jic就不行

用户377235 2013-6-20 18:14

您好 请问这段程序的时钟经过了几分频?
相关推荐阅读
用户282447 2011-01-19 17:05
stm32使用fsmc时地址移位问题
stm32平台使用fsmc时,当操作数据宽度为8位时,HADDR【25:0】与FSMC【25:0】对齐,当操作的数据为16位时,HADDR【25:1】与FSMC【24:0】对齐,HADDR【0】未接。...
用户282447 2011-01-05 19:42
verilog分频
fpga程序里经常会遇见给一个50 MHZ的clk,然后产生一个可变频率的clk‘。尤其是在电机控制中,加减速需要便频率,而fpga中除法又比较耗资源。今天看到一个程序,觉得思想不错,整理如下。   ...
用户282447 2011-01-01 23:47
2011,回顾从前
毕业第一年。    2010很快过去了,大学生活也已经成了历史,貌似很近,又貌似很远。    2011已经来临,是时候该回顾回顾自己大学至今都在做什么了。俗话说,男的把电脑当游戏机,女的把电脑当影碟机...
用户282447 2010-12-24 11:33
sdram verilog程序
sdram芯片用的是hy57v641620hgt-7,fpga用的是EP1C6Q240C8,晶振是50M,经过PLL倍频至125M,系统clk时钟是125M,sdram时钟相移-3ns程序是根据特权的...
用户282447 2010-12-24 11:26
串口verilog程序
发一个自己写的串口程序,波特率115200,一位起始位,8个数据位,一个停止位接收采用8倍过采样。下面有4个module,uart是顶层模块,uart_rx是接收模块,uart_tx是发送模块,uar...
用户282447 2010-11-27 18:58
tft verilog驱动
       使用的TFT为群创7寸液晶屏AT070TN83,分辨率为800*480FPGA为ep1c6q240c8,晶振为50M       首先介绍一下TFT接口       1和2脚VLED,4...
EE直播间
更多
我要评论
1
8
关闭 站长推荐上一条 /3 下一条