找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2197|回复: 1
收起左侧

单片机数码管温度计

[复制链接]
ID:353873 发表于 2018-6-18 21:31 | 显示全部楼层 |阅读模式
四位共阴数码管引脚排列.pdf.jpg QQ截图20180527190050.jpg
  1. /*一、主要功能:
  2. (1)1路温度采集电路.
  3. (2)采集测温范围为-55~+120 ℃.
  4. (3)温度精度在0.1 ℃;误差±0.2℃以内.
  5. (4)显示模块,采用4个LED数码管显示.
  6. (5)按键3个,设置、加、减.
  7. (6)报警设置1-99度.低于下限报警,高于上限报警。
  8. */
  9. #include<reg51.h>
  10. #include<intrins.h>
  11. #define uint unsigned int
  12. #define uchar unsigned char
  13. //-----------------------
  14. sbit S1=P1^0;     //设置 上下限
  15. sbit S2=P1^1;      //加
  16. sbit S3=P1^2;     //减
  17. sbit SEG1=P2^0;      //段码位1
  18. sbit SEG2=P2^2;      //段码位2  
  19. sbit SEG3=P2^4;      //段码位3
  20. sbit SEG4=P2^6;      //段码位4
  21. sbit DQ1=P1^7;       //传感器1
  22. sbit LED1=P3^0;     //报警显示灯
  23. sbit BUZ=P3^1;     //蜂鸣器
  24. uchar DQ1_SET[2];      //DQ1上下限设置     DQ1_SET[0] 下限 DQ1_SET[1] 上限;
  25. uchar Temp;       //温度报警
  26. uchar count;      //蜂鸣器定时用
  27. uchar mode;       //mode=1正常显示 mode=2 设置下限模式 mode=3设置上限  
  28. //////////////////////////////DS18B20////////////////////////////////////////////////
  29. uchar  ng;  //负号标志
  30. uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x58,0x00};//共阴数码码表
  31.                  /* 0    1    2   3    4    5    6    7    8    9     C   无*/

  32. uchar code df_Table[]=   
  33. {
  34.   0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
  35. }; //温度小数位对照表
  36. uchar CurrentT = 0;             //当前读取的温度整数部分
  37. uchar Temp_Value[]={0x00,0x00}; //从DS18B20读取的温度值
  38. uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位
  39. bit DS18B20_IS_OK = 1;          //传感器正常
  40. ////////////////////////////////DS18B20///////////////////////////////////////////////
  41. //************************************************************************/
  42. // 函数: LCD_Delay()
  43. // 描述: 延时t ms函数
  44. // 参数: t
  45. // 返回: 无
  46. // 备注: 12MHZ       t=1延时时间约1ms
  47. //************************************************************************/
  48. void Delay_ms(unsigned int t)
  49. {
  50. unsigned int i,j;
  51. for(i=0;i<t;i++)
  52. for(j=0;j<120;j++)
  53. ;
  54. }
  55. //************************************************************************/
  56. // 函数: LCD_Delay()
  57. // 描述: 延时x us函数
  58. // 参数: t
  59. // 返回: 无
  60. // 备注: 12MHZ       延时时间约us
  61. //************************************************************************/
  62. void Delay(uint x)
  63. {
  64.   while(--x);
  65. }
  66. //************************************************************************/
  67. // 函数: Init_DS18B20()
  68. // 描述: 初始化DS18B20
  69. // 参数: t
  70. // 返回: 无
  71. // 备注: 12MHZ      
  72. //************************************************************************/
  73. //初始化DS18B20
  74. /*DS18B20的复位脉冲 主机通过拉低单总线至少480us以产生复位脉冲
  75.   然后主机释放单总线并进入接收模式 此时单总线电平被拉高
  76.   DS18B20检测到上升沿后 延时15~60us,拉低总线60~240us产生应答脉冲  */      
  77. uchar Init_DS18B20(void)
  78. {
  79.   uchar status;
  80.   DQ1 = 1;     //DS18B20置高电平
  81. Delay(8);    //延时
  82. DQ1 = 0;  //DS18B20置低电平
  83. Delay(90);  //延时480us以上
  84. DQ1 = 1;  //DS18B20置高电平
  85. Delay(8);    //延时
  86. status = DQ1;//读状态
  87. Delay(100);  //延时
  88. DQ1 = 1;  //DS18B20置高电平
  89. return status;//返回状态
  90. }
  91. //************************************************************************/
  92. // 函数: Init_DS18B20()
  93. // 描述: 读一个字节
  94. // 参数: t
  95. // 返回: 无
  96. // 备注: 12MHZ      
  97. //************************************************************************/
  98. /*写时隙 主机在写1时隙向DS18B20写入1,在写0时隙向DS18B20写入0
  99.   所有写时隙至少需要60us,且在两次写时隙之间至少需要1us的恢复时间
  100.   两种写时隙均以主机拉低总线开始
  101.   产生写1时隙:主机拉低总线后,必须在15us内释放总线,由上拉电阻拉回至高电平
  102.   产生写0时隙:主机拉低总线后,必须整个时隙保持低电平 */
  103. uchar ReadOneByte()
  104. {
  105.   uchar i,dat=0;
  106. DQ1 = 1;//DS18B20置高电平
  107. _nop_();//延时
  108. for(i=0;i<8;i++)
  109. {
  110.    DQ1 = 0;//DS18B20置低电平
  111.   dat >>= 1;//右移数据
  112.   DQ1 = 1;//DS18B20置高电平
  113.   _nop_();//延时
  114.   _nop_();//延时
  115.   if(DQ1)
  116.   dat |= 0X80;
  117.   Delay(30);//延时
  118.   DQ1 = 1;//DS18B20置高电平
  119. }
  120. return (dat);
  121. }
  122. //************************************************************************/
  123. // 函数:  WriteOneByte(uchar dat)
  124. // 描述: 写一个字节
  125. // 参数: t
  126. // 返回: 无
  127. // 备注: 12MHZ      
  128. //************************************************************************/
  129. /*所有读时隙至少60us 且两次独立的读时隙之间至少需要1us的恢复时间
  130.   每次读时隙由主机发起,拉低总线至少1us。
  131.   若传1,则保持总线高电平;若发送0,则拉低总线
  132.   传0时DS18B20在该时隙结束时释放总线,再拉回高电平状态,主机必须在读时隙开始后的15us内释放总线,并保持采样总线状态 */
  133. void WriteOneByte(uchar dat)
  134. {
  135.   uchar i;
  136. for(i=0;i<8;i++)
  137. {  DQ1 = 0;  //DS18B20置低电平
  138.   DQ1 = dat& 0x01;
  139.   Delay(5);  //延时
  140.   DQ1 = 1;  //DS18B20置高电平
  141.   dat >>= 1;      //右移数据
  142. }
  143. }
  144. //************************************************************************/
  145. // 函数: Read_Temperature()
  146. // 描述: 读温度值
  147. // 参数: t
  148. // 返回: 无
  149. // 备注: 12MHZ      
  150. //************************************************************************/
  151. void Read_Temperature()
  152. {   EA=0;     //关中断
  153.   if(Init_DS18B20()==1)
  154.   DS18B20_IS_OK=0;
  155. else
  156. {   
  157.   WriteOneByte(0xcc);  //跳过序列号
  158.   WriteOneByte(0x44); //启动温度转换
  159.   Init_DS18B20();
  160.   WriteOneByte(0xcc);//跳过序列号
  161.   WriteOneByte(0xbe);//读取温度寄存器
  162.   Temp_Value[0] = ReadOneByte(); //温度低8位
  163.   Temp_Value[1] = ReadOneByte();//温度高8位
  164.   DS18B20_IS_OK=1;

  165. }
  166. EA=1;    // 开中断
  167. }
  168. //************************************************************************/
  169. // 函数: Display_Temperature()
  170. // 描述: 处理温度值
  171. // 参数: t
  172. // 返回: 无
  173. // 备注: 12MHZ      
  174. //************************************************************************/
  175. void Display_Temperature()
  176. {
  177. uchar t = 150;     //,延时
  178.     ng = 0;       //与负值标志
  179. if((Temp_Value[1]&0xf8)==0xf8)  //温度为负?
  180. {
  181.   Temp_Value[1] = ~Temp_Value[1];
  182.   Temp_Value[0] = ~Temp_Value[0]+1;
  183.   if(Temp_Value[0]==0x00)
  184.    Temp_Value[1]++;
  185.   ng = 1;      //负温度标志
  186. }
  187. else{ng = 0;}
  188. Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得温度小数部分
  189. CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4); //温度整数部分
  190. Display_Digit[3] = CurrentT/100;    //百
  191. Display_Digit[2] = CurrentT%100/10; //十
  192. Display_Digit[1] = CurrentT%10;     //个
  193. Temp=CurrentT ;    //报警温度
  194. if(ng == 1){Temp=0;}//当温度为负时,报警判断温度寄存器为0
  195. }
  196. //************************************************************************/
  197. // 函数: DIS_SEG(void)
  198. // 描述: 在LED上显示数据
  199. // 参数: t
  200. // 返回: 无
  201. // 备注: 12MHZ     
  202. //************************************************************************/
  203. void DIS_SEG(void)  
  204. {
  205.    if(ng==1){P0=0x40;}else{P0=tab[Display_Digit[3]];}   // 数码管显示负数 或正的百位
  206.    SEG1=0;      //片选数码管   
  207.    Delay_ms(3);    //延时2ms
  208.             SEG1=1;   //关闭数码管
  209.    P0=tab[Display_Digit[2]];    //温度十位     
  210.    SEG2=0;   //片选数码管   
  211.    Delay_ms(3);    //延时2ms
  212.             SEG2=1;   //关闭数码管
  213.    P0=(tab[Display_Digit[1]]+0x80); //温度个位和小数点
  214.    SEG3=0;   //片选数码管   
  215.    Delay_ms(3);    //延时2ms
  216.             SEG3=1;   //关闭数码管
  217.       P0=tab[Display_Digit[0]];  //小数位
  218.    SEG4=0;   //片选数码管   
  219.    Delay_ms(3);    //延时2ms
  220.             SEG4=1;   //关闭数码管
  221. }
  222. //************************************************************************/
  223. // 函数: DIS_SET_SEG(void)
  224. // 描述: 在LED上显示数据
  225. // 参数: t
  226. // 返回: 无
  227. // 备注: 12MHZ      
  228. //************************************************************************/
  229. void DIS_SET_SEG(void)
  230. {
  231.    P0=tab[Display_Digit[3]];// 数码管显示负数 或正的百位
  232.    SEG1=0;       //片选数码管        
  233.    Delay_ms(3);    //延时2ms
  234.             SEG1=1;   //关闭数码管
  235.    P0=tab[Display_Digit[2]];//温度十位     
  236.    SEG2=0;   //片选数码管   
  237.    Delay_ms(3);    //延时2ms
  238.             SEG2=1;   //关闭数码管
  239.    P0=tab[Display_Digit[1]];//温度个位
  240.    SEG3=0;   //片选数码管   
  241.    Delay_ms(3);    //延时2ms
  242.             SEG3=1;   //关闭数码管
  243.       P0=tab[Display_Digit[0]];//小数位
  244.    SEG4=0;   //片选数码管   
  245.    Delay_ms(3);    //延时2ms
  246.             SEG4=1;   //关闭数码管
  247. }
  248. //************************************************************************/
  249. // 函数: DIS_UP(void)   
  250. // 描述: 下限设置显示
  251. // 参数: t
  252. // 返回: 无
  253. // 备注: 12MHZ      
  254. //************************************************************************/
  255. void DIS_UP(void)   
  256. {
  257.     Display_Digit[3]=DQ1_SET[0]%100/10;  //处理显示温度
  258. Display_Digit[2]=DQ1_SET[0]%10;   
  259.     Display_Digit[1] =11;   //显示空白
  260. Display_Digit[0] =11;   //显示空白
  261. }
  262. //************************************************************************/
  263. // 函数: DIS_DOWN(void)  
  264. // 描述: 上限设置显示
  265. // 参数: t
  266. // 返回: 无
  267. // 备注: 12MHZ      
  268. //************************************************************************/
  269. void DIS_DOWN(void)   
  270. {
  271. Display_Digit[3] = 11; //显示空白
  272. Display_Digit[2] = 11; //显示空白
  273.     Display_Digit[1]=DQ1_SET[1]%100/10;    //处理显示温度
  274.     Display_Digit[0]=DQ1_SET[1]%10;      

  275. }
  276. //----------------------------键盘扫描-------------------------------------------
  277. //************************************************************************/
  278. // 函数: void S2_ADD(void)
  279. // 描述: 加按键操作函数
  280. // 参数: t
  281. // 返回: 无
  282. // 备注: 12MHZ     
  283. //************************************************************************/
  284. void S2_ADD(void)
  285. {  if(mode==2)   //下限模式
  286. {
  287.          DQ1_SET[0]++; if(DQ1_SET[0]>99){DQ1_SET[0]=99;}    //加下限 和限值下限最大值
  288. }
  289. if(mode==3)//上限模式
  290. {   
  291.      DQ1_SET[1]++; if(DQ1_SET[1]>99){DQ1_SET[1]=99;}  //加上限 和限值下限最大值
  292. }
  293. }
  294. //************************************************************************/
  295. // 函数: S3_SUB(void)
  296. // 描述: 减按键操作
  297. // 参数: t
  298. // 返回: 无
  299. // 备注: 12MHZ      
  300. //************************************************************************/
  301. void S3_SUB(void)
  302. {  if(mode==2)   //下限模式
  303. {
  304.    DQ1_SET[0]--; if(DQ1_SET[0]<1){DQ1_SET[0]=1;}   //加下限 和限值下限最大值
  305. }
  306. if(mode==3)//上限模式
  307. {
  308.            DQ1_SET[1]--; if(DQ1_SET[1]<1){DQ1_SET[1]=1;}   //加上限 和限值下限最大值
  309. }
  310. }
  311. //************************************************************************/
  312. // 函数: KEY_SCAN(void)
  313. // 描述: 键盘扫描
  314. // 参数: t
  315. // 返回: 无
  316. // 备注: 12MHZ      
  317. //************************************************************************/
  318. void KEY_SCAN(void)         
  319. {    if(S1==0)
  320. {
  321.   Delay_ms(10);   //延时去抖动
  322.   mode++;
  323.   if(mode>3){mode=1;}    //在1 2 3中切换
  324.    while(!S1){;}       //等待按键释放
  325. }  
  326.      if(S2==0)
  327. {
  328.   Delay_ms(10);   //延时去抖动
  329.         S2_ADD();
  330.    while(!S2){;}       //等待按键释放
  331. }
  332.    if(S3==0)
  333. {
  334.   Delay_ms(10);   //延时去抖动
  335.         S3_SUB();
  336.   while(!S3){;}       //等待按键释放
  337. }
  338. // 通道切换
  339. }
  340. //----------------------------键盘扫描-------------------------------------------
  341. //************************************************************************/
  342. // 函数: init(void)  
  343. // 描述: 初始化定时器蜂鸣器报警用
  344. // 参数: t
  345. // 返回: 无
  346. // 备注: 12MHZ      
  347. //************************************************************************/
  348. void init(void)     //定时器初始化
  349. {
  350. TMOD=0x01;
  351. TH0=(65536-50000)/256;
  352. TL0=(65536-50000)%256;
  353. EA=1;    //开中断
  354. ET0=1;   //
  355. TR0=0;   //
  356. BUZ=1;  //关蜂鸣器
  357. }
  358. //************************************************************************/
  359. // 函数: main(void)
  360. // 描述: 主程序
  361. // 参数: t
  362. // 返回: 无
  363. // 备注:
  364. //************************************************************************/

  365. void main(void)
  366. {  uchar i;
  367. //--------超温初始---------------
  368. DQ1_SET[0]=10;       //DQ1下限10   
  369. DQ1_SET[1]=90;       //DQ1上限90  
  370. //-----------------------
  371. init();           //初始化蜂鸣器
  372.       
  373.     Read_Temperature(); //初始化DQ1
  374.     Delay_ms(1000);    //延时1s
  375. Read_Temperature();   //读温度
  376. //------------------------------------
  377.    Read_Temperature();       //读温度
  378.   if(DS18B20_IS_OK)         
  379.    Display_Temperature();  //显示温度处理
  380. //------------------------------------
  381. mode=1; //mode=1 正常模式
  382. while(1)
  383. {  if(mode==1){//模式1
  384.      //--------------键盘扫描-------------------------
  385.   KEY_SCAN();
  386.   //------------在SEG上显示温度--------------------
  387.   DIS_SEG();
  388.   //--------------------温度-----------------------
  389.      i++;
  390.      if(i>88) //避免频繁采集温度
  391.     {  Read_Temperature();  //读温度
  392.        if(DS18B20_IS_OK){Display_Temperature();}  //温度数据处理
  393.     i=0;
  394.     }
  395. //-----------------------超温报警-----------------------------
  396. while(1)
  397. {
  398.   if(Temp<DQ1_SET[0]){LED1=0;TR0=1;break;}else{ if(Temp>DQ1_SET[1]){LED1=0;TR0=1;break;}else{LED1=1;BUZ=1;TR0=0;}}     
  399.   break; //下限报警  //上限报警
  400. }        
  401.    
  402. //-----------------------超温报警-----------------------------
  403.      }
  404.   if(mode==2)      //下限设置
  405.    {
  406.     KEY_SCAN();  //键盘扫描
  407.    DIS_UP();    //显示数据处理
  408.       DIS_SET_SEG();  //设置模式下SEG显示方式
  409.    }
  410.   if(mode==3)   //上限设置
  411.   {
  412.    KEY_SCAN();  //键盘扫描
  413.    DIS_DOWN();  //显示数据处理
  414.          DIS_SET_SEG();  //设置模式下SEG显示方式
  415.   //--------------------通道显示------------------------
  416.   }
  417.    }
  418. }
  419. void timer0() interrupt 1 using 1   //蜂鸣器报警声音
  420. {
  421. TH0=(65536-50000)/256;
  422. TL0=(65536-50000)%256;
  423. count++;
  424. if(count==10)   //约10*50000us 取反1次0.5s
  425. {
  426.   count=0;    //清除计数
  427.   BUZ=~BUZ; //蜂鸣器取反
  428. }
  429. }

复制代码


shumaguanwenduji.doc

387 KB, 下载次数: 18, 下载积分: 黑币 -5

评分

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

查看全部评分

回复

使用道具 举报

ID:297390 发表于 2018-9-25 16:04 | 显示全部楼层
非常好1
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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