標(biāo)題: 電動(dòng)牙刷的MCU驅(qū)動(dòng)程序 [打印本頁]

作者: 小胖波波    時(shí)間: 2019-6-17 13:32
標(biāo)題: 電動(dòng)牙刷的MCU驅(qū)動(dòng)程序
這是電動(dòng)牙刷的驅(qū)動(dòng)程序,電路可以采用電池供電,也可以USB供電,可以檢測(cè)電量的多少

單片機(jī)源程序如下:
  1. #include "main.h"

  2. void main(void)
  3. {
  4.         SystemInit();
  5.         while(1)
  6.         {
  7.                 BatteryVoltageWarning();
  8.                 KeyScan();
  9.                 switch (key_flag)
  10.                 {
  11.                         case 0: Led50 = 1;Led70 = 1;Led100 = 1;  //檔位指示燈全滅
  12.                                         MotorA = 1;MotorB = 1;   //電機(jī)不轉(zhuǎn)
  13.                                         break;
  14.                         case 1: Led50 = 0;Led70 = 1;Led100 = 1;  //1擋指示燈亮
  15.                                         MotorA = 0;MotorB = 1;
  16.                                         break;
  17.                         case 2: Led50 = 1;Led70 = 0;Led100 = 1;  //2擋指示燈亮
  18.                                        
  19.                                         break;
  20.                         case 3: Led50 = 1;Led70 = 1;Led100 = 0;  //3擋指示燈亮
  21.                                        
  22.                                         break;
  23.                         default: break;
  24.                 }
  25.                 if(time_flag == 4)   //time_flag為4時(shí),即4*30s=120s,2分鐘,此時(shí)電機(jī)停轉(zhuǎn)
  26.                         key_flag = 0;                       
  27.         }
  28. }

  29. /******延時(shí)x毫秒******/
  30. void DelayMs( uint x )                //@11.0592MHz
  31. {
  32.         uint a;
  33.         for(a=0;a<x;a++)
  34.         {
  35.                 uchar i, j;
  36.                 _nop_();
  37.                 i = 2;
  38.                 j = 199;
  39.                 do
  40.                 {
  41.                         while (--j);
  42.                 } while (--i);
  43.         }
  44. }

  45. /*******系統(tǒng)初始化******/
  46. void SystemInit()
  47. {
  48.         Led50 = 1;
  49.         Led70 = 1;
  50.         Led100 = 1;
  51.         LedPower = 1;
  52.         ModeKey = 1;
  53.         MotorA = 1;
  54.         MotorB = 1;
  55.         Timer0Init();
  56. }

  57. /*******定時(shí)器0初始化*****/
  58. void Timer0Init()                //333us @11.0592MHz  0.03%誤差
  59. {
  60.         TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
  61.         TMOD |= 0x01;                //設(shè)置定時(shí)器模式
  62.         TL0 = 0xCD;                //設(shè)置定時(shí)初值
  63.         TH0 = 0xFE;                //設(shè)置定時(shí)初值
  64.         TF0 = 0;                //清除TF0標(biāo)志
  65.         TR0 = 1;                //定時(shí)器0開始計(jì)時(shí)
  66.         ET0 = 1;          //開啟定時(shí)器0中斷
  67.         EA = 1;     //開啟總中斷
  68. }

  69. /*******讀ADC0832函數(shù)******/
  70. uchar Adc0832(uchar channel)     //AD轉(zhuǎn)換,返回結(jié)果
  71. {
  72.     uchar i=0;
  73.     uchar j;
  74.     uint dat=0;
  75.     uchar ndat=0;

  76.     if(channel==0)channel=2;
  77.     if(channel==1)channel=3;
  78.     ADDI=1;
  79.     _nop_();
  80.     _nop_();
  81.     ADCS=0;                    //拉低CS端
  82.     _nop_();
  83.     _nop_();
  84.     ADCLK=1;                   //拉高CLK端
  85.     _nop_();
  86.     _nop_();
  87.     ADCLK=0;                   //拉低CLK端,形成下降沿1
  88.     _nop_();
  89.     _nop_();
  90.     ADCLK=1;                   //拉高CLK端
  91.     ADDI=channel&0x1;
  92.     _nop_();
  93.     _nop_();
  94.     ADCLK=0;                   //拉低CLK端,形成下降沿2
  95.     _nop_();
  96.     _nop_();
  97.     ADCLK=1;                   //拉高CLK端
  98.     ADDI=(channel>>1)&0x1;
  99.     _nop_();
  100.     _nop_();
  101.     ADCLK=0;                   //拉低CLK端,形成下降沿3
  102.     ADDI=1;                    //控制命令結(jié)束
  103.     _nop_();
  104.     _nop_();
  105.     dat=0;
  106.     for(i=0;i<8;i++)
  107.     {
  108.         dat|=ADDO;            //收數(shù)據(jù)
  109.         ADCLK=1;
  110.         _nop_();
  111.         _nop_();
  112.         ADCLK=0;              //形成一次時(shí)鐘脈沖
  113.         _nop_();
  114.         _nop_();
  115.         dat<<=1;
  116.         if(i==7)dat|=ADDO;
  117.     }  
  118.     for(i=0;i<8;i++)
  119.     {
  120.         j=0;
  121.         j=j|ADDO;            //收數(shù)據(jù)
  122.         ADCLK=1;
  123.         _nop_();
  124.         _nop_();
  125.         ADCLK=0;             //形成一次時(shí)鐘脈沖
  126.         _nop_();
  127.         _nop_();
  128.         j=j<<7;
  129.         ndat=ndat|j;
  130.         if(i<7)ndat>>=1;
  131.     }
  132.     ADCS=1;                 //拉低CS端
  133.     ADCLK=0;                //拉低CLK端
  134.     ADDO=1;                 //拉高數(shù)據(jù)端,回到初始狀態(tài)
  135.     dat<<=8;
  136.     dat|=ndat;
  137.     return(dat);            //return ad k         
  138. }

  139. /*******電池低電量警告******/
  140. void BatteryVoltageWarning()
  141. {
  142.         ad_data =Adc0832(0);         //讀取電池電壓采樣值
  143.         //ADC0832模數(shù)轉(zhuǎn)換是8位ADC芯片,轉(zhuǎn)換回來的數(shù)值是0-255,0V時(shí)是0,5V時(shí)是255,相應(yīng)的倍數(shù)就是255/5=51
  144.         //因此,將轉(zhuǎn)換回來的數(shù)除以51,就得到相應(yīng)的電壓值了
  145.         battery_voltage = (double)(ad_data)/51.0;      
  146.         if(battery_voltage < 0.7)     //當(dāng)電池電壓小于0.7V,即電量低于20%時(shí),低電量指示燈亮
  147.                 LedPower = 0;
  148.         else
  149.                 LedPower = 1;
  150. }

  151. /*******按鍵掃描******/
  152. uchar KeyScan()
  153. {
  154.         if(!ModeKey)
  155.         {
  156.                 DelayMs(10);
  157.                 if(!ModeKey)
  158.                 {
  159.                         time_30s = 0;
  160.                         time_flag = 0;   //每次按檔位模式按鍵,電機(jī)轉(zhuǎn)動(dòng)都要復(fù)位,即清零已經(jīng)轉(zhuǎn)動(dòng)的時(shí)間
  161.                         key_flag++;
  162.                         if(key_flag > 3)
  163.                                 key_flag = 0;
  164.                 }
  165.                 while(!ModeKey);
  166.         }
  167.         return key_flag;       
  168. }

  169. /*******產(chǎn)生電機(jī)PWM******/
  170. void MotorControl(uchar pwm, uchar ab)
  171. {
  172.         if(pwm > 10)
  173.                 pwm = 10;
  174.         if(time_30s > 90000)  //約為90000*333us=30s
  175.         {
  176.                 time_30s = 0;
  177.                 time_flag++;    //每30s停轉(zhuǎn)一次,每停轉(zhuǎn)一次time_flag就加一
  178.                 if(time_flag > 4)   //time_flag加到4,即4*30s=120s,2分鐘
  179.                         time_flag = 0;
  180.                 MotorA = 1;
  181.                 MotorB = 1;      
  182.                 DelayMs(1000);  //電機(jī)每隔30s停轉(zhuǎn)1s
  183.         }
  184.         else
  185.         {
  186.                 if(time_pwm > 10)  //PWM周期為10*333us=3.33ms,頻率約為1/3.33ms=300.3Hz
  187.                         time_pwm = 0;
  188.                 if(ab=='A')       //如果參數(shù)為A
  189.                 {
  190.                         MotorB = 0;   //則產(chǎn)生正脈沖,此時(shí)電機(jī)正轉(zhuǎn)
  191.                         if(time_pwm < pwm)        //占空比為(pwm/10*100%),改變pwm值(范圍0-10)即改變占空比(對(duì)應(yīng)0-100%),從而可以改變電機(jī)的速度
  192.                                 MotorA = 1;
  193.                         else
  194.                                 MotorA = 0;
  195.                 }
  196.                 else if(ab=='B')  //如果參數(shù)為B
  197.                 {
  198.                         MotorA = 0;   //則產(chǎn)生負(fù)脈沖,此時(shí)電機(jī)反轉(zhuǎn)
  199.                         if(time_pwm < pwm)        //占空比為(pwm/10*100%),改變pwm值(范圍0-10)即改變占空比(對(duì)應(yīng)0-100%),從而可以改變電機(jī)的速度
  200.                                 MotorB = 1;
  201.                         else
  202.                                 MotorB = 0;
  203.                 }
  204.         }
  205. }

  206. /*******定時(shí)器0中斷******/
  207. void Time0(void) interrupt 1   
  208. {
  209.         TL0 = 0xCD;               
  210.         TH0 = 0xFE;      //重新賦初值333us,0.03%誤差
  211.         time_pwm++;         
  212.         time_30s++;     //每333us進(jìn)入一次中斷,同時(shí)time_pwm、time_30s值各加一
  213. }
復(fù)制代碼

所有資料51hei提供下載:
程序.zip (44.38 KB, 下載次數(shù): 65)



作者: admin    時(shí)間: 2019-6-17 15:56
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
作者: 小胖波波    時(shí)間: 2019-6-18 14:00
admin 發(fā)表于 2019-6-17 15:56
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)

我上傳一個(gè)仿真圖吧
作者: mcu_mpu    時(shí)間: 2019-8-12 10:19
好東西,學(xué)習(xí)下。
作者: cabot    時(shí)間: 2019-8-28 16:05
樓主有沒原理圖,謝謝
作者: cba_cba    時(shí)間: 2019-9-10 12:00
看看,能不能有用。
作者: m182892    時(shí)間: 2019-9-11 08:50
下載看了一下,牙刷里面就是一個(gè)電機(jī),正轉(zhuǎn)反轉(zhuǎn)線路怎么接,還是要有原理圖才清楚。
作者: IdeaMing    時(shí)間: 2019-9-11 09:48
admin 發(fā)表于 2019-6-17 15:56
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)

管理員建議太好了
作者: 我要打十個(gè)    時(shí)間: 2019-10-31 20:14
希望樓主能上傳看看
作者: cabot    時(shí)間: 2019-11-15 15:24
樓主,程序我有看了,有問題啊,你都沒有調(diào)動(dòng)MotorControl(uchar pwm, uchar ab)這個(gè)函數(shù)
作者: SilentK    時(shí)間: 2020-3-18 09:30
下下來研究研究。!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1