找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3846|回復: 5
打印 上一主題 下一主題
收起左側(cè)

mcu-stc12c5404ad單片機直流無刷電機驅(qū)動程序

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:830475 發(fā)表于 2020-10-15 21:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. //*****************************************************//* ***無刷電機控制器程序*** *//*===================================================* //* MCU-STC12C5404...

  2. //*****************************************************
  3. //* ***無刷電機控制器程序*** *
  4. //*===================================================*
  5. //* mcu-stc12c5404ad 8路ad轉(zhuǎn)換,4路pwm輸出,速度1t *
  6. //*===================================================*
  7. //*****************************************************
  8. #include<reg51.h> //包含文件預處理命令
  9. #define uchar unsigned char //8位單片機習慣性定義
  10. #define uint unsigned int //8位單片機習慣性定義
  11. //
  12. //*********ad轉(zhuǎn)換要用到的特殊寄存器地址定義*************************************
  13. sfr adc_contr=0xc5; //定義ad轉(zhuǎn)換控制寄存器地址
  14. sfr adc_data=0xc6; //定義ad轉(zhuǎn)換結(jié)果寄存器地址
  15. sfr p1m0=0x91; //帶有8路ad的p1口模式選擇寄存器0定義地址
  16. sfr p1m1=0x92; //帶有8路ad的p1口模式選擇寄存器1定義地址
  17. //
  18. //*********pwm輸出要用到的特殊寄存器地址定義************************************
  19. sfr ccap0h=0xfa; //pca模塊0捕捉/比較寄存器高8位
  20. sfr ccap1h=0xfb; //pca模塊1捕捉/比較寄存器高8位
  21. sfr ccap2h=0xfc; //pca模塊2捕捉/比較寄存器高8位
  22. sfr ccap3h=0xfd; //pca模塊3捕捉/比較寄存器高8位
  23. sfr pca_pwm0=0xf2; //pca模塊0-pwm寄存器
  24. sfr pca_pwm1=0xf3; //pca模塊1-pwm寄存器
  25. sfr pca_pwm2=0xf4; //pca模塊2-pwm寄存器
  26. sfr pca_pwm4=0xf5; //pca模塊3-pwm寄存器
  27. sfr ccapm0=0xda; //pca模塊0工作模式寄存器
  28. sfr ccapm1=0xdb; //pca模塊1工作模式寄存器
  29. sfr ccapm2=0xdc; //pca模塊2工作模式寄存器
  30. sfr ccapm3=0xdd; //pca模塊3工作模式寄存器
  31. sfr ch=0xf9; //pca計數(shù)器高8位
  32. sfr cl=0xe9; //pca計數(shù)器低8位
  33. sfr ccon=0xd8; //pca控制寄存器
  34. sfr cmod=0xd9; //pca工作模式寄存器
  35. sbit cr=ccon^6; //pca計數(shù)器控制位,1開0關(guān)
  36. sbit epca_lvd=ie^6; //pca中斷允許控制位1開0關(guān)
  37. sfr auxr=0x8e; //定時器工作于1t控制位
  38. //==============================================================================
  39. sbit zb=p1^3;
  40. sbit pwmal=p2^3; //a相下橋驅(qū)動定義
  41. sbit pwmbl=p2^2; //b相下橋驅(qū)動定義
  42. sbit pwmcl=p2^1; //c相下橋驅(qū)動定義
  43. sbit led=p2^7; //指示燈定義
  44. sbit abs=p2^5; //abs剎車功能選擇口,對地為abs功能
  45. sbit shache=p3^0; //剎車口定義,對地剎車
  46. sbit fd=p3^3; //防盜檢測口定義
  47. int ledcs; //定義一個指示燈閃燈次數(shù)變量
  48. static fd_hej;
  49. static timebj; //定義一個定時器計數(shù)比較變量
  50. static timejs; //定義一個定時器中斷計數(shù)次數(shù)變量
  51. static pwm_bl; //pwm輸出變量
  52. static zs_bl=20; //pwm舊的變量數(shù)據(jù),備份的
  53. static pwm_bls; //pwm軟啟動加速用變量
  54. static shache_bz; //剎車后該標志置1供軟啟動使用
  55. static hehc; //霍爾數(shù)據(jù)暫存區(qū)
  56. static hehc_bl; //上相霍爾數(shù)據(jù)暫存區(qū),用于檢測霍爾變化
  57. static dz_bz; //堵轉(zhuǎn)標志,為1堵轉(zhuǎn)
  58. static dz_bz1;
  59. static zbyx_bz; //轉(zhuǎn)把有效標志,歸0時為0,行駛時為1有效
  60. static ds_bf=10; //轉(zhuǎn)把上次的數(shù)據(jù)備份
  61. static zs_js; //轉(zhuǎn)速數(shù)據(jù)
  62. static zs_ds_js;
  63. int qy_1,qy_2,qy_3; //欠壓測量暫存區(qū)1,2,3
  64. int cs1,cs2,cs3,cs_fx; //電機測速全局變量
  65. static qy_bf; //欠壓上次的數(shù)據(jù)備份
  66. int h; //abs剎車用變量
  67. int dz;
  68. int dz2;
  69. void zb_fx(void);
  70. void he_gzjc(void);
  71. void pwm_out(void);
  72. //*********************ad轉(zhuǎn)換后pwm對照表*****************************************
  73. uchar code pwmout[256]=
  74. {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  75. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//60個1為1.3v以下
  76. //------------------------------------------------------------------------------------------
  77. 241,239,237,235,233,231,229,227,225,223,221,219,217,215,213,211,209,207,205,203,
  78. 201,199,197,195,193,191,189,187,185,183,181,179,177,175,173,171,169,167,165,163,
  79. 161,159,157,155,153,151,149,147,145,143,141,139,137,135,133,131,129,127,125,123,//60
  80. 121,119,117,115,113,111,109,107,105,103,101,99,97,95,93,91,89,87,85,83,81,79,77,//23
  81. 75,73,71,69,67,65,63,61,59,57,55,53,51,49,47,46,45,44,43,42,41,40,39,38,37,36,//26
  82. 35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,//26
  83. 9,8,7,6,5,4,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,//34 //25個0為4.1--4.5v
  84. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1}; //26個為4.5v以上
  85. //*********************1ms延時函數(shù)***********************************************
  86. void delay(int t)
  87. {
  88. int i,j;
  89. for(i=0;i<t;i++)
  90. for(j=0;j<250;j++)
  91. ;
  92. }
  93. //*********************abs剎車延時函數(shù)***********************************************
  94. void delay1(int t)
  95. {
  96. int i,j;
  97. for(i=0;i<t;i++)
  98. for(j=adc_data;j>0;j--)
  99. {}
  100. }
  101. //*********************設(shè)置ad電源和開漏函數(shù)**************************************
  102. adc_power()
  103. {
  104. adc_contr|=0x80; //開ad電源
  105. delay(2); //首次開ad電源要延時1ms左右
  106. p1m0|=0x88; //設(shè)置p1.3和p1.7為開漏即ad轉(zhuǎn)換模式
  107. p1m1|=0x88; //同上
  108. }
  109. //-------------------設(shè)置p1.3為轉(zhuǎn)把測量通道函------------------------------------
  110. set_p13_adc()
  111. { zb=1;
  112. adc_contr=0xe3; //p13口為轉(zhuǎn)換通道
  113. }
  114. //-------------------設(shè)置p17為電機超載測量通道函數(shù)--------------------------------
  115. set_p17_adc()
  116. {
  117. adc_contr=0xe7;
  118. }
  119. //------------------設(shè)置p15為欠壓檢測測量通道-------------------------------------
  120. set_p15_adc()
  121. {adc_contr=0xe5;}
  122. //===================測量電壓函數(shù)=================================================
  123. get_ad_dy()
  124. { int adon=0; //定義一個整型變量用于檢測ad轉(zhuǎn)換是否結(jié)束
  125. adc_data=0; //ad轉(zhuǎn)換結(jié)果寄存器清0
  126. adc_contr|=0x08; //轉(zhuǎn)換位置1啟動轉(zhuǎn)換
  127. while(adon==0) //循環(huán)判斷表達式成立反復執(zhí)行語句,不成立退出
  128. {adon=adc_contr&amt;0x10;} //循環(huán)語句體,即判斷ad轉(zhuǎn)換是否完成,完成后高第4位為1
  129. adc_contr&amt;=0xe7; //循環(huán)語句退出轉(zhuǎn)換完成,清adc_flag,adc_start,停止轉(zhuǎn)換
  130. }
  131. //********************pwm初始化函數(shù)***********************************************
  132. pwm_sz()
  133. {
  134. cmod=0x82; //pca在空閑模式下停止pca計數(shù)器工作
  135. //pca時鐘源為1/2溢出
  136. //禁止pca計數(shù)器溢出中斷
  137. ccon=0x00; //禁止pca計數(shù)器工作,清除中斷標志和計數(shù)器溢出標志
  138. cl=0x00; //清0計數(shù)器
  139. ch=0x00;
  140. //======================以下為4路pwm輸出設(shè)置程序=============================
  141. //設(shè)置模塊0為8位pwm輸出模式,pwm無需中斷支持,,脈沖在p3.7口輸出
  142. ccapm0=0x42; //***程序核心語句,-----0100,0010
  143. pca_pwm0=0x03; //先關(guān)閉pwm-輸出為0,寫入0x00就可開pwm輸出
  144. //設(shè)置模塊1為8位pwm輸出模式,pwm無需中斷支持,,脈沖在p3.5口輸出
  145. ccapm1=0x42; //***程序核心語句,-----0100,0010
  146. pca_pwm1=0x03; //先關(guān)閉pwm-輸出為0,寫入0x00就可開pwm輸出
  147. //設(shè)置模塊2為8位pwm輸出模式,pwm無需中斷支持,,脈沖在p2.0口輸出
  148. ccapm2=0x42; //***程序核心語句,-----0100,0010
  149. pca_pwm2=0x03; //先關(guān)閉pwm-輸出為0,寫入0x00就可開pwm輸出
  150. //模塊3未用
  151. epca_lvd=1; //開pca中斷
  152. ea=1; //開總中斷
  153. cr=1; //開pca計數(shù)器打開
  154. }
  155. //********************快閃燈函數(shù)***********************************************
  156. led_k()
  157. { int k; //定義一個臨時變量
  158. for(k=0;k<ledcs;k++) //表達式2條件不滿足即次數(shù)未到重復執(zhí)行循環(huán)體語句
  159. {led=0;delay(700);
  160. led=1;delay(700);}
  161. delay(2000);
  162. }
  163. //********************定時器0和1初始化函數(shù)*******************************************
  164. time_csh()
  165. {
  166. tmod=0x11; //定時器0工作于8位自動重裝,1工作于方式1
  167. th0=0x3c; //
  168. tl0=0x0b;
  169. th1=0x3c; //12mhz時50ms數(shù)據(jù),20次為1s
  170. tl1=0x0b;
  171. it0=1; //設(shè)置外中斷0為下降沿觸發(fā)358第一腳
  172. ex0=1; //開外中斷0
  173. ea=1; //開總中斷
  174. et0=1; //開定時期0中斷
  175. et1=1; //開定時期1中斷
  176. }
  177. //********************定時器0中斷函數(shù)pwm頻率用************************************
  178. void time0(void)interrupt 1
  179. {tr0=0;th0=0x3c;tl0=0x0b;
  180. zs_ds_js++;
  181. if(zs_ds_js==10)
  182. {if(zs_js<10)
  183. {dz_bz1=1;zs_ds_js=0;zs_js=0;
  184. th1=0x3c;tl1=0x0b;tr1=1;
  185. th0=0x3c;tl0=0x0b;tr0=1;
  186. // pwm_bls=200;
  187. }
  188. else
  189. {dz_bz1=0;zs_ds_js=0;zs_js=0;zs_bl=zs_js;
  190. th1=0x3c;tl1=0x0b;tr1=0;
  191. th0=0x3c;tl0=0x0b;tr0=1;
  192. }
  193. }
  194. else
  195. {tr0=1;}
  196. }
  197. //********************定時器1中斷函數(shù)*********************************************
  198. void time1(void)interrupt 3
  199. { tr1=0;th1=0x3c;tl1=0x0b;
  200. timejs++;
  201. if(timejs==12) //中斷次數(shù)等于給定的次數(shù)就取反led
  202. {if(zbyx_bz==0) //轉(zhuǎn)把歸0標志為0,可以閃燈
  203. {led=~led;timejs=0;tr1=1;}
  204. }
  205. if(timejs==80)
  206. {if(dz_bz1==1)
  207. {tr0=0;dz_bz1=0;dz_bz=1;zs_ds_js=0;zs_js=0;timejs=0;}
  208. else
  209. {dz_bz=0;zs_ds_js=0;zs_js=0;timejs=0;}
  210. }
  211. tr1=1;
  212. }
  213. //*******************電機堵轉(zhuǎn)轉(zhuǎn)函數(shù)***********************************************
  214. //根據(jù)2s定時內(nèi)一直堵轉(zhuǎn)的話置dz_bz為1,本函數(shù)檢測到該標志為1立即關(guān)閉所有輸出
  215. //并閃爍指示燈間隔快閃2次提示,最后監(jiān)控轉(zhuǎn)把歸0后可以退出本函數(shù)重新啟動
  216. void dgdz(void)
  217. {
  218. while(dz_bz1==1)
  219. {pwm_bls=100;he_gzjc();pwm_out();
  220. if(dz_bz==1)
  221. { tr0=0;tr1=0;
  222. pca_pwm0=0x03; //關(guān)3路pwm信號
  223. pca_pwm1=0x03; //
  224. pca_pwm2=0x03; //
  225. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)3路下橋
  226. set_p13_adc(); //電機進入保護后開始等待轉(zhuǎn)把歸零后可以重新啟動
  227. do{ledcs=2;led_k();get_ad_dy();} //間隔開閃2次提示堵轉(zhuǎn)保護,測量轉(zhuǎn)把電壓是否歸0
  228. while(adc_data>=61); //沒有歸0執(zhí)行do循環(huán)體語句
  229. led=1;dz_bz=0;dz_bz1=0; //轉(zhuǎn)把歸0后關(guān)指示燈清堵轉(zhuǎn)標志
  230. }
  231. }
  232. }
  233. //********************外中斷0函數(shù)限流或康銅開路************************************
  234. void intt0()interrupt 0
  235. {
  236. tr0=0;tr1=0; //關(guān)pwm頻率
  237. pca_pwm0=0x03; //關(guān)3路pwm信號
  238. pca_pwm1=0x03; //
  239. pca_pwm2=0x03; //
  240. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)3路下橋
  241. set_p13_adc();
  242. get_ad_dy();
  243. while(adc_data>=61)
  244. {ledcs=4;led=0;get_ad_dy();}
  245. led=1;
  246. }
  247. //********************pwm驅(qū)動橋驅(qū)動輸出函數(shù)****************************************
  248. void pwm_out(void) //入口:pwm_bl里有轉(zhuǎn)把調(diào)速參數(shù).出口:輸出全橋驅(qū)動信號
  249. {
  250. switch(hehc) //多分支語句根據(jù)霍爾位置輸出對應(yīng)節(jié)拍
  251. {case 0x01:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0;
  252. ccap0h=pwm_bls;pwmcl=1;pca_pwm0=0x00;cs1=0x01;break;} //第1拍ccap0h刷新參數(shù)開c下橋a上橋
  253. //-------------------------------------------------------------
  254. case 0x03:{pca_pwm0=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0;
  255. ccap1h=pwm_bls;pwmcl=1;pca_pwm1=0x00;cs2=0x03;break;} //第2拍ccap1h刷新參數(shù)開c下橋b上橋
  256. //-------------------------------------------------------------
  257. case 0x02:{pca_pwm0=0x03;pca_pwm2=0x03;pwmbl=0;pwmcl=0;
  258. ccap1h=pwm_bls;pwmal=1;pca_pwm1=0x00;cs3=0x02;break;} //第3拍ccap1h刷新參數(shù)開a下橋b上橋
  259. //-------------------------------------------------------------
  260. case 0x06:{pca_pwm0=0x03;pca_pwm1=0x03;pwmbl=0;pwmcl=0;
  261. ccap2h=pwm_bls;pwmal=1;pca_pwm2=0x00;cs1=0x06;break;} //第4拍ccap2h刷新參數(shù)開a下橋c上橋
  262. //-------------------------------------------------------------
  263. case 0x04:{pca_pwm0=0x03;pca_pwm1=0x03;pwmal=0;pwmcl=0;
  264. ccap2h=pwm_bls;pwmbl=1;pca_pwm2=0x00;cs2=0x04;break;} //第5拍ccap2h刷新參數(shù)開b下橋c上橋
  265. //-------------------------------------------------------------
  266. case 0x05:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmcl=0;
  267. ccap0h=pwm_bls;pwmbl=1;pca_pwm0=0x00;cs3=0x05;break;} //第6拍ccap0h刷新參數(shù)開b下橋a上橋
  268. }
  269. }
  270. //********************上電初始化函數(shù)**********************************************
  271. void sd_csh(void)
  272. {p1=0xff;zb=0;p2=0xff;p3=0xff;
  273. pwmal=0; //上電復位后首先關(guān)閉3組下橋
  274. pwmbl=0; //
  275. pwmcl=0; //
  276. adc_power(); //調(diào)ad轉(zhuǎn)換用初始化函數(shù)
  277. pwm_sz(); //調(diào)pwm輸出用初始化函數(shù)
  278. time_csh(); //調(diào)兩個定時器初始化函數(shù)
  279. }
  280. //********************上電防飛車函數(shù)歸0后led正常閃爍******************************
  281. void sd_ffc(void)
  282. {
  283. set_p13_adc(); //調(diào)轉(zhuǎn)把電壓轉(zhuǎn)換通道
  284. get_ad_dy(); //上電后測量轉(zhuǎn)把電壓是否歸零
  285. while(adc_data>=61) //61為1.2v轉(zhuǎn)換值轉(zhuǎn)把如果大于1.2v執(zhí)行循環(huán)體語句等待歸0
  286. {ledcs=2;led_k(); //循環(huán)體語句,2次間隔性快閃燈
  287. get_ad_dy(); //循環(huán)體語句,重新檢測電壓等待歸0
  288. }
  289. tr0=0; //關(guān)pwm頻率否則干擾閃燈
  290. timebj=12; //歸0后定時器中斷10次閃爍一次led
  291. tr1=1; //歸0后開定時器1-led閃爍
  292. }
  293. //*************剎車函數(shù)自動選擇是斷電還是abs剎車功***************************
  294. void sc_stop(void) //abs剎車有外接口對地選擇,對地時為abs功能
  295. {
  296. if(shache==0) //判斷語句剎車口等于0執(zhí)行大語句1
  297. { abs=1;
  298. //大語句體1
  299. if(abs==1) //判斷abs選擇不為0就執(zhí)行普通剎車斷電,否則執(zhí)行abs剎車
  300. //==========普通剎車斷電==================================================
  301. {
  302. tr0=0;led=0; //關(guān)測速定時器,亮剎車燈
  303. pca_pwm0=0x03; //關(guān)3路pwm信號ah
  304. pca_pwm1=0x03; //關(guān)3路pwm信號bh
  305. pca_pwm2=0x03; //關(guān)3路pwm信號ch
  306. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)3路下橋
  307. //----------------------------------------------------------------------
  308. while(shache==0) //循環(huán)語句,剎車口沒松開就一直等待
  309. {delay(500);} //語句體,延時抗干擾防止抖動
  310. hehc_bl=0;led=1; //剎車口松開后清霍爾變量內(nèi)存再關(guān)剎車燈
  311. //----------------------------------------------------------------------
  312. for(pwm_bls=241;pwm_bl!=pwm_bls;pwm_bls--) //以下兩句為剎車口松開后減緩沖擊
  313. {he_gzjc();pwm_out();} //從最低速度加高到實時的轉(zhuǎn)把設(shè)定速度
  314. }
  315. //===========eabs剎車斷電=====================================================
  316. else //abs功能已選擇進入abs剎車
  317. { //
  318. tr0=0;led=0; //關(guān)測速定時器,亮剎車燈
  319. pca_pwm0=0x03; //關(guān)3路pwm信號ah
  320. pca_pwm1=0x03; //關(guān)3路pwm信號bh
  321. pca_pwm2=0x03; //關(guān)3路pwm信號ch
  322. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)閉3個下橋:al-bl-cl
  323. //-------------------------------------------------------------------------
  324. do //do-while語句先執(zhí)行do再執(zhí)行while判斷表達式
  325. {
  326. for(h=100;h>0;h--) //每檢測一次沒松開就先執(zhí)行1萬次abs點剎,防止剎車抖動干擾
  327. { pwmal=0;pwmbl=0;pwmcl=0;
  328. delay1(1);
  329. pwmal=1;pwmbl=1;pwmcl=1; //abs點剎
  330. delay1(80);
  331. }
  332. }
  333. while(shache==0); //內(nèi)鑲循環(huán)語句,只要剎車沒松開就一直開abs點剎制動
  334. hehc_bl=0;led=1; //剎車口為1后清霍爾變量內(nèi)存再關(guān)剎車燈
  335. pwmal=0;pwmbl=0;pwmcl=0; //點剎后要關(guān)閉所有下橋防止剎車松開后車推不動
  336. for(pwm_bls=241;pwm_bl!=pwm_bls;pwm_bls--)//以下幾句剎車后軟啟動,減少剎車后高速沖擊
  337. {he_gzjc();pwm_out();}
  338. }
  339. //---------------
  340. }
  341. }
  342. //*******************欠壓檢測函數(shù)**************************************************
  343. void qy_jc(void)
  344. { //連續(xù)3次測量電池電壓抗干擾
  345. set_p15_adc();
  346. get_ad_dy(); //第1次測量電池電壓
  347. qy_1=adc_data; //保存第1次測量數(shù)據(jù)
  348. get_ad_dy(); //第2次測量電池電壓
  349. qy_2=adc_data; //保存第2次測量數(shù)據(jù)
  350. get_ad_dy(); //第3次測量電池電壓
  351. qy_3=adc_data; //保存第3次測量數(shù)據(jù)
  352. //比較取舍法,只有其中兩次相同才有效
  353. if(qy_1==qy_2) //比較第1次和第2次結(jié)果是否相同,否轉(zhuǎn)下一輪判斷
  354. {qy_bf=qy_1;adc_data=qy_1;} //相同的話本次測量有效有效,保存本次數(shù)據(jù)備份后直接退出if語句
  355. else //第1次和第2次的結(jié)果不同,
  356. {if(qy_2==qy_3) //再判斷第2次和第3次的結(jié)果相同嗎,否轉(zhuǎn)下一輪判斷
  357. {qy_bf=qy_2;adc_data=qy_2;} //相同的話本次測量有效有效,保存本次數(shù)據(jù)備份后直接退出if語句
  358. else //第1次和第2次的結(jié)果不同,
  359. {if(qy_1==qy_3) //再判斷第1次和第3次的結(jié)果相同嗎,3次都不同的話取舊備份數(shù)據(jù)
  360. {qy_bf=qy_3;adc_data=qy_3;}////相同的話本次測量有效有效,保存本次數(shù)據(jù)備份后直接退出if語句
  361. else //3次都不同取舊備份數(shù)據(jù)
  362. {adc_data=qy_bf;}
  363. }
  364. }
  365. if(adc_data<=158) //電壓小于等于3.1v嗎,不等于直接退出
  366. {tr0=0;tr1=0;led=1; //小于等于,電池電壓過低,關(guān)pwm頻率保護電池
  367. pca_pwm0=0x03; //關(guān)3路pwm信號
  368. pca_pwm1=0x03; //
  369. pca_pwm2=0x03; //
  370. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)3路下橋
  371. do{ledcs=3;led_k();get_ad_dy();} //閃燈提示重新測量電壓
  372. while(adc_data<=175); //檢測是否恢復到正常電壓44v
  373. ledcs=3;led_k(); //電壓恢復44v以上再閃燈做為延時用
  374. hehc_bl=0; //清霍爾舊數(shù)據(jù)為了起動
  375. }
  376. }
  377. //*******************霍爾故障檢測函數(shù)**********************************************
  378. void he_gzjc(void)
  379. {
  380. hehc=p1&amt;0x07; //讀入霍爾數(shù)據(jù),并分離有效數(shù)據(jù)
  381. //--查霍爾是否全1--------
  382. while(hehc==0x07) //判斷是否為3個全1,成立循環(huán)執(zhí)行語句體
  383. {pca_pwm0=0x03; //霍爾出現(xiàn)故障關(guān)閉所有輸出
  384. pca_pwm1=0x03; //
  385. pca_pwm2=0x03; //
  386. pwmal=0;pwmbl=0;pwmcl=0; //
  387. tr0=0;zs_ds_js=0;zs_js=0; //關(guān)測速定時器,定時計數(shù)器清0,轉(zhuǎn)速度計數(shù)器清0
  388. ledcs=6;led_k(); //循環(huán)執(zhí)行語句體6次閃爍,直到不成立退出
  389. hehc=p1&amt;0x07; //重新檢測霍爾
  390. }
  391. //--查霍爾是否全0--------
  392. while(hehc==0x00) //不為3個1再判斷是否為3個0,成立執(zhí)行循環(huán)語句體
  393. {pca_pwm0=0x03; //霍爾出現(xiàn)故障關(guān)閉所有輸出
  394. pca_pwm1=0x03; //
  395. pca_pwm2=0x03; //
  396. pwmal=0;pwmbl=0;pwmcl=0; //
  397. tr0=0;zs_ds_js=0;zs_js=0; //關(guān)測速定時器,定時計數(shù)器清0,轉(zhuǎn)速度計數(shù)器清0
  398. ledcs=6;led_k(); //循環(huán)執(zhí)行語句體6次閃爍,直到不成立退出
  399. hehc=p1&amt;0x07; //重新檢測霍爾
  400. }
  401. //--查霍爾是否更新--------
  402. if(hehc_bl!=hehc) //判斷霍爾是否變化,成立執(zhí)行語句1后退出
  403. {hehc_bl=hehc; } //語句2,霍爾變化存入新的數(shù)據(jù)到變量中
  404. }
  405. //**********電流自動調(diào)整函數(shù)******************************************************
  406. void dl_tz(void)
  407. {set_p17_adc();
  408. get_ad_dy();
  409. while(adc_data>=20)
  410. {pwm_bls++;if(pwm_bls>=241){pwm_bls=241;}
  411. he_gzjc();pwm_out();dgdz();
  412. }
  413. // if(adc_data>=45)
  414. // {pwm_bls=240;//adc_data*10+pwm_bl;
  415. // }
  416. // else
  417. //{pwm_bls=pwm_bl;}
  418. }
  419. //********************轉(zhuǎn)把工作狀態(tài)分析函數(shù)****************************************
  420. //函數(shù)出口--pwm_bl里有查表后數(shù)據(jù),pwm輸出程序直接讀出放入pwm占空比寄存器
  421. //ccap0h,ccap1h,ccap2h中即可
  422. //********************************************************************************
  423. void zb_fx(void)
  424. { //---連續(xù)3次測量轉(zhuǎn)把電壓--------
  425. set_p13_adc(); //調(diào)轉(zhuǎn)把電壓轉(zhuǎn)換通道
  426. get_ad_dy(); //第一次測量轉(zhuǎn)把電壓
  427. pwm_bl=pwmout[adc_data]; //在數(shù)組中查出對應(yīng)的ad轉(zhuǎn)換pwm值
  428. if(pwm_bl==1) //為1成立執(zhí)行大的語句1后退出,不成立執(zhí)行語句2后退出
  429. //語句1,轉(zhuǎn)把電壓等于1說明轉(zhuǎn)把在1.3v以下或4.5v以上停止輸出閃led
  430. {
  431. hehc_bl=0; //霍爾存儲舊數(shù)據(jù)的變量及時清0否則很難起動
  432. pca_pwm0=0x03; //停止所有輸出
  433. pca_pwm1=0x03;
  434. pca_pwm2=0x03;
  435. tr0=0;zs_ds_js=0;zs_js=0; //關(guān)測速定時器,定時計數(shù)器清0,轉(zhuǎn)速度計數(shù)器清0
  436. pwmal=0;pwmbl=0;pwmcl=0; //關(guān)3個下橋
  437. timebj=15; //定時器1中斷12次閃爍一次led
  438. tr1=1;zbyx_bz=0; //開定時器1-led閃爍,轉(zhuǎn)把歸0標志位為0,pwm輸出就無效
  439. }
  440. else
  441. //語句2,轉(zhuǎn)把電壓不等于1說明在1.3v-4.5v之間正常行駛數(shù)據(jù)
  442. {led=1;zbyx_bz=1;tr0=1;} //關(guān)定時器1指示燈,轉(zhuǎn)把有效標志位為1,pwm輸出有效
  443. }
  444. //**********************軟啟動************************************
  445. //dg_rqd()
  446. //{dgdz();
  447. //if(pwm_bl!=pwm_blj)
  448. // {for(pwm_bls=241;pwm_bl!=pwm_bls;pwm_bls--)
  449. // {he_gzjc();pwm_out();}pwm_blj=pwm_bl;
  450. // }
  451. //else
  452. // {if(shache_bz==1)
  453. // {for(pwm_bls=241;pwm_bl!=pwm_bls;pwm_bls--)
  454. // {he_gzjc();pwm_out();}pwm_blj=pwm_bl;shache_bz=0;
  455. // }
  456. // else
  457. // {he_gzjc();pwm_out();}
  458. // }
  459. //}
  460. //********************防盜鎖電機函數(shù)**********************************************
  461. fd_dg()
  462. {while(fd==0)
  463. {
  464. {int fd_he;
  465. fd_he=p1&amt;0x07;
  466. if(fd_he!=fd_hej)
  467. {fd_hej=fd_he;
  468. //switch(fd_he) //多分支語句根據(jù)霍爾位置輸出對應(yīng)節(jié)拍
  469. // {case 0x01:{
  470. pca_pwm0=0x03;pca_pwm2=0x03;pwmbl=0;pwmcl=0;
  471. ccap1h=10;pwmal=1;pca_pwm1=0x00;delay(20);
  472. pwmal=0;pca_pwm1=0x03;
  473. pwmal=1;pwmbl=1;pwmcl=1;delay(300);
  474. //-------
  475. //pwmcl=1;pca_pwm0=0x00;delay(1);
  476. // pwmcl=0;pca_pwm0=0x03;delay(2);
  477. // break;} //第1拍ccap0h刷新參數(shù)開c下橋a上橋
  478. //-------------------------------------------------------------
  479. // case 0x03:{pca_pwm0=0x03;pca_pwm1=0x03;pwmbl=0;pwmcl=0;
  480. // ccap2h=10;pwmal=1;pca_pwm2=0x00;delay(20);
  481. // pwmal=0;pca_pwm2=0x03;
  482. // pwmal=1;pwmbl=1;pwmcl=1;delay(200);
  483. //--------
  484. // pwmcl=1;pca_pwm1=0x00;delay(1);
  485. // pwmcl=0;pca_pwm1=0x03;delay(2);
  486. // break;} //第2拍ccap1h刷新參數(shù)開c下橋b上橋
  487. //-------------------------------------------------------------
  488. // case 0x02:{pca_pwm0=0x03;pca_pwm1=0x03;pwmal=0;pwmcl=0;
  489. // ccap2h=10;pwmbl=1;pca_pwm2=0x00;delay(20);
  490. // pwmbl=0;pca_pwm2=0x03;
  491. // pwmal=1;pwmbl=1;pwmcl=1;delay(200);
  492. // //--------
  493. //pwmal=1;pca_pwm1=0x00;delay(1);
  494. // //pwmal=0;pca_pwm1=0x03;delay(2);
  495. // break;} //第3拍ccap1h刷新參數(shù)開a下橋b上橋
  496. //-------------------------------------------------------------
  497. // case 0x06:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmcl=0;
  498. // ccap0h=10;pwmbl=1;pca_pwm0=0x00;delay(20);
  499. // pwmbl=0;pca_pwm0=0x03;
  500. // pwmal=1;pwmbl=1;pwmcl=1;delay(200);
  501. //---------
  502. //pwmal=1;pca_pwm2=0x00;delay(1);
  503. //pwmal=0;pca_pwm2=0x03;delay(2);
  504. // break;} //第4拍ccap2h刷新參數(shù)開a下橋c上橋
  505. //-------------------------------------------------------------
  506. // case 0x04:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0;
  507. // ccap0h=10;pwmcl=1;pca_pwm0=0x00;delay(20);
  508. // pwmcl=0;pca_pwm0=0x03;
  509. // pwmal=1;pwmbl=1;pwmcl=1;delay(200);
  510. // //---------
  511. //pwmbl=1;pca_pwm2=0x00;delay(1);
  512. //pwmbl=0;pca_pwm2=0x03;delay(2);
  513. // break;} //第5拍ccap2h刷新參數(shù)開b下橋c上橋
  514. //-------------------------------------------------------------
  515. // case 0x05:{pca_pwm0=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0;
  516. // ccap1h=10;pwmcl=1;pca_pwm1=0x00;delay(20);
  517. // pwmcl=0;pca_pwm1=0x03;
  518. // pwmal=1;pwmbl=1;pwmcl=1;delay(200);
  519. //----------
  520. // pwmbl=1;pca_pwm0=0x00;delay(1);
  521. // // pwmbl=0;pca_pwm0=0x03;delay(2);
  522. // break;} //第6拍ccap0h刷新參數(shù)開b下橋a上橋
  523. // }
  524. }
  525. }
  526. }
  527. }
  528. //********************主函數(shù)******************************************************
  529. main()
  530. {
  531. sd_csh(); //調(diào)上電初始化函數(shù)
  532. qy_jc(); //調(diào)欠壓檢測函數(shù)
  533. sd_ffc(); //調(diào)上電防飛車函數(shù),等待歸0后才往下執(zhí)行
  534. he_gzjc(); //調(diào)霍爾故障檢測函數(shù),無故障才往下執(zhí)行
  535. while(1)
  536. {
  537. qy_jc();
  538. if(fd==0){fd_hej=p1&amt;0x07;fd_dg();}//如果防盜口為低電平執(zhí)行防盜程序
  539. //--------------
  540. else //否則執(zhí)行正常程序
  541. {
  542. if(dz_bz1!=1){zb_fx();} //1>調(diào)轉(zhuǎn)把分析函數(shù)
  543. if(zbyx_bz==1) //如果轉(zhuǎn)把標志位為1轉(zhuǎn)把有效,就執(zhí)行語句體否則不執(zhí)行
  544. {dl_tz();dgdz();
  545. he_gzjc();pwm_out();
  546. cs_fx=cs1&amt;cs2&amt;cs3;
  547. if(cs_fx!=0x00)
  548. {zs_js++;}
  549. } //語句體,調(diào)霍爾分析函數(shù),調(diào)pwm輸出函數(shù)
  550. sc_stop(); //調(diào)剎車斷電檢測函數(shù)
  551. }
  552. //-----------------------
  553. }
  554. }
  555. //********************************************************************************
復制代碼

以上代碼打包(方便保存): 帶霍爾傳感器的無刷電機控制程序(PWM調(diào)速) 基于單片機編寫的C程序.rar (5.82 KB, 下載次數(shù): 116)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:328014 發(fā)表于 2020-10-15 22:51 | 只看該作者
樓主能分享下線路圖嗎?
回復

使用道具 舉報

板凳
ID:56665 發(fā)表于 2020-10-16 09:56 | 只看該作者
有程序沒有原理圖不完整
回復

使用道具 舉報

地板
ID:510170 發(fā)表于 2021-3-20 11:01 | 只看該作者
樓主,你的上橋程序里面沒有寫接那個腳呀。
回復

使用道具 舉報

5#
ID:961449 發(fā)表于 2021-9-13 18:34 來自手機 | 只看該作者
ttmax3 發(fā)表于 2021-3-20 11:01
樓主,你的上橋程序里面沒有寫接那個腳呀。

研究出來了嗎。
回復

使用道具 舉報

6#
ID:961449 發(fā)表于 2021-9-15 03:33 來自手機 | 只看該作者
有原理圖嗎
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表