单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 688|回复: 2
收起左侧

ATmeg16单片机+LCD12864温度检测显示程序(并行控制,不带字库)

[复制链接]
HI-XM 发表于 2018-12-17 16:45 | 显示全部楼层 |阅读模式
LCD12864温度检测显示程序(ATmega16)
制作出来的实物图如下:

LCD12864

LCD12864


单片机源程序如下:
  1. /*---------------------------------------------------------------
  2. ATmega64并行控制不带字库的12864程序
  3. ---------------------------------------------------------------
  4. 实验内容:LCD12864
  5. ---------------------------------------------------------------

  6. 硬件连接:
  7. LCD12864         --------        ATmega64

  8. 1.GND            --------        GND
  9. 2.VCC            --------        VCC
  10. 3.V0             --------        NC
  11. 4.RS(CS)         --------        PB0
  12. 5.R/W(SID)       --------        PB1
  13. 6.E(SCLK)        --------        PB2
  14. 7.D0             --------        PA0
  15. 8.D1             --------        PA1
  16. 9.D2             --------        PA2
  17. 10.D3            --------        PA3
  18. 11.D4            --------        PA4
  19. 12.D5            --------        PA5
  20. 13.D6            --------        PA6
  21. 14.D7            --------        PA7
  22. 15.PSB           --------        VCC
  23. 16.NC            --------        NC
  24. 17.RST           --------        VCC
  25. 18.NC            --------        NC
  26. 19.LED+          --------        VCC
  27. 20.LED-          --------        GND

  28. 编译烧写该程序到ATmega64
  29. 上电,如果操作正确,这时您可以看到显示的内容了
  30. ---------------------------------------------------------------*/
  31. //头文件定义
  32. #include<iom16v.h>
  33. #include<macros.h>
  34. //#include<string.h>
  35. //#include <stdio.h>
  36. //#include<stdlib.h>
  37. //宏定义
  38. #define uchar unsigned char
  39. #define uint unsigned int
  40. //LCD12864液晶显示(数据线端口)
  41. #define rs_h PORTB |= BIT(PB0)//数据/命令选择
  42. #define rs_l PORTB &=~BIT(PB0)
  43. #define rw_h PORTB |= BIT(PB1)//读/写选择
  44. #define rw_l PORTB &=~BIT(PB1)
  45. #define en_h PORTB |= BIT(PB2)//使能信号
  46. #define en_l PORTB &=~BIT(PB2)
  47. //温度18b20(数据线端口)
  48. #define tmp (PINB&BIT(PB3))
  49. #define temp_h PORTB |= BIT(PB3)
  50. #define temp_l PORTB &=~BIT(PB3)
  51. #define temp_o DDRB |= BIT(PB3)
  52. #define temp_i DDRB &=~BIT(PB3)
  53. //数组定义
  54. /*
  55. unsigned char dis1[]={"黄俊华,啊蠢。"};
  56. unsigned char dis2[]={"曾志成,啊成。"};
  57. unsigned char dis3[]={"梁毓毅,啊毓。"};
  58. unsigned char dis4[]={"柳艺明,啊明。"};

  59. unsigned char dis1[]={"温度检测"};
  60. unsigned char dis2[]={"℃"};
  61. */

  62. //温度18b20(变量定义)
  63. unsigned char dat1=0x00;//保存读出的温度 L
  64. unsigned char dat2=0x00;//保存读出的温度 H
  65. unsigned long int dat=0;//保存读出的温度 XS
  66. unsigned char flag=0;//错误标志位
  67. unsigned char keyvalue=0;//返回值变量
  68. unsigned char tempH=30;//温度H
  69. unsigned char tempL=20;//温度L
  70. //按键定义
  71. unsigned char key1=0;
  72. unsigned char key2=0;
  73. //unsigned char key3=0;
  74. //unsigned char key4=0;

  75. //**********************************************************************//
  76. //*************************      IO 端口定义      **********************//
  77. //**********************************************************************//

  78. void IO_init(void)
  79. {         
  80.          DDRA = 0XFF;
  81.          DDRB = 0XFF;
  82.          //DDRC = 0XFF;
  83.          //DDRD = 0XFF;
  84.         //PORTA = 0X00;
  85.         //PORTB = 0X00;
  86.         //PORTC = 0X00;
  87.         //PORTD = 0X00;
  88. }

  89. //**********************************************************************//
  90. //*************************      延时函数         **********************//
  91. //**********************************************************************//

  92. void delayms(uint z)          //8M晶振下,延时1ms
  93. {
  94.         uint x,y;
  95.         for(x=z;x>0;x--)
  96.                  for(y=1333;y>0;y--);
  97. }

  98. //**********************************************************************//
  99. //*************************      LCD12864         **********************//
  100. //**********************************************************************//
  101. void LCD_clear(void)//清屏函数
  102. {
  103.   write_com(0x01);
  104.   delayms(5);
  105. }
  106. void lcd_en(void)        //en端产生一个高电平脉冲,控制LCD写时序
  107. {
  108.         delayms(5);//延时5ms
  109.         en_h;
  110.     delayms(5);//延时5ms
  111.     en_l;
  112. }
  113. void write_com(uchar com)//向LCD12864写命令
  114. {
  115.         rs_l;
  116.         rw_l;
  117.         en_h;
  118.         delayms(5);//延时5ms
  119.         PORTA=com;
  120.         lcd_en();//写入命令
  121. }
  122. void write_dat(uchar dat)//向LCD12864写数据
  123. {
  124.         rs_h;
  125.         rw_l;
  126.         en_h;
  127.         delayms(5);//延时5ms
  128.         PORTA=dat;
  129.         lcd_en();//写入数据
  130. }
  131. void LCD_init(void)//LCD显示屏初始化函数
  132. {
  133.         write_com(0x30);//设置8位数据总线,DB7~DB0;
  134.         delayms(5);//延时5ms
  135.         write_com(0x0c);//开显示,光标不显示;
  136.         delayms(5);//延时5ms
  137.         write_com(0x01);//清屏
  138.         delayms(5);//延时5ms
  139. }
  140. void LCD_pos(uchar x,uchar y)//字符显示初始地址设置
  141. {
  142.         uchar pos;
  143.         if(x==0)//第一行显示
  144.         {
  145.                  x=0x80;
  146.         }
  147.         else if(x==1)//第二行显示
  148.         {
  149.                  x=0x90;
  150.         }
  151.         else if(x==2)//第三行显示
  152.         {
  153.                  x=0x88;
  154.         }
  155.         else if(x==3)//第四行显示
  156.         {
  157.                  x=0x98;
  158.         }
  159.         pos=x+y;
  160.         write_com(pos);
  161. }
  162. void LCD_write_str(uchar x,uchar y,uchar *s)//在第X行Y列开始显示,指针*S所指向的字符串
  163. {
  164.         LCD_pos(x,y);//设置初始字符显示地址
  165.         while(*s)//逐次写入显示字符,直到最后一个字符"/0"
  166.         {
  167.                  write_dat(*s);//写入当前字符并显示
  168.                 s++;//地址指针加1,指向下一个待写字符
  169.         }
  170. }
  171. void LCD_write_char(uchar x,uchar y,uchar Wdata)//在第X行Y列开始显示Wdata所对应的单个字符
  172. {
  173.         LCD_pos(x,y);//设置初始字符显示地址
  174.         write_dat(Wdata);//写入当前字符并显示
  175. }

  176. //**********************************************************************//
  177. //*************************         18B20         **********************//
  178. //**********************************************************************//

  179. void Ds18b20_reset(void)//DS18B20初始化
  180. {
  181.         uint count;
  182.         temp_o;
  183.         temp_l;
  184.         for(count=700;count>0;count--);//延时480us
  185.         temp_h;
  186.         temp_i;//不须配置PORT内部上拉电阻,MCU输入输出自动切换
  187.         while((tmp==0x08));//&&(i>0)) i--;
  188.         for(count=700;count>0;count--);//延时480us
  189. }
  190. void Ds18b20_write(uchar dat)//向DS18B20写一个字节
  191. {
  192.         uchar count;
  193.         uchar i;
  194.         temp_o;
  195.         for(i=8;i>0;i--)
  196.         {
  197.                 temp_l;
  198.                 for(count=2;count>0;count--);
  199.                 //temp_h;//不能有此语句
  200.                 if(dat&0x01==0x01)
  201.                         temp_h;
  202.                 else
  203.                         temp_l;
  204.                 for(count=120;count>0;count--);//延时60us
  205.                 temp_h;
  206.                 dat>>=1;       
  207.         }       
  208. }
  209. uchar Ds18b20_read(void)//从DS18B20读一个字节
  210. {
  211.         uchar i,datt;
  212.         uchar count;
  213.         for(i=8;i>0;i--)
  214.         {
  215.                 datt>>=1;
  216.                 temp_o;
  217.                 temp_l;
  218.                 for(count=2;count>0;count--);
  219.                 temp_h;//此语句必须有,参考datasheet的P15
  220.                 for(count=1;count>0;count--);
  221.                 temp_i;
  222.                 if(tmp==0x08)
  223.                         datt|=0x80;
  224.                 for(count=120;count>0;count--);        //延时60us
  225.         }
  226.         return datt;
  227. }
  228. void temp_display(void)//温度显示
  229. {
  230.         Ds18b20_reset();//DS18B20初始化
  231.         Ds18b20_write(0xcc);//跳过ROM
  232.         Ds18b20_write(0x44);//发送温度转换命令
  233.         delayms(1000);//延时1s,等待温度转换完成
  234.         Ds18b20_reset();//DS18B20初始化
  235.         Ds18b20_write(0xcc);//跳过ROM
  236.         Ds18b20_write(0xbe);//发送读温度寄存器命令
  237.         dat1=Ds18b20_read();//读温度值的低字节
  238.         dat2=Ds18b20_read();//读温度值的高字节
  239.        
  240.         if(dat2>=240)//dat2温度值的高字节为1时为负温度
  241.         {
  242.                 dat=(~(dat2*256+dat1)+1)*0.625;//负温度:取反加一,保留一位小数
  243.                 flag=1;
  244.         }
  245.         else
  246.         {
  247.                 dat=(dat2*256+dat1)*0.625;
  248.                 flag=0;
  249.         }
  250. /*******************************************************   正负温度显示   **/
  251.         if(flag==1)//负温度显示
  252.         {
  253.                 LCD_write_str(0,0,"18B20 温度检测");  //字符:18B20 温度检测
  254.                 LCD_write_str(1,0,"负温度:");                       //字符:负温度
  255.                 LCD_write_str(1,6,"℃");                          //符号:℃
  256.                 LCD_write_char(1,4,0x30+dat/100);
  257.                 LCD_write_char(1,5,0x30+dat%100/10);
  258.         }
  259.         if(flag==0)//正温度显示
  260.         {          
  261.                 LCD_write_str(0,0,"18B20 温度检测");  //字符:18B20 温度检测
  262.                 LCD_write_str(1,0,"正温度:");                //字符:正温度
  263.                 LCD_write_str(1,6,"℃");                          //符号:℃
  264.                 LCD_write_char(1,4,0x30+dat/100);
  265.                 LCD_write_char(1,5,0x30+dat%100/10);
  266.         }
  267. }
  268. void tempH_Setting(void)//最高温度设置显示
  269. {
  270.         LCD_write_str(0,1,"18B20 (高)");          //字符:18B20 高温度设置
  271.         LCD_write_str(1,0,"温度设置:");                  //字符:高温度设置
  272.         LCD_write_str(1,7,"℃");                          //符号:℃
  273.         LCD_write_char(1,5,0x30+tempH%100/10);
  274.         LCD_write_char(1,6,0x30+tempH%10);
  275. }
  276. void tempL_Setting(void)//最低温度设置显示
  277. {
  278.         LCD_write_str(0,1,"18B20 (低)");          //字符:18B20 低温度设置
  279.         LCD_write_str(1,0,"温度设置:");                  //字符:18B20 低温度设置
  280.         LCD_write_str(1,7,"℃");                          //符号:℃
  281.         LCD_write_char(1,5,0x30+tempL%100/10);
  282.         LCD_write_char(1,6,0x30+tempL%10);
  283. }
  284. void temp_police(void)//温度报警
  285. {
  286.         if(dat/10>=tempH)//最高检测温度>=设定温度:D1灯亮
  287.         {
  288.                  PORTC&=~BIT(0);
  289.                 LCD_write_str(3,0,"D1: 亮");            
  290.         }
  291.         else//反之:灯灭
  292.         {
  293.                  PORTC|= BIT(0);
  294.                 LCD_write_str(3,0,"D1: 灭");
  295.         }
  296.        
  297.         if(dat/10<=tempL)//最低检测温度<=设定温度:D2灯亮
  298.         {
  299.                  PORTC&=~BIT(1);
  300.                 LCD_write_str(3,4,"D2: 亮");
  301.         }
  302.         else//反之:灯灭
  303.         {
  304.                  PORTC|= BIT(1);
  305.                 LCD_write_str(3,4,"D2: 灭");
  306.         }       
  307. }
  308. //**********************************************************************//
  309. //***************************      按键扫描     ************************//
  310. //**********************************************************************//

  311. uchar keys(void)
  312. {
  313.         if(!(PIND&BIT(0)))//温度显示
  314.         {
  315.                 delayms(20);
  316.                 if(!(PIND&BIT(0)))
  317.                 {
  318.                         LCD_clear();//LCD清屏
  319.                         keyvalue=0;
  320.                         while(!(PIND&BIT(0)));//等待按键抬起
  321.                 }
  322.         }
  323.         if(!(PIND&BIT(1)))//最高、最低温度设置选择
  324.         {
  325.                 delayms(20);
  326.                 if(!(PIND&BIT(1)))
  327.                 {
  328.                         LCD_clear();//LCD清屏
  329.                         key1=key1+1;
  330.                         switch(key1)
  331.                         {
  332.                                  case 1:
  333.                                            tempH_Setting();//最高温度设置显示
  334.                                            temp_police();//温度报警
  335.                                            //temp_display();//温度显示
  336.                                            keyvalue=1;//按键最高温度返回值:1
  337.                                 break;
  338.                                 case 2:
  339.                                            tempL_Setting();//最低温度设置显示
  340.                                            temp_police();//温度报警
  341.                                            //temp_display();//温度显示
  342.                                            keyvalue=2;//按键最低温度返回值:2
  343.                                            key1=0;//按键清零
  344.                                 break;
  345.                         }
  346.                         while(!(PIND&BIT(1)));//等待按键抬起
  347.                 }
  348.         }
  349.         if(!(PIND&BIT(2)))//温度加
  350.         {
  351.                 delayms(20);
  352.                 if(!(PIND&BIT(2)))
  353.                 {
  354.                         if(keyvalue==1)
  355.                         {
  356.                                  tempH++;
  357.                                 if(tempH>=100)
  358.                                 {
  359.                                          tempH=100;
  360.                                 }
  361.                                 tempH_Setting();//最高温度设置显示
  362.                                 temp_police();//温度报警
  363.                                 //temp_display();//温度显示
  364.                         }
  365.                         else if(keyvalue==2)
  366.                         {
  367.                                  tempL++;
  368.                                 if(tempL>=100)
  369.                                 {
  370.                                          tempL=100;
  371.                                 }
  372.                                 tempL_Setting();//最低温度设置显示
  373.                                 temp_police();//温度报警
  374.                                 //temp_display();//温度显示
  375.                         }
  376.                         //while(!(PIND&BIT(2)));//等待按键抬起
  377.                 }
  378.         }
  379.         if(!(PIND&BIT(3)))//温度减
  380.         {
  381.                 delayms(20);
  382.                 if(!(PIND&BIT(3)))
  383.                 {
  384.                         if(keyvalue==1)
  385.                         {
  386.                                  tempH--;
  387.                                 if(tempH<=10)
  388.                                 {
  389.                                          tempH=10;
  390.                                 }
  391.                                 tempH_Setting();//最高温度设置显示
  392.                                 temp_police();//温度报警
  393.                                 //temp_display();//温度显示
  394.                         }
  395.                         else if(keyvalue==2)
  396.                         {
  397.                                  tempL--;
  398.                                 if(tempL<=10)
  399.                                 {
  400.                                          tempL=10;
  401.                                 }
  402.                                 tempL_Setting();//最低温度设置显示
  403.                                 temp_police();//温度报警
  404.                                 //temp_display();//温度显示
  405.                         }
  406.                         //while(!(PIND&BIT(3)));//等待按键抬起
  407.                 }
  408.         }
  409. }

  410. //**********************************************************************//
  411. //***************************      主函数       ************************//
  412. //**********************************************************************//

  413. void main()
  414. {
  415.         uchar i;
  416.         IO_init();//端口初始化
  417.         LCD_init();//LCD显示屏初始化函数
  418.         while(1)
  419.         {
  420.                 keys();//按键扫描
  421.                 if(keyvalue==0)
  422.                 {
  423.                          temp_display();//温度显示
  424.                         temp_police();//温度报警
  425.                 }
  426.         }
  427. }
复制代码

所有资料51hei提供下载:
LCD12864(ATmeg16).zip (58.13 KB, 下载次数: 7)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

dzc2018 发表于 2018-12-26 13:47 | 显示全部楼层
谢谢分享
回复

使用道具 举报

51单片机1234 发表于 2018-12-28 16:38 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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