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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機測溫程序中的數組、串口問題 求大神幫忙

[復制鏈接]
跳轉到指定樓層
樓主
ID:269536 發表于 2018-2-1 16:57 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
10黑幣
求大神幫忙,
這一個單片機多路測溫,然后串口傳入PC
這個串口通過數組傳入一直些不好了,求好心人指點,程序在下方
測溫程序
  1. #include <reg52.h>
  2. #include <intrins.h>


  3. #define MAXNUM 8 //定義最多有8個 DS18B20

  4. sbit DQ=P2^3;    //定義DS18B20數據線

  5. sbit RS=P2^6;     //液晶端口控制線端口定義
  6. sbit RW=P2^5;     //液晶端口控制線端口定義
  7. sbit E= P2^7;     //液晶端口控制線端口定義

  8. sbit keyenter =P3^2;
  9. sbit keyup    =P3^3;
  10. sbit keydown  =P3^4;

  11. sbit led=    P1^6;
  12. sbit buzzer= P1^7;



  13. unsigned char code lcd0[]={"SEARCH ROMING..."};
  14. unsigned char code lcd1[]={"SEARCH ROM OK!"};
  15. unsigned char code lcd2[]={"The total is:"};
  16. unsigned char code lcd3[]={"No.( ):"};
  17. unsigned char code lcd4[]={'0','1','2','3','4','5','6','7','8','9','.',0xdf,0x43,' '};
  18. unsigned char code setinfo[]={"Set Alarm Point:"};
  19. unsigned char code pointinfo[]={"Alarm:"};
  20. signed char tempalarm=0;


  21. //0xdf在1602中是“℃”符號的左上角那個圓,0X43是大寫的"C" 他們一起構成了”℃“這個符號

  22. unsigned char dat[6];//用來顯示溫度的參數                     
  23. unsigned char temp_l,temp_h,negetiveflag=0,temp_over,t;
  24. unsigned char num=0;
  25. unsigned int i;
  26. bit keyflag=0;
  27. idata unsigned char al[MAXNUM];
  28. idata unsigned char ID[MAXNUM][8];

  29. signed char alarm=30; //默認為30攝氏度報警

  30. /***********************液晶模塊**********************************/
  31. void delaylcd(void)//延時程序
  32. {
  33.     unsigned char y;
  34.     for(y=0;y<250;y++);
  35. }

  36. void LCD_write_com(unsigned char com)//液晶寫命令函數
  37. {
  38.     delaylcd();
  39.     RS=0; //RS為1 寫命令
  40.     RW=0;
  41.     E=0;
  42.     E=1;
  43.     P0=com;
  44.        E=0;
  45.     delaylcd();
  46. }

  47. void LCD_write_data(unsigned char dat)//液晶寫數據函數
  48. {
  49.     delaylcd();
  50.     RS=1;   //RS為1 寫數據
  51.     RW=0;
  52.     E=0;
  53.     E=1;
  54.     P0=dat;
  55.     E=0;
  56.     delaylcd();
  57. }
  58. void lcdinit(void)//初始化
  59. {
  60.     LCD_write_com(0x01); //液晶清屏 
  61.     LCD_write_com(0x38); //1602”功能設置命令字“ 顯示2行 每行字體用5*8 ASCII顯示    8位數據接口
  62.     LCD_write_com(0x0c); //顯示控制,開始顯示,不顯示游標,游標不閃爍   
  63.     LCD_write_com(0x06); //輸入方式為增量輸入,不移屏幕
  64. }

  65. /************************ds18b20****************************/
  66. void delay_nus(unsigned int n)//延時 程序 一次8+6(進出)=14us
  67. {
  68.     while(n--);
  69. }

  70. void reset(void)  //ds18b20初始化復位操作
  71. {
  72.      unsigned char x=0;
  73.      DQ = 1;              //DQ復位
  74.      delay_nus(8);      //稍做延時
  75.      DQ = 0;              //單片機將DQ拉低
  76.      delay_nus(80);     //精確延時 大于 480us
  77.      DQ = 1;              //拉高總線
  78.      delay_nus(10);
  79.      x=DQ;                //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  80.      delay_nus(5);
  81. }

  82. void write_bit(unsigned char dat)    //DS18B20 寫一位 操作
  83. {
  84.       DQ = 0;
  85.     _nop_();
  86.     _nop_();
  87.      DQ = dat&0x01;
  88.     delay_nus(5);
  89.      DQ = 1;
  90. }

  91. void write_byte(unsigned char dat)//寫一個字節
  92. {
  93.      unsigned char i,j;
  94.      for (i=8; i>0; i--)
  95.      {
  96.         j=dat&0x01;
  97.           write_bit(j);
  98.         dat>>=1;
  99.     }
  100. }

  101. unsigned char read_2bit(void)//讀二位 子程序
  102. {
  103.     unsigned char i;
  104.     unsigned char dat = 0;
  105.     for (i=2;i>0;i--)
  106.     {
  107.         DQ = 0; // 給脈沖信號
  108.         dat<<=1;
  109.         DQ = 1; // 給脈沖信號
  110.         if(DQ)
  111.         dat|=0x01;
  112.         delay_nus(4);
  113.     }
  114.      return(dat);
  115. }

  116. unsigned char read_byte(void)//讀一個字節 子程序
  117. {
  118.     unsigned char i=0;
  119.     unsigned char dat = 0;
  120.     for (i=8;i>0;i--)
  121.     {
  122.         DQ = 0; // 給脈沖信號
  123.         dat>>=1;
  124.         DQ = 1; // 給脈沖信號
  125.         if(DQ)
  126.         dat|=0x80;
  127.         delay_nus(4);
  128.     }
  129.      return(dat);  
  130. }



  131. void delay_nms(unsigned int n)
  132. {
  133.     unsigned int j=0;
  134.     unsigned char i=0;
  135.     for(j=0;j<n;j++)
  136.     {
  137.         for(i=0;i<120;i++)
  138.         {
  139.             _nop_();
  140.         }
  141.     }
  142. }

  143. void read_temp(unsigned char num_data)//讀取溫度 子程序 參數表示讀第幾個傳感器
  144. {
  145.     unsigned char f;   
  146.     reset();
  147.     write_byte(0xcc);//發送跳過ROM號命令
  148.     write_byte(0x44);//發送溫度轉換命令
  149.     delay_nms(2000);        
  150.     reset();
  151.     write_byte(0x55);//發送匹配ROM號命令
  152.     for(f=0;f<8;f++) //8字節ROM號
  153.     {
  154.         write_byte(ID[num_data][f]);//發匹配ROM
  155.     }
  156.     delay_nus(100);
  157.     write_byte(0xbe);//讀寄存器命令
  158.     delay_nus(100);
  159.     temp_l=read_byte();
  160.     temp_h=read_byte();
  161. }


  162. void temp_convert(void)//溫度轉換
  163. {
  164.     negetiveflag=0;
  165.     negetiveflag=temp_h&0x80;
  166.     if(negetiveflag)
  167.     {
  168.         negetiveflag=1;
  169.         temp_h=~temp_h;
  170.           if(temp_l==0)
  171.         {
  172.              temp_h++;  //若低8位全為0且溫度為負,取補時就要向高位進1
  173.         }
  174.           temp_l=~temp_l+1;
  175.     }
  176.     temp_h<<=4;
  177.     temp_l>>=4;
  178.     temp_over=temp_h|temp_l;
  179.     tempalarm=temp_over;
  180.     if(negetiveflag==1)
  181.     {
  182.          tempalarm=tempalarm*(-1);
  183.     }
  184. }

  185. /*******************顯示***************************/
  186. void search_cartoon(void)//搜索ROM動畫
  187. {
  188.     lcdinit();
  189.     LCD_write_com(0x80);//液晶第一行地址
  190.     for(i=0;i<16;i++)
  191.     {
  192.         LCD_write_data(lcd0[i]);
  193.     }
  194.     LCD_write_com(0xc0);//液晶第二行地址
  195.     for(i=0;i<16;i++)
  196.     {
  197.         LCD_write_data(0xff);//顯示類似進度條的黑點
  198.         delay_nms(num*80);
  199.     }         
  200. }

  201. void display_alarm_normal(signed char alarm_data)//顯示報警溫度
  202. {
  203.     unsigned int data_b,data_temp,l,datx[6]={0};
  204.     data_b=alarm_data;
  205.     negetiveflag=0;

  206.     LCD_write_com(0x80);
  207.     for(l=0;l<6;l++)
  208.     {
  209.         LCD_write_data(pointinfo[l]);
  210.     }   

  211.     if(alarm_data>=0)
  212.     {
  213.         data_b=alarm_data/100;//百位//
  214.     }
  215.     else
  216.     {
  217.         negetiveflag=1;
  218.         alarm_data=alarm_data*(-1);//變成正溫度
  219.     }

  220.     data_temp=alarm_data%100;//對100取余,也就是十位數和個位數

  221.     datx[0]=data_temp/10;//十位
  222.     datx[1]=data_temp%10;//個位
  223.     datx[2]=13;//空格符號
  224.     datx[3]=13;//空格符號
  225.     datx[4]=11;//攝氏度符號
  226.     datx[5]=12;//攝氏度符號

  227.     LCD_write_com(0x88);

  228.     if(negetiveflag==1)
  229.     {
  230.         LCD_write_data(0x2d);//顯示"-"  “負號”
  231.     }
  232.     else
  233.     {
  234.         LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數,否則百位數就顯示“負號”
  235.     }

  236.     for(l=0;l<6;l++)//顯示報警值和攝氏度符號
  237.     {
  238.       LCD_write_data(lcd4[datx[l]]);
  239.     }   
  240. }

  241. void display_total(void)      //顯示搜索到的DS18B20傳感器數目
  242. {
  243.     lcdinit();
  244.     LCD_write_com(0x80);//第一行地址
  245.     for(i=0;i<14;i++)
  246.     {
  247.         LCD_write_data(lcd1[i]);
  248.     }
  249.     LCD_write_com(0xc0);//第二行地址
  250.     for(i=0;i<13;i++)
  251.     {
  252.         LCD_write_data(lcd2[i]);
  253.     }
  254.     LCD_write_data(lcd4[num]);
  255.     delay_nms(2000);
  256.     lcdinit();                    //清屏,準備顯示溫度
  257.     display_alarm_normal(alarm);//顯示報警溫度
  258. }



  259. void display_ds18b20(i)//顯示編號為i的DS18B20的溫度//
  260. {
  261.     unsigned int data_b,data_temp,l;
  262.     data_b=temp_over/1000;//百位//
  263.     data_temp=temp_over%100;
  264.     dat[0]=data_temp/10;//十位//
  265.     dat[1]=data_temp%10;//個位//
  266.     dat[2]=13; //空格
  267.     dat[3]=13; //空格
  268.     dat[4]=11; //攝氏度符號
  269.     dat[5]=12; //攝氏度符號

  270.     LCD_write_com(0xc0);
  271.     for(l=0;l<7;l++)
  272.     {
  273.         LCD_write_data(lcd3[l]);
  274.     }
  275.     LCD_write_com(0xc4);
  276.     LCD_write_data(lcd4[++i]);
  277.     LCD_write_com(0xc8);

  278.     if(negetiveflag==1)
  279.     {
  280.         LCD_write_data(0x2d);
  281.     }
  282.     else
  283.     {
  284.         LCD_write_data(lcd4[data_b]);
  285.     }

  286.     for(l=0;l<6;l++)
  287.         LCD_write_data(lcd4[dat[l]]);
  288.     delay_nms(1000);
  289. }




  290. void display_alarm(signed char alarm_data)//顯示報警溫度
  291. {
  292.     unsigned int data_b,data_temp,l;
  293.     data_b=alarm_data;
  294.     negetiveflag=0;
  295.     if(alarm_data>=0)
  296.     {
  297.      data_b=alarm_data/100;//百位//
  298.     }
  299.     else
  300.     {
  301.      negetiveflag=1;
  302.      alarm_data=alarm_data*(-1);//變成正溫度
  303.     }

  304.     data_temp=alarm_data%100;//對100取余,也就是十位數和個位數

  305.     dat[0]=data_temp/10;//十位
  306.     dat[1]=data_temp%10;//個位
  307.     dat[2]=13;//空格符號
  308.     dat[3]=11;//攝氏度符號
  309.     dat[4]=12;//攝氏度符號

  310.     if(keyflag==1)//剛剛進入設置報警溫度
  311.     {
  312.         lcdinit();
  313.         LCD_write_com(0x80);//第一行地址
  314.         for(l=0;l<16;l++)
  315.         {
  316.             LCD_write_data(setinfo[l]);
  317.         }
  318.    
  319.         LCD_write_com(0xc0);//第二行地址
  320.         for(l=0;l<8;l++)
  321.         {
  322.             LCD_write_data(pointinfo[l]);
  323.         }
  324.     }
  325.    

  326.     LCD_write_com(0xc7);

  327.     if(negetiveflag==1)
  328.     {
  329.         LCD_write_data(0x2d);//顯示"-"  “負號”
  330.     }
  331.     else
  332.     {
  333.         LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數,否則百位數就顯示“負號”
  334.     }

  335.     for(l=0;l<5;l++)//顯示報警值和攝氏度符號
  336.     {
  337.       LCD_write_data(lcd4[dat[l]]);
  338.     }   
  339. }


  340. /***********************自動搜索ROM*****************************/
  341. void search_rom(void)//搜索ROM
  342. {
  343.     unsigned char k=0,l=0,chongtuwei=0,m=0,n=0;
  344.     unsigned char s=0;
  345.     unsigned char zhan[MAXNUM];
  346.     unsigned char ss[64];
  347.     do
  348.     {
  349.         reset();
  350.         write_byte(0xf0);  //搜索ROM命令   
  351.         for(m=0;m<8;m++)
  352.         {
  353.             for(n=0;n<8;n++)
  354.             {
  355.                 k=read_2bit();//讀兩位數據
  356.                 k=k&0x03;   
  357.                 s>>=1;
  358.                 if(k==0x01)//01讀到的數據為0 寫0 此位為0的器件響應
  359.                 {           
  360.                     write_bit (0);
  361.                     ss[(m*8+n)]=0;
  362.                 }
  363.                 else if(k==0x02)//讀到的數據為1 寫1 此位為1的器件響應
  364.                 {
  365.                     s=s|0x80;
  366.                     write_bit (1);
  367.                     ss[(m*8+n)]=1;
  368.                 }
  369.                 else if(k==0x00)//讀到的數據為0  有沖突位 判斷沖突位
  370.                 {                //如果沖突位大于棧頂寫0 小于棧頂寫以前數據 等于棧頂寫1
  371.                     chongtuwei=m*8+n+1;                    
  372.                     if(chongtuwei>zhan[l])
  373.                     {                        
  374.                         write_bit (0);
  375.                         ss[(m*8+n)]=0;                                                
  376.                         zhan[++l]=chongtuwei;                        
  377.                     }
  378.                     else if(chongtuwei<zhan[l])
  379.                     {
  380.                         s=s|((ss[(m*8+n)]&0x01)<<7);
  381.                         write_bit (ss[(m*8+n)]);
  382.                     }
  383.                     else if(chongtuwei==zhan[l])
  384.                     {
  385.                         s=s|0x80;
  386.                         write_bit (1);
  387.                         ss[(m*8+n)]=1;
  388.                         l=l-1;
  389.                     }
  390.                 }
  391.                 else
  392.                 {
  393.                     goto loop;
  394.                 }
  395.             }
  396.             ID[num][m]=s;        
  397.         }
  398.         num++;
  399.     }
  400.     while(zhan[l]!=0&&(num<MAXNUM));        
  401. loop:
  402.     search_cartoon();
  403.     display_total();

  404. }



  405. void main (void)
  406. {
  407.     unsigned char i=0,t=0;
  408.     delay_nms(50);
  409.     IT0=0;
  410.     EX0=1;
  411.     EA=1;

  412.     search_rom();//搜索ROM并且存儲,把18B20的每一個ROM讀取出來,方便下次調用


  413.     reset();
  414.         
  415.     while(1)
  416.     {
  417.         if(keyflag==0)
  418.         {
  419.               for(i=0;i<num;i++)    //每一個 ds18b20 循環顯示
  420.               {
  421.                     if(keyflag==1) break;
  422.                     read_temp(i);   //讀編號 i 的ds18b20 的溫度
  423.                     if(keyflag==1) break;
  424.                     temp_convert(); //調用溫度轉換
  425.                     if(keyflag==1) break;
  426.                     if(tempalarm>alarm)//報警判斷
  427.                     {
  428.                       for(t=0;t<3;t++)
  429.                       {
  430.                            buzzer=0;//打開報警蜂鳴器
  431.                          led=0;   //打開報警指示燈
  432.                          delay_nms(100);
  433.                          buzzer=1;//關閉報警蜂鳴器
  434.                          led=1;   //關閉報警指示燈
  435.                          delay_nms(100);
  436.                       }
  437.                     }
  438.                     display_ds18b20(i);//顯示 編號 i 的溫度        
  439.               }
  440.         }         

  441.         else//設置按鍵按下 進行按鍵掃描動作
  442.         {
  443.            display_alarm(alarm);
  444.            keyflag=0;
  445.            while(1)
  446.            {
  447.                 if(keyenter==0&&keyflag==0)//進入設置以后,再按設置按鍵,就退出設置,重新顯示每一個通道溫度
  448.                 {
  449.                   delay_nms(200);
  450.                   if(keyenter==0)
  451.                   {
  452.                     while(keyenter==0);     
  453.                     lcdinit();
  454.                     display_alarm_normal(alarm);//顯示報警溫度
  455.                     break;//退出按鍵掃描
  456.                   }
  457.                 }
  458.             if(keyup==0)//
  459.                 {
  460.                   delay_nms(200);
  461.                   if(keyup==0&&alarm<125)
  462.                   {
  463.                      alarm++;//報警溫度加1
  464.                   }
  465.                   display_alarm(alarm);
  466.                 }
  467.            if(keydown==0&&alarm>-55)//
  468.                 {
  469.                   delay_nms(200);
  470.                   if(keydown==0)
  471.                   {
  472.                     alarm--;//報警溫度減1
  473.                   }
  474.                   display_alarm(alarm);
  475.                 }
  476.                 delay_nms(50);
  477.            }
  478.            EX0=1;   
  479.         }
  480.                   
  481.     }//while(1)結束  
  482. }

  483. void key_init0(void) interrupt 0
  484. {
  485.     if(keyenter==0)
  486.     {
  487.       delay_nms(10);
  488.       if(keyenter==0)
  489.       {
  490.           EX0=0;
  491.         keyflag=1;
  492.       }
  493.     }
  494.    
  495. }


  496. 串口程序
  497. //#include <STC89C5xRC.H>
  498. #include "reg52.h"             //此文件中定義了單片機的一些特殊功能寄存器
  499. typedef unsigned int u16;      //對數據類型進行聲明定義
  500. typedef unsigned char u8;

  501. sbit led=P2^0;     //定義P20口是led
  502. unsigned char code darArr1[]={"*23 75 798 5 0.3 89 &"};    //串口發送內容
  503. void UART_init(void)
  504. {
  505.     TMOD = 0x20;
  506.     SCON = 0x40;
  507.     TH1 = 0xF3;
  508.     TL1 = TH1;
  509.     PCON = 0x80;
  510.     TR1 = 1;
  511. }

  512. /*******************************************************************************
  513. * 函 數 名         : Timer0Init
  514. * 函數功能           : 定時器0初始化
  515. * 輸    入         : 無
  516. * 輸    出         : 無
  517. *******************************************************************************/
  518. void Timer0Init()
  519. {
  520.     TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。

  521.     TH0=0XFC;    //給定時器賦初值,定時1ms
  522.     TL0=0X18;   
  523.     ET0=1;//打開定時器0中斷允許
  524.     EA=1;//打開總中斷
  525.     TR0=1;//打開定時器            
  526. }
  527. void UART_send_byte(unsigned char dat)
  528. {
  529.     SBUF = dat;
  530.     while(!TI);
  531.     TI = 0;
  532. }
  533. void main(){

  534. unsigned char i=0;
  535.     UART_init();
  536.     P1=0xf0;
  537.     Timer0Init();  //定時器0初始化
  538.     while(1){

  539.     }

  540. }

  541. /*******************************************************************************
  542. * 函 數 名         : void Timer0() interrupt 1
  543. * 函數功能           : 定時器0中斷函數
  544. * 輸    入         : 無
  545. * 輸    出         : 無
  546. *******************************************************************************/
  547. void Timer0() interrupt 1
  548. {
  549.     static u16 i;
  550.     TH0=0XFC;    //給定時器賦初值,定時1ms
  551.     TL0=0X18;
  552.     i++;
  553.     if(i==1000)
  554.     {
  555.         i=0;
  556.         led=~led;
  557.         for(i=0;darArr1[i]!='&';i++){
  558.             UART_send_byte(darArr1[i]);
  559.         }   
  560.     }   
  561. }
復制代碼


AAA.zip

302.88 KB, 下載次數: 3

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

使用道具 舉報

沙發
ID:284230 發表于 2018-2-16 22:10 | 只看該作者
不要在中斷里處理串口發送這種很耗時的處理。移到主程序中去。或使用中斷方式寫串口發送程序。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美视频免费在线观看 | 中文字幕 国产精品 | 久久国产精品久久久久久久久久 | 日韩中文一区二区三区 | 日韩中文字幕在线播放 | 先锋资源吧 | 97人人澡人人爽91综合色 | av性色全交蜜桃成熟时 | 欧美高清视频在线观看 | 天天操网| 毛片区| 久久久女女女女999久久 | 日本免费在线 | 国产91在线播放精品91 | 色偷偷噜噜噜亚洲男人 | 久草在线在线精品观看 | 亚洲一区有码 | 久久精品国产一区二区电影 | 中文字幕亚洲一区二区va在线 | 国产日产久久高清欧美一区 | 亚洲欧美一区二区三区在线 | 91精品国产综合久久香蕉麻豆 | 综合九九 | 美女视频一区二区三区 | av一区在线观看 | 午夜天堂精品久久久久 | 黄网在线观看 | 亚洲欧洲精品在线 | 日本精品视频 | 国产成人综合一区二区三区 | 福利一区在线观看 | 欧美日韩一区二区三区不卡视频 | 欧美色综合天天久久综合精品 | 国产精品亚洲一区二区三区在线 | 久一精品 | 午夜视频一区二区 | 精品亚洲一区二区三区 | 99只有精品 | 国产aⅴ | 中文字幕人成人 | 国产激情第一页 |