久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3702|回復: 2
打印 上一主題 下一主題
收起左側

LCD12864基于ds18b20 顯示溫度曲線 單片機源程序

[復制鏈接]
跳轉到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include "lcd12864.h"
  2. #ifdef LCD12864_DEV_DRIVER
  3. sbit DQ = DS18B20_DQ_PIN
  4. static uint16_t clock_ticks = 0;
  5. static bool_t second_flag = 0;
  6. static uint8_t pos_x = 0;
  7. static uint8_t pos_y = 0;
  8. static uint8_t pos_x_befor = 0;
  9. static uint8_t pos_y_befor = 0;
  10. static idata int16_t temperature;
  11. static idata float temp_display;
  12. static idata uint8_t display_buf[8];
  13. static void ds18b20_delay(uint16_t i)
  14. {
  15.         while( i-- );
  16. }
  17. static bool_t ds18b20_reset(void) /* 初始化函數 */
  18. {
  19.   uint8_t x = 0;
  20.   
  21.   DQ = 1;          //DQ復位
  22.   ds18b20_delay(8);  //稍做延時
  23.   DQ = 0;          //單片機將DQ拉低
  24.   ds18b20_delay(80); //精確延時 大于 480us
  25.   DQ = 1;          //拉高總線
  26.   ds18b20_delay(14);
  27.   x = DQ;            //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  28.   ds18b20_delay(20);

  29.   if(x == 0){
  30.     return TRUE;
  31.   }else{
  32.     return FALSE;
  33.   }
  34. }
  35. static uint8_t ds18b20_read_one_char(void)/* 讀一個字節 */
  36. {
  37.         uint8_t i=0;
  38.         uint8_t dat = 0;
  39.   
  40.   for (i=8;i>0;i--){
  41.     DQ = 0;       /* 給脈沖信號 */
  42.     dat>>=1;
  43.     DQ = 1;       /* 給脈沖信號 */
  44.     if(DQ)
  45.     dat|=0x80;
  46.     ds18b20_delay(4);
  47.   }
  48.   
  49.          return dat;
  50. }

  51. static uint8_t ds18b20_write_one_char(uint8_t dat)/* 寫一個字節      */
  52. {
  53.   uint8_t i=0;
  54.   
  55.   for (i=8; i>0; i--){
  56.     DQ = 0;
  57.     DQ = dat&0x01;
  58.     ds18b20_delay(5);
  59.     DQ = 1;
  60.     dat>>=1;
  61.   }
  62.   return dat;
  63. }
  64. int16_t ds18b20_read_temperature(void)/* 讀取溫度, 返回的溫度值 *10, 即一位小數 */
  65. {
  66.         uint8_t a = 0;
  67.         uint8_t b = 0;
  68.         int16_t  t = 0;
  69.   bool_t is_negative_temp = 0;
  70.   
  71.         __disable_irq();
  72.   
  73.         ds18b20_reset();

  74.         ds18b20_write_one_char(0xCC); /* 跳過讀序號列號的操作 */
  75.         ds18b20_write_one_char(0x44); /* 啟動溫度轉換 */
  76.         ds18b20_delay(100);
  77.   ds18b20_reset();
  78.         
  79.         ds18b20_write_one_char(0xCC); /* 跳過讀序號列號的操作 */
  80.         ds18b20_write_one_char(0xBE); /* 讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 */
  81.         a = ds18b20_read_one_char();
  82.         b = ds18b20_read_one_char();
  83.   
  84.         __enable_irq();        

  85.   if( b > 0x7f )      /* 最高位為1 時溫度是負 */
  86.   {
  87.     a = ~a + 1;
  88.     b = ~b;
  89.     is_negative_temp = 1;
  90.   }

  91.   t = a >> 4;
  92.   t += b << 4;

  93.   a = (a&0x0f)*10 >> 4;

  94.   t *= 10;
  95.   t += a;
  96.   
  97.   if(is_negative_temp){
  98.     t = -t;
  99.   }
  100.   
  101.         return t;
  102. }
  103. void ds18b20_init(void)
  104. {
  105.   ds18b20_reset();

  106.   ds18b20_write_one_char(0xcc);//忽略ROM指令
  107.   ds18b20_write_one_char(0x4e);//寫暫存器指令
  108.   ds18b20_write_one_char(0); //TH值未使用
  109.   ds18b20_write_one_char(0);  //TL值未使用
  110.   ds18b20_write_one_char(0x3f);// 采用bit數。
  111.   //0x1f : 0.5000°C  轉換時間93.75ms
  112.   //0x3f : 0.2000°C  轉換時間187.5ms
  113.   //0x5f : 0.1250°C  轉換時間375ms
  114.   //0x7f : 0.0625°C  轉換時間750ms

  115.   ds18b20_read_temperature();  /* 第一次讀取值錯誤,丟棄 */
  116. }
  117. static void draw_coord(void)/* 畫坐標 */
  118. {
  119.   pos_x = 0;
  120.   pos_y = 0;
  121.   pos_x_befor = 0;
  122.   pos_y_befor = 0;
  123.   lcd12864_clear_display(0);
  124.   
  125.   lcd12864_draw_dotted_line(0,63, 0, 0);
  126.   lcd12864_draw_dotted_line(0,32,127,32);
  127.   lcd12864_draw_dotted_line(0, 63,127, 63);

  128.   lcd12864_show_string(0, 80, "T:0");
  129. }
  130. void Delay500ms()                //@11.0592MHz
  131. {
  132.         unsigned char i, j, k;

  133.         _nop_();
  134.         i = 4;
  135.         j = 129;
  136.         k = 119;
  137.         do
  138.         {
  139.                 do
  140.                 {
  141.                         while (--k);
  142.                 } while (--j);
  143.         } while (--i);
  144. }
  145. void main(void)
  146. {
  147.   SCON = 0x50;    /* 8位數據,可變波特率 */
  148.   TMOD &= 0x0f;   /* 設定定時器1為16位自動重裝方式 */
  149.   TMOD |= 0x20;   /* 設定定時器1為16位自動重裝方式 */
  150.   PCON = 0x00;    /* 波特率不加倍 */
  151.   TH1 = 0xFD;     /* 設定定時初值 */
  152.   TL1 = 0xFD;     /* 設定定時初值 */
  153.   TR1 = 1;        /* 啟動定時器1 */
  154.   REN = 1;        /* 使能接收 */
  155.   ES = 1;         /* 打開串口中斷 */
  156.   
  157.   TMOD &= 0xF0;                //設置定時器模式
  158.         TMOD |= 0x01;                //設置定時器模式
  159.         TL0 = 0x00;                //設置定時初值,50ms中斷
  160.         TH0 = 0x4C;                //設置定時初值
  161.         TF0 = 0;                //清除TF0標志
  162.         TR0 = 1;                //定時器0開始計時
  163.   ET0 = 1;          //允許定時/計數器0中斷
  164.   
  165.   ds18b20_init();
  166.   lcd12864_init();
  167.   __enable_irq();
  168.   draw_coord();
  169.   second_flag = 1;

  170.   ds18b20_read_temperature();
  171.   Delay500ms();
  172.   ds18b20_read_temperature();
  173.   Delay500ms();
  174.   while(1){
  175.     if(second_flag == 1){
  176.       second_flag = 0;
  177.       if(pos_x == 128){
  178.         draw_coord();
  179.       }
  180.    
  181.       temperature = ds18b20_read_temperature();
  182.       temp_display = temperature / 10.0;
  183.       sprintf(display_buf, "%.1f", temp_display);
  184.       lcd12864_show_string(0, 96, "    ");
  185.       lcd12864_show_string(0, 96, display_buf);
  186.       if(temperature > 630){
  187.         temperature = 630;
  188.       }else if(temperature < 0){
  189.         temperature = 0;
  190.       }
  191.       
  192.       pos_y = temperature / 10;
  193.       pos_y = 63 - pos_y;
  194.       
  195.       if(pos_x == 0){
  196.         pos_x_befor = 0;
  197.         pos_y_befor = pos_y;
  198.       }
  199.       lcd12864_draw_line(pos_x_befor, pos_y_befor, pos_x, pos_y);
  200.       pos_x_befor = pos_x;
  201.       pos_y_befor = pos_y;
  202.       pos_x++;
  203.     }
  204.   }
  205. }
  206. void timer0() interrupt 1
  207. {
  208.   TL0 = 0x00;//重新裝載初值, 50ms中斷
  209.   TH0 = 0x4c;  
  210.          
  211.   clock_ticks++;

  212.   if(clock_ticks == 20){
  213.     clock_ticks = 0;
  214.     second_flag = 1;
  215.   }
  216. }

  217. sbit RST = LCD12864_RST;
  218. sbit E   = LCD12864_EN;
  219. sbit RW  = LCD12864_RW;
  220. sbit DI  = LCD12864_DI;
  221. sbit CS1 = LCD12864_CS1;
  222. sbit CS2 = LCD12864_CS2;

  223. #define LCDPORT   P0
  224. #define LCDSTARTROW 0xC0                            /* 設置起始行指令 */
  225. #define LCDPAGE     0xB8                                  /* 設置頁指令 */
  226. #define LCDLINE     0x40                                  /* 設置列指令 */
  227. #define ASCII_CODE_12864_ELEMENT_NUM      ( 67 )
  228. extern ascii_12864 code ascii_code_12864[];
  229. /*---------------------------------------------------------------------------*/
  230. static bool_t lcd12864_is_busy(void)
  231. {
  232.   uint8_t state = 0;
  233.   bool_t busy;
  234.   
  235.         LCDPORT = 0xFF;
  236.         RW = 1;
  237.         DI = 0;
  238.         E = 1;
  239.         E = 0;
  240.   E = 1;/* E的下降沿,然后E持續拉高讀才有效 */
  241.   state = LCDPORT;
  242.   E = 0;

  243.   busy = (bool_t)(state>>7);
  244.         return busy;
  245. }
  246. /*---------------------------------------------------------------------------*/
  247. static void lcd12864_write_data(uint8_t ucData)
  248. {
  249.   uint16_t timeout;

  250.   timeout = 0;
  251.         while(lcd12864_is_busy()){
  252.     timeout++;
  253.     if(timeout > 0xff){
  254.       break;
  255.     }
  256.   }
  257.         LCDPORT = 0xFF;

  258.         RW = 0;
  259.         DI = 1;
  260.         LCDPORT = ucData;
  261.         E = 1;
  262.         E = 0;
  263. }
  264. /*---------------------------------------------------------------------------*/
  265. static void lcd12864_write_cmd(uint8_t ucCMD)
  266. {
  267.         uint16_t timeout;

  268.   timeout = 0;
  269.         while(lcd12864_is_busy()){
  270.     timeout++;
  271.     if(timeout > 0xff){
  272.       break;
  273.     }
  274.   }
  275.         LCDPORT = 0xFF;

  276.         RW = 0;
  277.         DI = 0;
  278.         LCDPORT = ucCMD;
  279.         E = 1;
  280.         E = 0;
  281. }
  282. /*---------------------------------------------------------------------------*/
  283. void lcd12864_init( void )
  284. {
  285.         CS1 = 1;
  286.         CS2 = 1;
  287.   
  288.         lcd12864_write_cmd(0x38);                      /* 8位形式,兩行字符 */
  289.         lcd12864_write_cmd(0x0F);                      /* 開顯示 */
  290.         lcd12864_write_cmd(0x01);                      /* 清屏 */
  291.         lcd12864_write_cmd(0x06);                      /* 畫面不動,光標右移 */
  292.         lcd12864_write_cmd(LCDSTARTROW);        /* 設置起始行 */
  293. }

  294. /*---------------------------------------------------------------------------*/
  295. static void lcd12864_show_custom_row(uint8_t ucPage,uint8_t ucLine,uint8_t ucWidth,uint8_t *ucaRow)
  296. {
  297.         uint8_t ucCount;
  298.   
  299.         if(ucLine < 64){
  300.           CS1=1;
  301.           CS2=0;
  302.           lcd12864_write_cmd(LCDPAGE + ucPage);
  303.           lcd12864_write_cmd(LCDLINE + ucLine);
  304.           if( (ucLine + ucWidth) < 64 ){
  305.                   for(ucCount = 0; ucCount < ucWidth; ucCount++){
  306.                           lcd12864_write_data(*(ucaRow + ucCount));
  307.                   }
  308.                 }
  309.           else{
  310.                   for(ucCount = 0; ucCount < (64 - ucLine); ucCount++){
  311.                           lcd12864_write_data(*(ucaRow+ucCount));
  312.       }


  313. ……………………

  314. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
程序+proteus.zip (167.24 KB, 下載次數: 123)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:748788 發表于 2021-3-7 16:32 | 只看該作者
如果橫軸和縱軸有時間和溫度標尺就更好了
回復

使用道具 舉報

板凳
ID:53978 發表于 2021-8-11 12:29 | 只看該作者
誰能把18B20程序換成K型熱電偶嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜精品网站 | 久久久久免费精品国产 | 欧美日韩在线观看一区 | 亚洲精品视频免费 | 久久免费精品视频 | 激情av | 欧美日韩在线观看视频网站 | 国产精品自拍av | 亚州精品天堂中文字幕 | 日日做夜夜爽毛片麻豆 | 精品久久久久久久人人人人传媒 | 国产精品日韩欧美一区二区三区 | 久久国产区 | 中文字幕日韩欧美一区二区三区 | 欧美激情综合色综合啪啪五月 | 欧美一区二区三区在线 | 欧美全黄 | 免费黄色在线观看 | 久久久久国产成人精品亚洲午夜 | 免费一区二区三区 | 在线免费观看日本视频 | 欧美黄在线观看 | 男女免费在线观看视频 | 免费黄色av网站 | 色综合视频在线 | 免费在线成人 | 99久久婷婷国产综合精品电影 | 伊人在线视频 | 四虎影院免费在线播放 | 91在线观看 | 国产黄色av网站 | 超碰免费在线 | 亚洲成人黄色 | 超碰成人在线观看 | 91 久久 | 九九精品视频在线 | 国产91亚洲精品一区二区三区 | 成人欧美一区二区三区在线观看 | 自拍视频一区二区三区 | 久在线精品视频 | 久久综合亚洲 |