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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4709|回復(fù): 4
收起左側(cè)

單片機(jī)程序keil DEBUG運(yùn)行到初始化定時(shí)器后一直循環(huán)中斷?

[復(fù)制鏈接]
ID:490607 發(fā)表于 2019-4-15 13:26 | 顯示全部樓層 |閱讀模式
本帖最后由 gq2352100 于 2019-4-15 19:08 編輯

寫了一個(gè)溫度控制程序,DS18B20采集,LCD1602顯示,根據(jù)當(dāng)前溫度和設(shè)定溫度的誤差輸出5檔PWM,但是不知道為什么,用 keil DEBUG的時(shí)候,一旦運(yùn)行到初始化定時(shí)器后,就不會(huì)再繼續(xù)運(yùn)行下面的代碼,而是一直循環(huán)STARTUP.A51里面的兩行,一直到左上R0寄存器減1到0就會(huì)復(fù)位,從頭執(zhí)行程序。如圖:

就是圖中標(biāo)記的這兩行

就是圖中標(biāo)記的這兩行

找了半天不知道問(wèn)題所在,請(qǐng)各位大佬幫幫忙,感激萬(wàn)分。

單片機(jī)代碼貼上:

  1. //這是主程序
  2. #include < reg52.h >
  3. #include < intrins.h >
  4. #include < ds18b20.h >
  5. #include < lcd1602.h >
  6. #include < fuzzy.h >
  7. #include < pwm.h >


  8. #define uchar unsigned char
  9. #define uint   unsigned int



  10. void init_time()
  11. {
  12.         TMOD=0x01;   //T0都是定時(shí)方式1
  13.         TH0=0xFC;   //T1  10us初值
  14.         TL0=0x18;
  15.         TR0=1;
  16.         ET0=1;
  17.         EA=1;
  18.         time=0;
  19.         zkb=50;
  20. }

  21. void main()
  22. {
  23.         lcd_display();
  24.   delayms(500);
  25.   ow_reset();
  26.         if(presence==0)
  27.         {
  28.                 Ok_Menu ();
  29.                 delayms(500);        
  30.                 init_time();
  31.           while(1)
  32.           {
  33.                   temperature_trans();
  34.                         fuzzy();
  35.                         pwmchange();
  36.       c_display();
  37.                         temperature_display();
  38.     }

  39. //下面是DS18B20程序
  40.                
  41. #include < reg52.h >
  42. #include < intrins.h >

  43. #define uchar unsigned char
  44. #define uint   unsigned int

  45. sbit DQ = P0^0;   //定義DS18B20端口DQ
  46. bit presence=1;           //ds18b20應(yīng)答信號(hào) 0允許,1禁止
  47. unsigned char data   temp_data[2] = {0x00,0x00} ;  //用于存儲(chǔ)16位溫度

  48. /*us級(jí)延時(shí),延時(shí)時(shí)間約4+2*i*/
  49. void delayus(uchar us)
  50. {
  51.   while(--us);
  52. }

  53. /*ms級(jí)別      */
  54. void delayms(uint ms)
  55. {
  56. uint i;
  57. uchar j;
  58. for(i=0;i<ms;i++)
  59.    for(j=0;j<250;j++)
  60.    {
  61.     _nop_();          //一個(gè)機(jī)器周期,1us
  62.     _nop_();          //適用于精度高的
  63.     _nop_();
  64.     _nop_();
  65.    }
  66. }
  67. /*復(fù)位,每次讀寫之前都要進(jìn)行復(fù)位*/
  68. /**********************************/
  69. bit ow_reset(void)
  70. {

  71. DQ = 1 ;       //DQ復(fù)位
  72. delayus(8) ;     //稍做延時(shí)

  73. DQ = 0; //拉低約600us
  74. delayus(250);


  75. DQ = 1;//產(chǎn)生上升沿,延時(shí)約15~60us
  76. delayus(20);

  77. presence=DQ;      


  78. delayus(250);
  79.         

  80. return(presence); //等待應(yīng)答信號(hào) 0允許,1禁止

  81. }

  82. /*讀取數(shù)據(jù)一位            */
  83. //---------------------------------
  84. bit Read_bit()
  85. {
  86. uint i = 0;
  87. bit b = 0;

  88. DQ = 0; //產(chǎn)生讀時(shí)隙  
  89. i++;         //維持低電平至少1us

  90. DQ = 1; //1us以上后拉高
  91. delayus(2); //延時(shí)8us,DO下降沿15內(nèi)ds18b20輸出的數(shù)據(jù)才有效


  92. b = DQ; //讀取數(shù)據(jù)
  93. delayus(40);         //每個(gè)讀時(shí)隙至少持續(xù)60us

  94. return(b);
  95. }

  96. /*讀取一個(gè)字節(jié)             */
  97. //------------------------------------
  98. uchar Read_byte()
  99. {
  100. uchar byte_read = 0;
  101. uchar i, j;

  102. for(i=0; i<8; i++)
  103.   {
  104.    j = Read_bit();
  105.    byte_read = (j<<i) | byte_read; //低位讀起
  106.   }

  107. return(byte_read);
  108. }

  109. //-----------------------------------------
  110. /*寫一個(gè)字節(jié)         */
  111. void Write_byte(uchar byte_to_write)
  112. {
  113. uchar i = 0;
  114. uchar j = 0;
  115. bit write_bit = 0;

  116. for(j=0; j<8; j++)
  117.   {
  118.    write_bit =         (byte_to_write & 0x01);
  119.     if(write_bit == 1) //寫1
  120.          {
  121.           DQ = 0;  //產(chǎn)生寫時(shí)隙
  122.          delayus(3);           //延時(shí)15us
  123.          
  124.           DQ = 1;  //寫1
  125.           delayus(40);   //延時(shí),寫時(shí)隙不得低于60us
  126.          }
  127.         else
  128.          {
  129.           DQ = 0;  //產(chǎn)生寫時(shí)隙
  130.           delayus(50);   //延時(shí),保持低約60us~120us
  131.           DQ = 1;  
  132.           i++;
  133.          }
  134.    byte_to_write = byte_to_write >> 1;
  135.   }
  136. }
  137. //-----------------------------------
  138. /*讀取溫度,啟動(dòng)溫度轉(zhuǎn)換*/
  139. /*啟動(dòng)溫度轉(zhuǎn)換*/
  140. void start_convert()
  141. {
  142.   ow_reset();          // 發(fā)出復(fù)位脈沖,每次操作都從復(fù)位開始
  143.   delayms(1);
  144.   Write_byte(0xcc); //skip room命令,跳過(guò)序列號(hào)命令字
  145.   Write_byte(0x44); //啟動(dòng)溫度轉(zhuǎn)換命令
  146. }

  147. /*讀取溫度值*/
  148. void read_tempreture()
  149. {
  150.   ow_reset();          // 發(fā)出復(fù)位脈沖,每次操作都從復(fù)位開始
  151.   delayms(1);
  152.   Write_byte(0xcc); //跳過(guò)rom命令
  153.   Write_byte(0xbe); //讀取暫存器命令
  154.   temp_data[0] = Read_byte(); //存儲(chǔ)溫度低字節(jié)值 (整數(shù)部分低四位和小數(shù)部分) 先從低字節(jié)讀取
  155.   temp_data[1] = Read_byte(); //存儲(chǔ)溫度高字節(jié)值 (其中高五位為符號(hào)位)
  156. }


  157. //下面是LCD1602程序

  158. #include < reg52.h >
  159. #include < ds18b20.h >

  160. #define uchar unsigned char
  161. #define uint   unsigned int

  162. #define lcddata P2

  163. sbit LCDRS=P1^7;              //液晶數(shù)據(jù)選擇命令端
  164. sbit LCDRW=P1^6;             //液晶讀寫命令端
  165. sbit LCDEN=P1^5;            //液晶使能端

  166. uint cc,cc2;       //變量cc中保存讀出的溫度值
  167. float cc1;
  168. uchar flag;    //正負(fù)標(biāo)志
  169. uchar  cdis2[ ] = "+00.00";     //將來(lái)測(cè)得的溫度修改各位即可
  170. uchar code cdis5[ ] = "Temp: ";
  171. uchar code cdis0[ ] = "CHECKING...";
  172. uchar code cdis1[ ] = "   DS18B20 OK   " ;
  173. uchar code cdis3[ ] = " DS18B20   ERR0R " ;
  174. uchar code cdis4[ ] = "   PLEASE CHECK  " ;

  175. void delaylcd(uint z)
  176. {uchar x,y;
  177. for(x=z;x>0;x--)
  178.   {for(y=110;y>0;y--);
  179.   }
  180. }



  181. /*寫命令to lcd        */
  182. /**********************************/
  183. void write_com(uchar com)//寫命令
  184. {
  185.   LCDRW=0;         //低電平為寫
  186.   LCDRS=0;         //低電平為命令選擇
  187.   lcddata=com;
  188.   delaylcd(5);
  189.   LCDEN=1;
  190.   delaylcd(5);
  191.   LCDEN=0;
  192. }


  193. /*lcd1602初始化        */
  194. /**********************************/
  195. void lcd_init(void)
  196. {
  197. LCDRW=0;                 //低電平為寫
  198. LCDEN=0;
  199. write_com(0x38);                 //使用8位數(shù)據(jù)開關(guān),顯示兩行,使用5*7字形

  200. write_com(0x0c);                //顯示器開,光標(biāo)關(guān),字符不閃爍         0x0e 光標(biāo)開

  201. write_com(0x06);           //字符不動(dòng),光標(biāo)自動(dòng)右移動(dòng)一位

  202. write_com(0x01);          //清屏
  203. }



  204. /*寫數(shù)據(jù)to lcd             */
  205. /**********************************/
  206. void write_data(uchar  date)
  207. {
  208. LCDRW=0;  //低電平為寫
  209. LCDRS=1;  //高電平為數(shù)據(jù)選擇
  210. lcddata=date;
  211. delaylcd(5);
  212. LCDEN=1;
  213. delaylcd(5);
  214. LCDEN=0;
  215. }

  216. /*設(shè)定顯示位置             */
  217. /********************************/
  218. void lcd_pos(uchar pos)
  219. {                                 //第一行第幾列直接寫pos為幾,第二行pos從0x40開始
  220.     write_com(pos|0x80);   //數(shù)據(jù)指針=80+地址變量

  221. }


  222. //--------------------------------------
  223. /* CHECKING...顯示              */
  224. void lcd_display()
  225. {
  226. uchar   m ;
  227. lcd_init() ;                 //初始化LCD
  228. lcd_pos(0) ;                 //設(shè)置顯示位置為第一行的第1個(gè)字符
  229.       m = 0 ;
  230.      while(cdis0[m] != '\0')
  231.       {                          //顯示字符
  232.         write_data(cdis0[m]) ;
  233.         m++ ;
  234.       }
  235. }

  236. //--------------------------------------
  237. /* DS18B20 OK 顯示菜單                 */
  238. void Ok_Menu ()
  239. {
  240.      uchar   m ;
  241.      lcd_init() ;                 //初始化LCD
  242.             
  243.      lcd_pos(0) ;                 //設(shè)置顯示位置為第一行的第1個(gè)字符
  244.       m = 0 ;
  245.      while(cdis1[m] != '\0')
  246.       {                          //顯示字符
  247.         write_data(cdis1[m]) ;
  248.         m++ ;
  249.       }         
  250. }




  251. //------------------------------------
  252. /*Temp:      ℃顯示        */
  253. void c_display()
  254. {
  255.   uchar m;
  256.   lcd_init() ;
  257.   lcd_pos(0);
  258.   m=0;
  259.   while(cdis5[m]!='\0')
  260.   {
  261.    write_data(cdis5[m]);
  262.    m++;
  263.   }
  264.   lcd_pos(12);
  265.   write_data(0xDF);                //°
  266.         lcd_pos(13);                  
  267.   write_data('C');
  268. }


  269. //------------------------------------
  270. /*采集溫度轉(zhuǎn)換成LCD顯示的格式                       */

  271. void temperature_trans()
  272. {
  273.      EA=0;                           //DS18B20讀寫數(shù)據(jù)按照嚴(yán)格的時(shí)序,最好不要被打斷,故把所有中斷關(guān)閉
  274.     start_convert();                          //啟動(dòng)溫度轉(zhuǎn)換
  275.     delayms(100);
  276.     read_tempreture();
  277.                                    //讀取溫度
  278.                          cc=temp_data[1]*256+temp_data[0];   
  279.     if(temp_data[1]>0xF8)
  280.        {flag=1;cc=~cc+1;}
  281.                 else
  282.                           flag=0;   //高5位全1負(fù),全0正
  283.     cc1=cc*0.0625;    //浮點(diǎn)數(shù)溫度
  284.     cc2=cc1*100;
  285.     cdis2[1]=cc2/1000+0x30;
  286.     if(cdis2[1]==0x30)
  287.        cdis2[1]=0x20;
  288.         cdis2[2]=cc2/100%10+0x30;
  289.         cdis2[4]=cc2%100/10+0x30;
  290.         cdis2[5]=cc2%10+0x30;
  291.         if(flag==1)
  292.            cdis2[0]='-';
  293.         else
  294.            cdis2[0]='+';
  295.     EA=1;
  296.    
  297.                                 
  298. }


  299. //------------------------------------
  300. /*溫度顯示                       */
  301. void temperature_display()
  302. {

  303.      uchar m;   
  304.      lcd_pos(6);                 //設(shè)置顯示位置為第一行的第6個(gè)字符
  305.      m=0;
  306.      while(cdis2[m]!='\0')
  307.        {                          //顯示字符
  308.         write_data(cdis2[m]) ;
  309.                 m++;
  310.        }                                                                  
  311. }

  312. //下面是根據(jù)采集溫度和設(shè)定溫度差值查表得輸出的程序

  313. #include <reg52.h>
  314. #include <lcd1602.h>

  315. #define uint unsigned int

  316. float set_temp=20.0000;     //設(shè)置溫度


  317. uchar u;
  318. uchar e_f;  
  319.         
  320. void fuzzy()
  321. {
  322.         
  323.         float e=cc1-set_temp;  //算出誤差
  324.   unsigned int code ely[ ]={0,1,2,3,4};
  325.   unsigned int code uly[ ]={0,1,2,3,4};


  326.   e_f=(e/5*10+5)/10;   //誤差轉(zhuǎn)換成0-4整數(shù)

  327.   if(e_f<0)
  328.   {e_f=0;}
  329.   if(e_f>4)
  330.   e_f=4;

  331.   u=uly[e_f];          //差表得到控制輸出,改變PWM占空比
  332. }


  333. //下面是PWM的程序

  334. #include<reg52.h>
  335. #include<fuzzy.h>
  336. #include<lcd1602.h>

  337. #define uint unsigned int
  338. #define uchar unsigned char

  339. uchar time;  //計(jì)數(shù)
  340. uchar zkb;  //占空比

  341. sbit pwm=P1^0;                //P1^0口輸出方波



  342. void pwmchange()                  //根據(jù)算法輸出調(diào)節(jié)占空比,5個(gè)檔位
  343. {
  344.         EA=0;
  345.         if(u==0)
  346.           {zkb=0;}
  347.         else if(u==1)
  348.                 {zkb=25;}
  349.         else if(u==2)        
  350.                 {zkb=50;}
  351.         else if(u==3)
  352.                 {zkb=75;}
  353.         else if(u==4)
  354.           {zkb=100;}
  355.   EA=1;
  356. }

  357. //----------------------------------------------

  358. //------------------------------------------
  359. void time_1() interrupt 1
  360. {
  361.         TH0=0xFC;   //T1  10us初值
  362.         TL0=0x18;
  363.         if(time<zkb)
  364.                 pwm=1;      //方波翻轉(zhuǎn)  
  365.         else
  366.                 if(time>=zkb)  
  367.                 pwm=0;
  368.         time++;
  369.          if(time==100)       //100份 最大100%
  370.                 time=0;

  371. }
復(fù)制代碼




回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2019-4-15 15:18 | 顯示全部樓層
程序不全,猜不出來(lái)。
回復(fù)

使用道具 舉報(bào)

ID:490607 發(fā)表于 2019-4-15 18:31 | 顯示全部樓層
wulin 發(fā)表于 2019-4-15 15:18
程序不全,猜不出來(lái)。

謝謝你得提醒。我馬上上傳完整程序
回復(fù)

使用道具 舉報(bào)

ID:490607 發(fā)表于 2019-4-15 19:03 | 顯示全部樓層
wulin 發(fā)表于 2019-4-15 15:18
程序不全,猜不出來(lái)。

已經(jīng)上傳完整程序,請(qǐng)大家?guī)蛶兔Γx謝!
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2019-4-16 06:24 | 顯示全部樓層
gq2352100 發(fā)表于 2019-4-15 18:31
謝謝你得提醒。我馬上上傳完整程序

你的主程序本身就是不完整的,補(bǔ)全后出現(xiàn)更多的錯(cuò)誤和警告。給你一個(gè)比較成熟程序參考。
1602+ds1302+18B20萬(wàn)年歷+仿真.zip (146.93 KB, 下載次數(shù): 9)

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区三区免费 | 久久国产精品一区二区三区 | 欧美日韩一 | 午夜国产精品视频 | 日韩aⅴ片 | 国产精品久久久久久亚洲调教 | 免费一区二区三区在线视频 | 天堂视频中文在线 | 五月天国产在线 | 天天操天天射天天 | 久久久久一区二区三区 | 欧美日韩高清一区二区三区 | 日韩精品免费在线观看 | 不卡av在线 | 久久99国产精一区二区三区 | 国产激情视频网 | 成人精品国产免费网站 | 欧美日韩高清免费 | 国产精品久久久久久久久久 | 伊人欧美视频 | av大片 | 天天天插 | 久久久久国产 | av中文天堂| 久久精品亚洲一区二区三区浴池 | 国产一区二区三区视频 | 亚洲精品一区二区在线观看 | 欧美激情欧美激情在线五月 | av超碰 | 成人毛片在线视频 | 亚洲国产精品99久久久久久久久 | 欧美一区二区在线 | 欧美国产精品一区二区三区 | 亚洲综合色视频在线观看 | 狠狠干美女 | 欧美在线视频一区二区 | 丁香五月缴情综合网 | 午夜影院网站 | 国产一区二区在线免费观看 | 欧美日韩亚洲在线 | 国产综合一区二区 |