单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 160|回复: 0
收起左侧

分享:LCD1602温度检测显示程序(ATmega16)

[复制链接]
HI-XM 发表于 2018-12-17 16:50 | 显示全部楼层 |阅读模式
LCD1602温度检测显示程序(ATmega16)

单片机源程序如下:

  1. //**********************************************************************//
  2. //*************************      头文件定义       **********************//
  3. //**********************************************************************//
  4. #include<iom16v.h>
  5. #include <macros.h>

  6. //宏定义
  7. #define uchar unsigned char
  8. #define uint unsigned int

  9. //温度18b20(数据线端口)
  10. #define tmp (PINB&BIT(PB3))
  11. #define temp_h PORTB |= BIT(PB3)
  12. #define temp_l PORTB &=~BIT(PB3)
  13. #define temp_o DDRB |= BIT(PB3)
  14. #define temp_i DDRB &=~BIT(PB3)

  15. //LCD1602液晶显示(数据线端口)
  16. #define rs_h PORTB |= BIT(PB0)//数据/命令选择
  17. #define rs_l PORTB &=~BIT(PB0)
  18. #define rw_h PORTB |= BIT(PB1)//读/写选择
  19. #define rw_l PORTB &=~BIT(PB1)
  20. #define en_h PORTB |= BIT(PB2)//使能信号
  21. #define en_l PORTB &=~BIT(PB2)

  22. //温度18b20(变量定义)
  23. unsigned char dat1=0x00;//保存读出的温度 L
  24. unsigned char dat2=0x00;//保存读出的温度 H
  25. unsigned long int dat=0;//保存读出的温度 XS
  26. unsigned char flag=0;//错误标志位
  27. //按键定义
  28. unsigned char key1=0;
  29. unsigned char key2=0;
  30. //unsigned char key3=0;
  31. //unsigned char key4=0;
  32. //返回值变量
  33. unsigned char keyvalue=0;
  34. //温度H
  35. unsigned char tempH=30;
  36. //温度L
  37. unsigned char tempL=20;

  38. //**********************************************************************//
  39. //*************************      IO 端口定义      **********************//
  40. //**********************************************************************//

  41. void IO_init(void)
  42. {         
  43.          DDRA = 0XFF;
  44.          DDRB = 0XF0;
  45.          DDRC = 0XFF;
  46.          DDRD = 0XFF;
  47.         PORTA = 0X00;
  48.         PORTB = 0X00;
  49.         PORTC = 0XFF;
  50.         PORTD = 0XFF;
  51. }

  52. //**********************************************************************//
  53. //*************************      延时函数         **********************//
  54. //**********************************************************************//

  55. void delayms(uint z)          //8M晶振下,延时1ms
  56. {
  57.          uint x,y;
  58.          for(x=z;x>0;x--)
  59.                   for(y=1333;y>0;y--);
  60. }

  61. //**********************************************************************//
  62. //***************************      18B20        ************************//
  63. //**********************************************************************//

  64. void Ds18b20_reset(void)//DS18B20初始化
  65. {
  66.         uint count;
  67.         temp_o;
  68.         temp_l;
  69.         for(count=700;count>0;count--);//延时480us
  70.         temp_h;
  71.         temp_i;//不须配置PORT内部上拉电阻,MCU输入输出自动切换
  72.         while((tmp==0x08));//&&(i>0)) i--;
  73.         for(count=700;count>0;count--);//延时480us
  74. }
  75. void Ds18b20_write(uchar dat)//向DS18B20写一个字节
  76. {
  77.         uchar count;
  78.         uchar i;
  79.         temp_o;
  80.         for(i=8;i>0;i--)
  81.         {
  82.                 temp_l;
  83.                 for(count=2;count>0;count--);
  84.                 //temp_h;//不能有此语句
  85.                 if(dat&0x01==0x01)
  86.                         temp_h;
  87.                 else
  88.                         temp_l;
  89.                 for(count=120;count>0;count--);//延时60us
  90.                 temp_h;
  91.                 dat>>=1;        
  92.         }        
  93. }
  94. uchar Ds18b20_read(void)//从DS18B20读一个字节
  95. {
  96.         uchar i,datt;
  97.         uchar count;
  98.         for(i=8;i>0;i--)
  99.         {
  100.                 datt>>=1;
  101.                 temp_o;
  102.                 temp_l;
  103.                 for(count=2;count>0;count--);
  104.                 temp_h;//此语句必须有,参考datasheet的P15
  105.                 for(count=1;count>0;count--);
  106.                 temp_i;
  107.                 if(tmp==0x08)
  108.                         datt|=0x80;
  109.                 for(count=120;count>0;count--);        //延时60us
  110.         }
  111.         return datt;
  112. }
  113. void temp_Read(void)//温度读取
  114. {
  115.          Ds18b20_reset();//DS18B20初始化
  116.         Ds18b20_write(0xcc);//跳过ROM
  117.         Ds18b20_write(0x44);//发送温度转换命令
  118.         delayms(1000);//延时1s,等待温度转换完成
  119.         Ds18b20_reset();//DS18B20初始化
  120.         Ds18b20_write(0xcc);//跳过ROM
  121.         Ds18b20_write(0xbe);//发送读温度寄存器命令
  122.         dat1=Ds18b20_read();//读温度值的低字节
  123.         dat2=Ds18b20_read();//读温度值的高字节
  124. }
  125. void temp_display(void)//温度显示
  126. {
  127.         if(dat2>=240)//dat2温度值的高字节为1时为负温度
  128.         {
  129.                 dat=(~(dat2*256+dat1)+1)*0.625;//负温度:取反加一,保留一位小数
  130.                 flag=1;
  131.         }
  132.         else
  133.         {
  134.                 dat=(dat2*256+dat1)*0.625;
  135.                 flag=0;
  136.         }
  137.         if(flag==1)//负温度显示
  138.         {
  139.                  LCD_write_str(0,0," 18B20 ");
  140.                 LCD_write_str(3,1,"Temp:");
  141.                 LCD_write_str(8,1,"-");// 符号“- ”
  142.                 LCD_write_char(9,1,0x30+dat/1000);
  143.                 LCD_write_char(10,1,0x30+dat%1000/100);
  144.                 LCD_write_char(11,1,0x30+dat%100/10);
  145.                 LCD_write_str (12,1,".");// 符号“. ”
  146.                 LCD_write_char(13,1,0x30+dat%10);        
  147.         }
  148.         if(flag==0)//正温度显示
  149.         {           
  150.                 LCD_write_str(0,0," 18B20 ");
  151.                 LCD_write_str(3,1,"Temp:");
  152.                 LCD_write_str(8,1," ");// 符号“+ ”
  153.                 LCD_write_char(9,1,0x30+dat/1000);
  154.                 LCD_write_char(10,1,0x30+dat%1000/100);
  155.                 LCD_write_char(11,1,0x30+dat%100/10);
  156.                 LCD_write_str (12,1,".");// 符号“. ”
  157.                 LCD_write_char(13,1,0x30+dat%10);
  158.         }        
  159. }
  160. void tempH_Setting(void)//最高温度设置显示
  161. {
  162.          LCD_write_str(0,0," temp(H)Setting ");
  163.         LCD_write_char(6,1,0x30+tempH%1000/100);
  164.         LCD_write_char(7,1,0x30+tempH%100/10);
  165.         LCD_write_char(8,1,0x30+tempH%10);
  166. }
  167. void tempL_Setting(void)//最低温度设置显示
  168. {
  169.          LCD_write_str(0,0," temp(L)Setting ");
  170.         LCD_write_char(6,1,0x30+tempL%1000/100);
  171.         LCD_write_char(7,1,0x30+tempL%100/10);
  172.         LCD_write_char(8,1,0x30+tempL%10);
  173. }
  174. void temp_police(void)//温度报警
  175. {
  176.         if(dat/10>=tempH)//最高检测温度>=设定温度:灯亮
  177.         {
  178.                  PORTC&=~BIT(7);
  179.         }
  180.         else
  181.         {
  182.                  PORTC|= BIT(7);
  183.         }
  184.         if(dat/10<=tempL)//最低检测温度<=设定温度:灯亮
  185.         {
  186.                  PORTC&=~BIT(6);
  187.         }
  188.         else
  189.         {
  190.                  PORTC|= BIT(6);
  191.         }
  192. }

  193. //**********************************************************************//
  194. //***************************      LCD1602      ************************//
  195. //**********************************************************************//

  196. void LCD_init(void)//LCD显示屏初始化函数
  197. {
  198.         DDRA = 0xFF;                                                    //I/O口方向设置
  199.         DDRB|=BIT(PB0)|BIT(PB1)|BIT(PB2);
  200.         delayms(15);                           //上电延时一段时间,使供电稳定
  201.         Write_Instruction(0x38);                                //8bit interface,2line,5*7dots
  202.         delayms(5);
  203.         Write_Instruction(0x38);        
  204.         delayms(5);
  205.         Write_Instruction(0x38);        
  206.         Write_Instruction(0x08);        //关显示,不显光标,光标不闪烁
  207.         Write_Instruction(0x01);        //清屏
  208.         delayms(5);
  209.         Write_Instruction(0x04);        //写一字符,整屏显示不移动
  210.         //Write_Instruction(0x05);        //写一字符,整屏右移
  211.         //Write_Instruction(0x06);        //写一字符,整屏显示不移动
  212.         //Write_Instruction(0x07);        //写一字符,整屏左移
  213.         delayms(5);
  214.         //Write_Instruction(0x0B);        //关闭显示(不显示字符,只有背光亮)
  215.         Write_Instruction(0x0C);        //开显示,光标、闪烁都关闭
  216.         //Write_Instruction(0x0D);        //开显示,不显示光标,但光标闪烁
  217.         //Write_Instruction(0x0E);        //开显示,显示光标,但光标不闪烁
  218.         //Write_Instruction(0x0F);        //开显示,光标、闪烁均显示
  219. }
  220. void lcd_en(void)        //en端产生一个高电平脉冲,控制LCD写时序
  221. {
  222.         delayms(1);
  223.         en_h;
  224.     delayms(1);
  225.     en_l;
  226. }
  227. void LCD_clear(void)//清屏函数
  228. {
  229.   Write_Instruction(0x01);
  230.   delayms(5);
  231. }
  232. void Write_Instruction(uchar com)//向LCD1602写命令
  233. {
  234.         rs_l;
  235.         rw_l;
  236.         en_h;
  237.         PORTA=com;
  238.         lcd_en();//写入命令
  239. }
  240. void lcd_dat(uchar dat)//向LCD1602写数据
  241. {
  242.         rs_h;
  243.         rw_l;
  244.         en_h;
  245.         PORTA=dat;
  246.         lcd_en();//写入数据
  247. }
  248. void LCD_SET_XY(uchar X,uchar Y)//字符显示初始地址设置
  249. {
  250.   uchar address;
  251.   if(Y==0)
  252.     address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80
  253.   else
  254.     address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0XC0
  255.     Write_Instruction(address);//写指令,设置显示初始地址
  256. }
  257. void LCD_write_str(uchar X,uchar Y,uchar *s)//在第X行Y列开始显示,指针*S所指向的字符串
  258. {
  259.   LCD_SET_XY(X,Y);//设置初始字符显示地址
  260.   while(*s)//逐次写入显示字符,直到最后一个字符"/0"
  261.   {
  262.     lcd_dat(*s);//写入当前字符并显示
  263.         s++;//地址指针加1,指向下一个待写字符
  264.   }
  265. }
  266. void LCD_write_char(uchar X,uchar Y,uchar Wdata)//在第X行Y列开始显示Wdata所对应的单个字符
  267. {
  268.   LCD_SET_XY(X,Y);//写地址
  269.   lcd_dat(Wdata);//写入当前字符并显示
  270. }
  271. void LCD_Start(void)//LCD启动界面
  272. {
  273.          LCD_write_str(0,0,"  18B20         ");
  274.         LCD_write_str(0,1,"  temp display  ");
  275. }
  276. //**********************************************************************//
  277. //***************************      按键扫描     ************************//
  278. //**********************************************************************//

  279. uchar keys(void)
  280. {
  281.         if(!(PIND&BIT(0)))//温度显示
  282.         {
  283.                 delayms(20);
  284.                 if(!(PIND&BIT(0)))
  285.                 {
  286.                         LCD_clear();//LCD清屏
  287.                         keyvalue=0;
  288.                         while(!(PIND&BIT(0)));//等待按键抬起
  289.                 }
  290.         }
  291.         if(!(PIND&BIT(1)))//最高、最低温度设置选择
  292.         {
  293.                 delayms(20);
  294.                 if(!(PIND&BIT(1)))
  295.                 {
  296.                         LCD_clear();//LCD清屏
  297.                         key1=key1+1;
  298.                         switch(key1)
  299.                         {
  300.                                  case 1:
  301.                                            tempH_Setting();//最高温度设置显示
  302.                                            keyvalue=1;//按键最高温度返回值:1
  303.                                 break;
  304.                                 case 2:
  305.                                            tempL_Setting();//最低温度设置显示
  306.                                            keyvalue=2;//按键最低温度返回值:2
  307.                                            key1=0;//按键清零
  308.                                 break;
  309.                         }
  310.                         while(!(PIND&BIT(1)));//等待按键抬起
  311.                 }
  312.         }
  313.         if(!(PIND&BIT(2)))//温度加
  314.         {
  315.                 delayms(20);
  316.                 if(!(PIND&BIT(2)))
  317.                 {
  318.                         if(keyvalue==1)
  319.                         {
  320.                                  tempH++;
  321.                                 if(tempH>=100)
  322.                                 {
  323.                                          tempH=100;
  324.                                 }
  325.                                 tempH_Setting();//最高温度设置显示
  326.                         }
  327.                         else if(keyvalue==2)
  328.                         {
  329.                                  tempL++;
  330.                                 if(tempL>=100)
  331.                                 {
  332.                                          tempL=100;
  333.                                 }
  334.                                 tempL_Setting();//最低温度设置显示
  335.                         }
  336.                         //while(!(PIND&BIT(2)));//等待按键抬起
  337.                 }
  338.         }
  339.         if(!(PIND&BIT(3)))//温度减
  340.         {
  341.                 delayms(20);
  342.                 if(!(PIND&BIT(3)))
  343.                 {
  344.                         if(keyvalue==1)
  345.                         {
  346.                                  tempH--;
  347.                                 if(tempH<=10)
  348.                                 {
  349.                                          tempH=10;
  350.                                 }
  351.                                 tempH_Setting();//最高温度设置显示
  352.                         }
  353.                         else if(keyvalue==2)
  354.                         {
  355.                                  tempL--;
  356.                                 if(tempL<=10)
  357.                                 {
  358.                                          tempL=10;
  359.                                 }
  360.                                 tempL_Setting();//最低温度设置显示
  361.                         }
  362.                         //while(!(PIND&BIT(3)));//等待按键抬起
  363.                 }
  364.         }
  365. }

  366. //**********************************************************************//
  367. //***************************      主函数       ************************//
  368. //**********************************************************************//

  369. void main(void)
  370. {
  371.         uchar key_j;
  372.         IO_init();        //端口初始化
  373.         LCD_init(); //LCD初始化
  374.         LCD_clear();//LCD清屏
  375.         //LCD_Start();//LCD启动界面
  376.         while(1)
  377.         {
  378.                 keys();
  379.                 if(keyvalue==0)
  380.                 {
  381.                          temp_Read();//温度读取
  382.                         temp_display();//温度显示
  383.                         temp_police();//温度报警
  384.                 }
  385.         }
  386. }
复制代码

所有资料51hei提供下载:
LCD1602&amp;DS18B20温度测试.zip (254.85 KB, 下载次数: 10)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机.

Powered by 单片机教程网

快速回复 返回顶部 返回列表