找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机温度显示小制作 仿真图+源程序

[复制链接]
ID:203329 发表于 2017-5-22 20:58 | 显示全部楼层 |阅读模式
仿真图+源程序,希望大家能够有所收获呀
0.png 0.png

单片机源程序如下:

  1. #include<reg51.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #include<stdio.h>

  3. sbit RS = P2^4;   //定义端口
  4. sbit RW = P2^5;
  5. sbit EN = P2^6;
  6. sbit DQ = P3^4;

  7. #define RS_CLR RS=0
  8. #define RS_SET RS=1

  9. #define RW_CLR RW=0
  10. #define RW_SET RW=1

  11. #define EN_CLR EN=0
  12. #define EN_SET EN=1

  13. #define DataPort P0

  14. bit ReadTempFlag;//定义读时间标志


  15. void DelayUs2x(unsigned char t)
  16. {   
  17. while(--t);
  18. }
  19. /*------------------------------------------------
  20. mS延时函数,含有输入参数 unsigned char t,无返回值
  21. unsigned char 是定义无符号字符变量,其值的范围是
  22. 0~255 这里使用晶振12M,精确延时请使用汇编
  23. ------------------------------------------------*/
  24. void DelayMs(unsigned char t)
  25. {
  26.      
  27. while(t--)
  28. {
  29.      //大致延时1mS
  30.      DelayUs2x(245);
  31.          DelayUs2x(245);
  32. }
  33. }


  34. /*------------------------------------------------
  35.               判忙函数
  36. ------------------------------------------------*/
  37. bit LCD_Check_Busy(void)
  38. {
  39. DataPort= 0xFF;
  40. RS_CLR;
  41. RW_SET;
  42. EN_CLR;
  43. // _nop_();
  44. EN_SET;
  45. return (bit)(DataPort & 0x80);
  46. }
  47. /*------------------------------------------------
  48.               写入命令函数
  49. ------------------------------------------------*/
  50. void LCD_Write_Com(unsigned char com)
  51. {  
  52. // while(LCD_Check_Busy()); //忙则等待
  53. DelayMs(5);
  54. RS_CLR;
  55. RW_CLR;
  56. EN_SET;
  57. DataPort= com;
  58. //_nop_();
  59. EN_CLR;
  60. }
  61. /*------------------------------------------------
  62.               写入数据函数
  63. ------------------------------------------------*/
  64. void LCD_Write_Data(unsigned char Data)
  65. {
  66. //while(LCD_Check_Busy()); //忙则等待
  67. DelayMs(5);
  68. RS_SET;
  69. RW_CLR;
  70. EN_SET;
  71. DataPort= Data;
  72. //_nop_();
  73. EN_CLR;
  74. }


  75. /*------------------------------------------------
  76.                 清屏函数
  77. ------------------------------------------------*/
  78. void LCD_Clear(void)
  79. {
  80. LCD_Write_Com(0x01);
  81. DelayMs(5);
  82. }
  83. /*------------------------------------------------
  84.               写入字符串函数
  85. ------------------------------------------------*/
  86. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  87. {     
  88. if (y == 0)
  89.         {     
  90.          LCD_Write_Com(0x80 + x);     //表示第一行
  91.         }
  92. else
  93.         {      
  94.         LCD_Write_Com(0xC0 + x);      //表示第二行
  95.         }        
  96. while (*s)
  97.         {     
  98. LCD_Write_Data( *s);     
  99. s ++;     
  100.         }
  101. }
  102. /*------------------------------------------------
  103.               写入字符函数
  104. ------------------------------------------------*/
  105. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  106. {     
  107. if (y == 0)
  108.         {     
  109.         LCD_Write_Com(0x80 + x);     
  110.         }   
  111. else
  112.         {     
  113.         LCD_Write_Com(0xC0 + x);     
  114.         }        
  115. LCD_Write_Data( Data);  
  116. }
  117. /*------------------------------------------------
  118.               初始化函数
  119. ------------------------------------------------*/
  120. void LCD_Init(void)
  121. {
  122.    LCD_Write_Com(0x38);    /*显示模式设置*/
  123.    DelayMs(5);
  124.    LCD_Write_Com(0x38);
  125.    DelayMs(5);
  126.    LCD_Write_Com(0x38);
  127.    DelayMs(5);
  128.    LCD_Write_Com(0x38);  
  129.    LCD_Write_Com(0x08);    /*显示关闭*/
  130.    LCD_Write_Com(0x01);    /*显示清屏*/
  131.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  132.    DelayMs(5);
  133.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  134.    }
  135. /*------------------------------------------------   
  136. 设定二个自定义字符,LCD1602中自定义字符的地址为0x00--0x07,
  137. 即可定义8个字符
  138. 这里我们设定把一个自定义字符放在0x00位置(000),
  139. 另一个放在0x01位子(001)
  140. ------------------------------------------------*/
  141. void Lcd_User_Chr(void)
  142. { //第一个自定义字符
  143. LCD_Write_Com(0x40); //"01 000 000"  第1行地址 (D7D6为地址设定命令形式D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))
  144. LCD_Write_Data(0x00); //"XXX 11111" 第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭)
  145. LCD_Write_Com(0x41); //"01 000 001"  第2行地址
  146. LCD_Write_Data(0x04); //"XXX 10001" 第2行数据
  147. LCD_Write_Com(0x42); //"01 000 010"  第3行地址
  148. LCD_Write_Data(0x0e); //"XXX 10101" 第3行数据
  149. LCD_Write_Com(0x43); //"01 000 011"  第4行地址
  150. LCD_Write_Data(0x0e); //"XXX 10001" 第4行数据
  151. LCD_Write_Com(0x44); //"01 000 100"  第5行地址
  152. LCD_Write_Data(0x0e); //"XXX 11111" 第5行数据
  153. LCD_Write_Com(0x45); //"01 000 101"  第6行地址
  154. LCD_Write_Data(0x1f); //"XXX 01010" 第6行数据
  155. LCD_Write_Com(0x46); //"01 000 110"  第7行地址
  156. LCD_Write_Data(0x04); //"XXX 11111" 第7行数据
  157. LCD_Write_Com(0x47); //"01 000 111"  第8行地址
  158.    LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
  159. //第二个自定义字符

  160. LCD_Write_Com(0x48); //"01 001 000"  第1行地址  
  161. LCD_Write_Data(0x03); //"XXX 00001" 第1行数据
  162. LCD_Write_Com(0x49); //"01 001 001"  第2行地址
  163. LCD_Write_Data(0x03); //"XXX 11011" 第2行数据
  164. LCD_Write_Com(0x4a); //"01 001 010"  第3行地址
  165. LCD_Write_Data(0x00); //"XXX 11101" 第3行数据
  166. LCD_Write_Com(0x4b); //"01 001 011"  第4行地址
  167. LCD_Write_Data(0x00); //"XXX 11001" 第4行数据
  168. LCD_Write_Com(0x4c); //"01 001 100"  第5行地址
  169. LCD_Write_Data(0x00); //"XXX 11101" 第5行数据
  170. LCD_Write_Com(0x4d); //"01 001 101"  第6行地址
  171. LCD_Write_Data(0x00); //"XXX 11011" 第6行数据
  172. LCD_Write_Com(0x4e); //"01 001 110"  第7行地址
  173. LCD_Write_Data(0x00); //"XXX 00001" 第7行数据
  174. LCD_Write_Com(0x4f); //"01 001 111"  第8行地址
  175. LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
  176. }



  177. bit Init_DS18B20(void)
  178. {
  179. bit dat=0;
  180. DQ = 1;    //DQ复位
  181. DelayUs2x(5);   //稍做延时
  182. DQ = 0;         //单片机将DQ拉低
  183. DelayUs2x(200); //精确延时 大于 480us 小于960us
  184. DelayUs2x(200);
  185. DQ = 1;        //拉高总线
  186. DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
  187. dat=DQ;        //如果x=0则初始化成功, x=1则初始化失败
  188. DelayUs2x(25); //稍作延时返回
  189. return dat;
  190. }

  191. /*------------------------------------------------
  192.                     读取一个字节
  193. ------------------------------------------------*/
  194. unsigned char ReadOneChar(void)
  195. {
  196. unsigned char i=0;
  197. unsigned char dat = 0;
  198. for (i=8;i>0;i--)
  199. {
  200.   DQ = 0; // 给脉冲信号
  201.   dat>>=1;
  202.   DQ = 1; // 给脉冲信号
  203.   if(DQ)
  204.    dat|=0x80;
  205.   DelayUs2x(25);
  206. }
  207. return(dat);
  208. }
  209. /*------------------------------------------------
  210.                     写入一个字节
  211. ------------------------------------------------*/
  212. void WriteOneChar(unsigned char dat)
  213. {
  214. unsigned char i=0;
  215. for (i=8; i>0; i--)
  216. {
  217.   DQ = 0;
  218.   DQ = dat&0x01;
  219.   DelayUs2x(25);
  220.   DQ = 1;
  221.   dat>>=1;
  222. }
  223. DelayUs2x(25);
  224. }

  225. /*------------------------------------------------
  226.                     读取温度
  227. ------------------------------------------------*/
  228. unsigned int ReadTemperature(void)
  229. {
  230. unsigned char a=0;
  231. unsigned int b=0;
  232. unsigned int t=0;
  233. Init_DS18B20();
  234. WriteOneChar(0xCC); // 跳过读序号列号的操作
  235. WriteOneChar(0x44); // 启动温度转换
  236. DelayMs(10);
  237. Init_DS18B20();
  238. WriteOneChar(0xCC); //跳过读序号列号的操作
  239. WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  240. a=ReadOneChar();   //低位
  241. b=ReadOneChar();   //高位

  242. b<<=8;
  243. t=a+b;

  244. return(t);
  245. }




  246. void Init_Timer0(void);//定时器初始化
  247. /*------------------------------------------------
  248.               串口通讯初始化
  249. ------------------------------------------------*/
  250. void UART_Init(void)
  251. {
  252.     SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
  253.     TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
  254.     TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
  255.     TR1   = 1;                  // TR1:  timer 1 打开                        
  256.     //EA    = 1;                  //打开总中断
  257.     //ES    = 1;                  //打开串口中断
  258.         TI=1;
  259. }
  260. /*------------------------------------------------
  261.                     主函数
  262. ------------------------------------------------*/
  263. void main (void)
  264. {                  
  265. int temp;
  266. float temperature;
  267. char displaytemp[16];//定义显示区域临时存储数组

  268. LCD_Init();           //初始化液晶
  269. DelayMs(20);          //延时有助于稳定
  270. LCD_Clear();          //清屏
  271. Init_Timer0();
  272. UART_Init();
  273. Lcd_User_Chr();       //写入自定义字符
  274. LCD_Write_String(0,0,"     nihao! ");
  275. LCD_Write_Char(13,1,0x01);//写入温度右上角点
  276. LCD_Write_Char(14,1,'C'); //写入字符C

  277. while (1)         //主循环
  278.   {

  279. if(ReadTempFlag==1)
  280. {
  281.   ReadTempFlag=0;
  282.   temp=ReadTemperature();

  283. ……………………

  284. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
温度显示 源程序 仿真图.zip (129.94 KB, 下载次数: 72)

评分

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

查看全部评分

回复

使用道具 举报

ID:305168 发表于 2018-4-10 14:43 | 显示全部楼层
学习一下。。。
回复

使用道具 举报

ID:330289 发表于 2019-4-11 20:45 | 显示全部楼层
学习学习
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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