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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機溫控紅外遙控風扇源程序 舵機對直流電機控制方向

[復制鏈接]
跳轉到指定樓層
樓主
ID:638921 發表于 2020-11-26 22:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
通過DS18b20來測溫度,在lcd1602上顯示溫度和時間,時間初始值設為18:30,當溫度超過26度時,直流電機打開,蜂鳴器報警,低于26關閉。也可遙控打開或關閉電機,沒有使用舵機,此時直流電機不能改變方向。
當遙控器按下時,lcd1602顯示turn off,無法顯示溫度,定時器1初始化,舵機可以使用,利用舵機對直流電機來控制方向,只有0,45,90,135,180,五個角度可以選。

將ds18b20和舵機分開使用的原因,ds18b20對時序的要求很高,如果用舵機的話就會使溫度無法正常顯示,

遇到的問題:
       剛開始是直接在main函數里面使用舵機和溫度傳感器,發現溫度顯示不了,然后我想的在main函數用舵機,然后再用一個定時器,每隔一定時間顯示溫度,這樣用到兩個定時器,需要考慮優先級,舵機用定時器1,溫度用定時器0,這樣才能每隔一定時間刷新溫度,但是這樣發現舵機和溫度都不能正常工作,我認為,因為舵機要保持一個角度話,必須持續給他該角度下的脈沖,兩個定時器可能沖突了,
         然后我就將兩個東西分開用,在兩者之間來回切換,在用完舵機,準備用18b20的時候,就令TR1=0;可是這樣做溫度還是顯示不了,而且在關定時器的同時,我還重新初始化18b20和lcd1602,還是沒用,但是如果按下復位鍵的話,就可以顯示,在網上找了很久也提問了沒有結果,我試過用串口打印ds18b20i/o的值,發現如果沒切換,可以打印溫度,切換后就沒有值打印出來,于是我就想能不能在按下遙控上的鍵就執行軟件復位,但是有人說,51不能軟件復位,我最后居然想的是,(我看開發板原理圖,發現復位鍵按下時,RST管腳就為高電平,RST管腳默認為低電平),我用一根杜邦線,一端接在RST上,另一端就隨便接在一個管腳上P1^1,通過改變P1^1的電平,來改變RST的電壓,但是給P1^1高電平的時候,并沒有復位,有人說,可能是電壓不夠。我分別測了一下,它的對地電壓只有2.4v的樣子。
復位按鍵下兩端的電壓大約4.8v左右,確實是電壓不不夠,我想升壓,我想起來有些管腳它是本身開發板就給他加了上拉電阻,看了原理圖,測了一下其中一個電壓,果然有4.4v,我把它接到RST的時候,就復位了,但是我這樣做發現,在程序中一但執行復位后,它會一直復位,比如P3^6=1;//復位delay(1000);P3^6=0;//P3^6管腳有上拉電阻。在它復位后,P1^1=0;根本沒機會執行;而P3^6默認為高電平。這種方法就不行。
    我最后就打算手動復位,我準備加上ds1302,讓1302和溫度同時顯示,發現溫度又用不了,我在網上看到有一些人也是同樣的問題,但是在一個論壇里面,有人說在1302讀溫度的時候,在最后,讓CE=1;就可以了,不過他也不知道原因,百度上顯示ds1302有些是CE,有些是RST,RST是CE的舊稱,我試了一下,發現可以,而且把之前切換后不能顯示的問題也解決了,就是不知道原因。到這里我要做的就基本完成了。

待改進:
最需要改進兩個地方
1.直流電機的速度沒能實現調節
2.舵機的角度不能為任意角度轉動


單片機源程序如下:
  1. #include "reg52.h"                        
  2. #include"temp.h"
  3. #include"1302.h"        
  4. sbit  IRIN=P3^2;  //紅外
  5. sbit  duoji=P3^5;

  6. uchar IrValue[6];//溫度數組
  7. uchar zxc,count=0,flag1=1,flag2,k,m;
  8. uchar Disp[16]="trun off        ";
  9. uchar push_val_left=14,pwm_val_left;
  10. uint timer=0,flex;

  11. uchar DisplayData[14]={'t'-0x30,'e'-0x30,'m'-0x30,'p'-0x30,':'-0x30,' '-0x30};
  12. uchar code smgduan[10]={0,1,2,3,4,5,6,7,8,9};
  13. void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time)
  14. {
  15.                   push_val_left=5+angle*20/180;          //舵機向左轉90度
  16.                  // timer=0;
  17.                   while(timer<=Servo_time); //延時400MS讓舵機轉到其位置                 4000
  18.                   delay(flex);
  19. }
  20. void pwm_Servomoto(void)
  21. {  

  22.     if(pwm_val_left<=push_val_left)
  23.                duoji=1;
  24.         else
  25.                duoji=0;
  26.         if(pwm_val_left>=200)
  27.         pwm_val_left=0;

  28. }

  29. void datapros(int temp)         
  30. {
  31.            float tp; uint h=4000;
  32.         if(temp< 0)                                //當溫度值為負數
  33.           {
  34.                 DisplayData[0] = 0x40;           //   -
  35.                 //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼
  36.                 temp=temp-1;
  37.                 temp=~temp;
  38.                 tp=temp;
  39.                 temp=tp*0.0625*100+0.5;        
  40.                

  41.           }
  42.          else
  43.           {                        
  44.                 DisplayData[6] = 0x00;
  45.                 tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
  46.                 //如果溫度是正的那么,那么正數的原碼就是補碼它本身
  47.                 temp=tp*0.0625*100+0.5;        
  48.                
  49.         }
  50.         if(flag2==0)
  51.         if(temp>2600)
  52.            {dj=1;
  53.            while(h)
  54.            {beep=~beep;
  55.            delay(10);
  56.                   h--;
  57.                 }
  58.            }
  59.         else
  60.            dj=0;
  61.         DisplayData[7] = smgduan[temp / 10000];
  62.         DisplayData[8] = smgduan[temp % 10000 / 1000];
  63.         DisplayData[9] = smgduan[temp % 1000 / 100] ;
  64.         DisplayData[10] = -2;
  65.         DisplayData[11] = smgduan[temp % 100 / 10];
  66.         DisplayData[12] = smgduan[temp % 10];
  67.         DisplayData[13] =51;
  68.         
  69. }
  70. void test_servo(void)
  71. {
  72. int pos;
  73.         for(pos=0;pos<180;pos+=3)
  74.         {
  75.                

  76.         
  77.                 pwm_Servomoto_angle(pos,100) ;
  78.                 delay(300);
  79.         }
  80.         for(pos = 180; pos>=0; pos-=3)     // goes from 180 degrees to 0 degrees
  81.         {
  82.         
  83.           pwm_Servomoto_angle(pos,100) ;
  84.           delay(300);
  85.         }
  86. }
  87.                                                                   
  88. void LcdDisplay()
  89. {
  90.         lcdwrc(0x80+0X40);
  91.         lcdwrd('t');
  92.         lcdwrd('i');
  93.         lcdwrd('m');
  94.         lcdwrd('e');
  95.         lcdwrd(':');
  96.         lcdwrd(' ');
  97.         lcdwrd('0'+hsp[2]/16);                                //時
  98.         lcdwrd('0'+(hsp[2]&0x0f));                                 
  99.         lcdwrd('-');
  100.         lcdwrd('0'+hsp[1]/16);                                //分
  101.         lcdwrd('0'+(hsp[1]&0x0f));        
  102.         lcdwrd('-');
  103.     lcdwrd('0'+hsp[0]/16);                                //秒
  104.         lcdwrd('0'+(hsp[0]&0x0f));
  105. }                                                                                          

  106.                                                                 //外部中斷0初始化
  107. void IrInit()           
  108. {
  109.         IT0=1;//下降沿觸發
  110.         EX0=1;//打開中斷0允許
  111.         EA=1;        //打開總中斷

  112.         IRIN=1;//初始化端口
  113. }
  114.                                 //定時器1初始化
  115. void timeinit()
  116. {TMOD=0X10;
  117.         TH1=(65536-100)/256;          //100US定時
  118.         TL1=(65536-100)%256;
  119.         TR1= 1;
  120.         ET1= 1;
  121.         EA = 1;
  122. }               

  123.                                 //main函數
  124. void main()
  125. {uchar i,n=0;
  126. IrInit(); //紅外初始化
  127. lcdinit();
  128. Ds1302Init();

  129.   dj=0;
  130. while(1)
  131.   {
  132.     if(flag1==1)         //關閉定時器,實現功能為超過設定溫度打開電機
  133.        {  
  134.              Ds1302ReadTime();
  135.              datapros(Ds18b20ReadTemp());         //數據處理函數
  136.          for(i=0;i<14;i++)
  137.               {               
  138.                lcdwrd(DisplayData[i]+0x30);
  139.               }
  140.                LcdDisplay();
  141.               lcdwrc(0x80);
  142.            }
  143.     else        //打開定時器,(電機舵機)關閉溫度傳感器,和lcd1602
  144.             {  if(m==0)
  145.                     { timeinit();
  146.                       m=1;
  147.                           dj=0;
  148.                     }
  149.                         test_servo();
  150.                  for(n=0;n<16;n++)
  151.                {
  152.                     lcdwrd(Disp[n]);        
  153.                 }
  154.                    lcdwrc(0x80+0x40);
  155.                   for(n=0;n<16;n++)
  156.                     { lcdwrd(' ');
  157.                         }
  158.                   
  159.               lcdwrc(0x80);
  160.                 }
  161.                
  162.   }
  163. }
  164. void ReadIr() interrupt 0
  165. {
  166.         uchar j,k;
  167.         uchar err;
  168.     zxc=0;                                         
  169.         delay(700);        //7ms
  170.         if(IRIN==0)                //確認是否真的接收到正確的信號
  171.         {         
  172.                
  173.                 err=1000;                                //1000*10us=10ms,超過說明接收到錯誤的信號
  174.                         
  175.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低電平過去                  
  176.                 {                        
  177.                         delay(1);
  178.                         err--;
  179.                 }
  180.                 if(IRIN==1)                        //如果正確等到9ms低電平
  181.                 {
  182.                         err=500;
  183.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高電平過去
  184.                         {
  185.                                 delay(1);
  186.                                 err--;
  187.                         }
  188.                         for(k=0;k<4;k++)                //共有4組數據
  189.                         {                                
  190.                                 for(j=0;j<8;j++)        //接收一組數據
  191.                                 {

  192.                                         err=60;               
  193.                                         while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
  194.                                         {
  195.                                                 delay(1);
  196.                                                 err--;
  197.                                         }
  198.                                         err=500;
  199.                                         while((IRIN==1)&&(err>0))         //計算高電平的時間長度。
  200.                                         {
  201.                                                 delay(10);         //0.1ms
  202.                                                 zxc++;
  203.                                                 err--;
  204.                                                 if(zxc>30)
  205.                                                 {
  206.                                                         return;
  207.                                                 }
  208.                                         }
  209.                                         IrValue[k]>>=1;         //k表示第幾組數據
  210.                                         if(zxc>=8)                        //如果高電平出現大于565us,那么是1
  211.                                         {
  212.                                                 IrValue[k]|=0x80;
  213.                                         }
  214.                                         zxc=0;                //用完時間要重新賦值                                                        
  215.                                 }
  216.                         }
  217.                 }
  218.                 if(IrValue[2]!=~IrValue[3])
  219.                 {
  220.                         return;
  221.                 }
  222.         }
  223.          if(flag1==0)
  224.          {
  225.                 if(IrValue[2]==0x45)   //電源鍵          模式一 過溫
  226.                 {
  227.                    flag1=1;
  228.                 TR1=0;
  229.                 }
  230.         }
  231.            
  232.         if(flag1==1)
  233.         {
  234.                 if(IrValue[2]==0x46)   //mode         模式二 調整舵機
  235.                 {
  236.                         flag1=0;
  237.                     m=0;
  238.                   }
  239.                 if(IrValue[2]==0x47)
  240.                    {dj=1;                                //                打開電機  注意flag2的作用為設置為了控制優先級大于if(temp>25)
  241.                     flag2=1;
  242.                         }
  243.                 if(IrValue[2]==0x44)         //      關閉電機
  244.                    {dj=0;
  245.                     flag2=0;
  246.                    }
  247.                 if(IrValue[2]==0x16)   //按鍵0 舵機0度
  248.                   flex=550;
  249.                 if(IrValue[2]==0x0c)  //按鍵1 舵機45度
  250.                   flex=1100;
  251.                 if(IrValue[2]==0x18)  //按鍵2 舵機90度
  252.                   ;
  253.                 if(IrValue[2]==0x5e)  //按鍵3 舵機135度
  254.                   ;
  255. ……………………

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

所有資料51hei提供下載:
溫控紅外遙控風扇.zip (2.55 MB, 下載次數: 22)


評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 涩爱av一区二区三区 | 一a级片| 国产91在线精品 | 亚洲午夜精品在线观看 | 特级a欧美做爰片毛片 | 亚洲欧美一区二区三区情侣bbw | 99久久精品国产一区二区三区 | 精品日韩| 久久亚洲精品视频 | 日本成人一区二区 | 天天躁日日躁aaaa视频 | 久久久久久久久久久福利观看 | 亚洲成人一区 | 亚洲国产精品视频一区 | 欧美国产亚洲一区二区 | 美女中文字幕视频 | 午夜av电影| 午夜精品久久久久久 | 超碰人人艹 | 草b视频 | 欧美在线小视频 | 国产精品成人国产乱 | 日本免费网 | 成人av鲁丝片一区二区小说 | 麻豆av电影网 | 日本在线综合 | 九九视频在线观看 | 亚洲一区在线日韩在线深爱 | 国产午夜精品久久久 | 综合国产在线 | 久久综合成人精品亚洲另类欧美 | 超碰天天 | 国产精品久久久久久二区 | 不卡av电影在线播放 | 真人女人一级毛片免费播放 | 国产乱精品一区二区三区 | 狠狠爱免费视频 | 亚洲精品中文字幕 | 久久中文字幕一区 | 97伦理| 91精品一区二区三区久久久久 |