找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STC89C52單片機(jī)(PWM直流電機(jī)調(diào)速正反轉(zhuǎn)帶eeprom記憶)源程序

  [復(fù)制鏈接]
ID:424598 發(fā)表于 2020-10-25 16:29 | 顯示全部樓層 |閱讀模式
好久沒玩單片機(jī), 又花了些時間重新找回感覺
花了三天時間測試買了很久的L298N迷你板, 之前接了單片機(jī)的P0^0和P0^1結(jié)果沒有反應(yīng), 還以為是L298N壞了
L298N模塊1.jpg

L298N模塊2.jpg


老樣子, 單片機(jī)代碼我盡量備注詳細(xì), 別問我要電路圖啊, 引腳接線我都已注明清楚
  1. /*******************************************************************/
  2. /* 程序名稱:STC89C52_PWM直流電機(jī)調(diào)速及正反轉(zhuǎn)
  3. /* 單片機(jī)型號:STC89C52系列 晶振:11.00592 MHz
  4. /* 單片機(jī)供電5V, L298N模塊可共用電源, 也可以單獨外接電源(具體看L298N模塊說明)
  5. /* 直流電機(jī)的PWM波控制,可以直接調(diào)速從0到100共21級(每級+5)
  6. /* 所謂的占空比其實就是利用計數(shù)改變0和1的比列
  7. /*     大家可以接LED測試, 當(dāng)占空比越大, LED燈閃爍越慢, 當(dāng)占空比越小, LED閃爍越快, 直到眼睛都看不出有閃爍
  8. /* 新增功能:
  9. /* 2020.10.24 新增長按停止, 短按保留正反轉(zhuǎn)
  10. /* 2020.10.25 將調(diào)速等級和正反轉(zhuǎn)狀態(tài)寫入EEPROM, 以便關(guān)機(jī)后再次開機(jī)能保留關(guān)機(jī)前狀態(tài)
  11. /*****************************************************************/


  12. #include "eeprom.h"
  13.         
  14. #define TH0_TL0 (65536-1000)//設(shè)定中斷的間隔時長

  15. //引腳聲明
  16. sbit Key_add=P2^0; //電機(jī)加速(輕觸開關(guān)一腳接P2^0, 斜對腳接GND)
  17. sbit Key_minus=P2^1; //電機(jī)減速(輕觸開關(guān)一腳接P2^1, 斜對腳接GND)
  18. sbit Key_fr=P2^2; //電機(jī)反向(輕觸開關(guān)一腳接P2^2, 斜對腳接GND)

  19. //L298N模塊+引腳接VCC, -引腳接GND
  20. //MOTOR-A二個引腳接電機(jī)的二個引腳, 正反自己按需求調(diào)整
  21. sbit PWM1=P2^6; //PWM1 (接L298N模塊的L298N模塊的INT1)
  22. sbit PWM2=P2^7; //PWM2 (接L298N模塊的L298N模塊的INT2)

  23. //配合eeprom使用
  24. uchar code set1[21]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15}; //用來判斷調(diào)速等級
  25. uchar code set2[2]={0x01,0x02}; //用來判斷正反轉(zhuǎn)
  26. uint zsdj; //轉(zhuǎn)速等級
  27. uchar count0; //低電平的占空比
  28. uchar count1 = 0;//高電平的占空比
  29. bit Flag;//電機(jī)正反轉(zhuǎn)標(biāo)志位 -- 1正轉(zhuǎn),0反轉(zhuǎn)
  30. bit zt = 1; //記錄狀態(tài)(1啟動, 0停止)


  31. //用于判斷Key_fr的長按短按
  32. #define key_S 500 //宏定義短按(約20ms)
  33. #define key_L 16000 //宏定義長按(約2/3s)
  34. #define key_M 8000 //宏定義長按間隔(約1/3s)


  35. /************函數(shù)聲明**************/
  36. void Write_Eeprom(void); //寫eeprom
  37. void Motor_High_speed(void); //馬達(dá)高速
  38. void Motor_Low_speed(void); //馬達(dá)低速
  39. void Motor_Forward_and_Reverse(void); //馬達(dá)正反轉(zhuǎn)
  40. void Timer0_init(void); //定時器0初始化


  41. /*寫eeprom*/
  42. void Write_Eeprom(void){
  43.         IapEraseSector(0x2000); //擦除0x2000--0x21FF
  44.         IapProgramByte(0x2001,set1[zsdj]); //存儲count0
  45.         IapProgramByte(0x2002,set2[Flag]); //存儲Flag
  46. }


  47. /*******按鍵+處理增加PWM,PWM越大,電機(jī)越快**********/
  48. void Motor_High_speed(void)
  49. {
  50.         if(Key_add==0)
  51.         {
  52.                 Delay(10);
  53.                 if(Key_add==0)
  54.                 {
  55.                         count0 += 5;
  56.                         zsdj += 1;

  57.                         if(count0 >= 100)
  58.                         {
  59.                                 count0 = 100;
  60.                         }        
  61.                         if(zsdj >= 20)
  62.                         {
  63.                                 zsdj = 20;
  64.                         }
  65.                         Write_Eeprom(); //eeprom操作
  66.                 }
  67.                 while(!Key_add);//等待鍵松開
  68.         }
  69. }

  70. /*******按鍵-處理減少PWM,PWM越小,電機(jī)越慢**********/
  71. void Motor_Low_speed(void)
  72. {
  73.         if(Key_minus==0)
  74.         {
  75.           Delay(10);
  76.           if(Key_minus==0)
  77.           {
  78.             count0 -= 5;
  79.                         zsdj -= 1;
  80.                         
  81.             if(count0 <= 0)
  82.             {
  83.                     count0 = 0;
  84.             }
  85.                         if(zsdj <= 0)
  86.                         {
  87.                                 zsdj = 0;
  88.                         }
  89.                         Write_Eeprom(); //eeprom操作
  90.           }
  91.           while(!Key_minus);
  92.         }
  93. }

  94. /************電機(jī)正反向控制**************/
  95. void Motor_Forward_and_Reverse(void)
  96. {
  97.                 static uint jcs=0; //計數(shù)變量
  98.                 if(!Key_fr)   
  99.                 {  
  100.                         jcs++;  
  101.                         if(jcs>=key_L) //長按
  102.                         {      
  103.                                 jcs=key_M; //設(shè)一個值
  104.                                 zt=0; //停止
  105.                         }
  106.                 }  
  107.                 else //按鍵抬起
  108.                 {  
  109.                                 if(jcs>key_S && jcs<key_M)//短按
  110.                                 {
  111.                                         if(zt==1){
  112.                                                 Flag=~Flag; //當(dāng)狀態(tài)為1時,才會切換正反轉(zhuǎn)                        
  113.                                                 Write_Eeprom(); //eeprom操作
  114.                                         }
  115.                                         if(zt==0){
  116.                                                 PWM1=0; //當(dāng)狀態(tài)為0時,啟動為正轉(zhuǎn)
  117.                                                 PWM2=1;        
  118.                                         }
  119.                                         zt=1; //設(shè)狀態(tài)為1
  120.                                 }
  121.                                 jcs=0;  //count清0
  122.                 }
  123. }

  124. /***********定時器0初始化***********/
  125. void Timer0_init(void)
  126. {
  127.         TMOD=0x01; //定時器0工作于方式1
  128.         TH0=TH0_TL0/256;
  129.         TL0=TH0_TL0%256;
  130.         TR0=1;
  131.         ET0=1;
  132.         EA=1;
  133. }

  134. /*********主函數(shù)********************/
  135. void main(void)
  136. {
  137.         //開機(jī)初始化定時器0
  138.         Timer0_init();
  139.         
  140.         //開機(jī)讀取記憶數(shù)據(jù)(轉(zhuǎn)速等級)
  141.         switch(IapReadByte(0x2001))
  142.         { //判斷
  143.                 case 0x01:count0=0;zsdj=0;break;
  144.                 case 0x02:count0=5;zsdj=1;break;
  145.                 case 0x03:count0=10;zsdj=2;break;
  146.                 case 0x04:count0=15;zsdj=3;break;
  147.                 case 0x05:count0=20;zsdj=4;break;
  148.                 case 0x06:count0=25;zsdj=5;break;
  149.                 case 0x07:count0=30;zsdj=6;break;
  150.                 case 0x08:count0=35;zsdj=7;break;
  151.                 case 0x09:count0=40;zsdj=8;break;
  152.                 case 0x0A:count0=45;zsdj=9;break;
  153.                 case 0x0B:count0=50;zsdj=10;break;
  154.                 case 0x0C:count0=55;zsdj=11;break;
  155.                 case 0x0D:count0=60;zsdj=12;break;
  156.                 case 0x0E:count0=65;zsdj=13;break;
  157.                 case 0x0F:count0=70;zsdj=14;break;
  158.                 case 0x10:count0=75;zsdj=15;break;
  159.                 case 0x11:count0=80;zsdj=16;break;
  160.                 case 0x12:count0=85;zsdj=17;break;
  161.                 case 0x13:count0=90;zsdj=18;break;
  162.                 case 0x14:count0=95;zsdj=19;break;
  163.                 case 0x15:count0=100;zsdj=20;break;
  164.                 default:count0=50;zsdj=10;
  165.         }
  166.         
  167.         //開機(jī)讀取記憶數(shù)據(jù)(正向或反向)
  168.         if(IapReadByte(0x2002)==0x01){
  169.                 Flag = 0;
  170.         }
  171.         else if(IapReadByte(0x2002)==0x02){
  172.                 Flag = 1;
  173.         }

  174.         while(1)
  175.         {         
  176.           Motor_High_speed(); //加速
  177.           Motor_Low_speed(); //減速
  178.                 Motor_Forward_and_Reverse(); //正反轉(zhuǎn)
  179.         }
  180. }
復(fù)制代碼

全部代碼請下載附件 STC89C52(PWM直流電機(jī)調(diào)速正反轉(zhuǎn)帶eeprom記憶).zip (190.92 KB, 下載次數(shù): 153)

評分

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

查看全部評分

回復(fù)

使用道具 舉報

ID:89286 發(fā)表于 2020-10-26 08:01 | 顯示全部樓層
thanks for sharing
回復(fù)

使用道具 舉報

ID:838184 發(fā)表于 2020-11-3 11:16 | 顯示全部樓層
thanks for sharing
回復(fù)

使用道具 舉報

ID:722684 發(fā)表于 2020-11-7 16:00 | 顯示全部樓層
Thanks for sharing
回復(fù)

使用道具 舉報

ID:840797 發(fā)表于 2020-11-9 07:01 | 顯示全部樓層
雖然暫時看不懂,還是要頂一個。
回復(fù)

使用道具 舉報

ID:100749 發(fā)表于 2020-11-12 10:28 來自手機(jī) | 顯示全部樓層
沒有電路圖嗎
回復(fù)

使用道具 舉報

ID:967893 發(fā)表于 2021-9-24 10:16 | 顯示全部樓層
thanks for sharing
回復(fù)

使用道具 舉報

ID:540334 發(fā)表于 2021-9-25 00:00 來自手機(jī) | 顯示全部樓層
受教了,感謝大師
回復(fù)

使用道具 舉報

ID:917597 發(fā)表于 2021-10-15 17:32 | 顯示全部樓層
萌新求教,有沒有大佬能夠解釋一下,我想問一下按下按鍵之后,對應(yīng)的zsdj和count0變化以后,是怎樣改變pwm波的占空比的?我只看到按鍵程序改變轉(zhuǎn)速等級和占空比變量的數(shù)值最后面的定時器中斷貌似沒改變時間啊,是我理解不到位嗎?
回復(fù)

使用道具 舉報

ID:970710 發(fā)表于 2021-10-20 08:42 | 顯示全部樓層
感謝分享,你的資料很有參考價值!
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表