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

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

QQ登錄

只需一步,快速開始

搜索
查看: 7123|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

二輪平衡機(jī)器人控制器代碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:80436 發(fā)表于 2015-5-22 01:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式



  1. //MCU:Mega16;晶振:8MHz;

  2. //PWM:4KHz;濾波器頻率:100Hz;系統(tǒng)頻率:100Hz;10ms;

  3. //二輪平衡機(jī)器人項(xiàng)目

  4. #include <iom16v.h>

  5. #include <macros.h>

  6. #include <math.h>

  7. //#define checkbit(var,bit)     (var&(0x01<<(bit)))     /*定義查詢位函數(shù)*/

  8. //#define setbit(var,bit)     (var|=(0x01<<(bit)))     /*定義置位函數(shù)*/

  9. //#define clrbit(var,bit)     (var&=(~(0x01<<(bit)))) /*定義清零位函數(shù)*/

  10. //-------------------------------------------------------

  11. //輸出端口初始化

  12. void PORT_initial(void)

  13. {

  14. DDRA=0B00000000;

  15. PINA=0X00;

  16. PORTA=0X00;

  17. DDRB=0B00000000;

  18. PINB=0X00;

  19. PORTB=0X00;

  20. DDRC=0B00010000;

  21. PINC=0X00;

  22. PORTC=0X00;

  23. DDRD=0B11110010;

  24. PIND=0X00;

  25. PORTD=0X00;

  26. }

  27. //-------------------------------------------------------

  28. //定時(shí)器1初始化

  29. void T1_initial(void)       

  30. {

  31. TCCR1A|=(1<<COM1A1)|(1<<WGM10)|(1<<COM1B1);        //T1:8位快速PWM模式、匹配時(shí)清0,TOP時(shí)置位

  32. TCCR1B|=(1<<WGM12)|(1<<CS11);        //PWM:8分頻:8M/8/256=4KHz;

  33. }

  34. //-------------------------------------------------------

  35. //定時(shí)器2初始化

  36. void T2_initial(void)        //T2:計(jì)數(shù)至OCR2時(shí)產(chǎn)生中斷

  37. {

  38. OCR2=0X4E;        //T2:計(jì)數(shù)20ms(0X9C)10ms(0X4E)時(shí)產(chǎn)生中斷;

  39. TIMSK|=(1<<OCIE2);

  40. TCCR2|=(1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20);        //CTC模式,1024分頻

  41. }

  42. //-------------------------------------------------------

  43. //外部中斷初始化

  44. void INT_initial(void)

  45. {

  46. MCUCR|=(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10);        //INT0、INT1上升沿有效

  47. GICR|=(1<<INT0)|(1<<INT1);        //外部中斷使能

  48. }

  49. //-------------------------------------------------------

  50. //串口初始化;

  51. void USART_initial( void )

  52. {       

  53. UBRRH = 0X00;

  54. UBRRL = 51;        //f=8MHz;設(shè)置波特率:9600:51;19200:25;

  55. UCSRB = (1<<RXEN)|(1<<TXEN);        //接收器與發(fā)送器使能;

  56. UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);        //設(shè)置幀格式: 8 個(gè)數(shù)據(jù)位, 1 個(gè)停止位;

  57. UCSRB|=(1<<RXCIE);        //USART接收中斷使能

  58. }

  59. //-------------------------------------------------------

  60. //串口發(fā)送數(shù)據(jù);

  61. void USART_Transmit( unsigned char data )

  62. {

  63. while ( !( UCSRA & (1<<UDRE)));        //等待發(fā)送緩沖器為空;

  64. UDR = data;        //將數(shù)據(jù)放入緩沖器,發(fā)送數(shù)據(jù);

  65. }

  66. //-------------------------------------------------------

  67. //串口接收數(shù)據(jù)中斷,確定數(shù)據(jù)輸出的狀態(tài);

  68. #pragma interrupt_handler USART_Receive_Int:12

  69. static char USART_State;

  70. void USART_Receive_Int(void)

  71. {

  72. USART_State=UDR;//USART_Receive();

  73. }

  74. //-------------------------------------------------------

  75. //計(jì)算LH側(cè)輪速:INT0中斷;

  76. //-------------------------------------------------------

  77. static int speed_real_LH;

  78. //-------------------------------------------------------

  79. #pragma interrupt_handler SPEEDLHINT_fun:2

  80. void SPEEDLHINT_fun(void)

  81. {

  82. if (0==(PINB&BIT(0)))

  83. {

  84. speed_real_LH-=1;

  85. }

  86. else

  87. {

  88. speed_real_LH+=1;

  89. }

  90. }

  91. //-------------------------------------------------------

  92. //計(jì)算RH側(cè)輪速,:INT1中斷;

  93. //同時(shí)將輪速信號(hào)統(tǒng)一成前進(jìn)方向了;

  94. //-------------------------------------------------------

  95. static int speed_real_RH;

  96. //-------------------------------------------------------

  97. #pragma interrupt_handler SPEEDRHINT_fun:3

  98. void SPEEDRHINT_fun(void)

  99. {

  100. if (0==(PINB&BIT(1)))

  101. {

  102. speed_real_RH+=1;

  103. }

  104. else

  105. {

  106. speed_real_RH-=1;

  107. }

  108. }

  109. //-------------------------------------------------------

  110. //ADport采樣:10位,采樣基準(zhǔn)電壓Aref

  111. //-------------------------------------------------------

  112. static int AD_data;

  113. //-------------------------------------------------------

  114. int ADport(unsigned char port)

  115. {

  116. ADMUX=port;

  117. ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADPS1)|(1<<ADPS0);        //采樣頻率為8分頻;

  118. while(!(ADCSRA&(BIT(ADIF))));

  119. AD_data=ADCL;

  120. AD_data+=ADCH*256;

  121. AD_data-=512;

  122. return (AD_data);

  123. }

  124. //*

  125. //-------------------------------------------------------

  126. //Kalman濾波,8MHz的處理時(shí)間約1.8ms;

  127. //-------------------------------------------------------

  128. static float angle, angle_dot; //外部需要引用的變量

  129. //-------------------------------------------------------

  130. static const float Q_angle=0.001, Q_gyro=0.003, R_angle=0.5, dt=0.01;

  131. //注意:dt的取值為kalman濾波器采樣時(shí)間;

  132. static float P[2][2] = {

  133. { 1, 0 },

  134. { 0, 1 }

  135. };

  136. static float Pdot[4] ={0,0,0,0};

  137. static const char C_0 = 1;

  138. static float q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;

  139. //-------------------------------------------------------

  140. void Kalman_Filter(float angle_m,float gyro_m)        //gyro_m:gyro_measure

  141. {

  142. angle+=(gyro_m-q_bias) * dt;

  143. Pdot[0]=Q_angle - P[0][1] - P[1][0];

  144. Pdot[1]=- P[1][1];

  145. Pdot[2]=- P[1][1];

  146. Pdot[3]=Q_gyro;

  147. P[0][0] += Pdot[0] * dt;

  148. P[0][1] += Pdot[1] * dt;

  149. P[1][0] += Pdot[2] * dt;

  150. P[1][1] += Pdot[3] * dt;

  151. angle_err = angle_m - angle;

  152. PCt_0 = C_0 * P[0][0];

  153. PCt_1 = C_0 * P[1][0];

  154. E = R_angle + C_0 * PCt_0;

  155. K_0 = PCt_0 / E;

  156. K_1 = PCt_1 / E;

  157. t_0 = PCt_0;

  158. t_1 = C_0 * P[0][1];

  159. P[0][0] -= K_0 * t_0;

  160. P[0][1] -= K_0 * t_1;

  161. P[1][0] -= K_1 * t_0;

  162. P[1][1] -= K_1 * t_1;

  163. angle        += K_0 * angle_err;

  164. q_bias        += K_1 * angle_err;

  165. angle_dot = gyro_m-q_bias;

  166. }

  167. //*/

  168. /*

  169. //-------------------------------------------------------

  170. //互補(bǔ)濾波

  171. //-------------------------------------------------------

  172. static float angle,angle_dot; //外部需要引用的變量

  173. //-------------------------------------------------------       

  174. static float bias_cf;

  175. static const float dt=0.01;

  176. //-------------------------------------------------------

  177. void complement_filter(float angle_m_cf,float gyro_m_cf)

  178. {

  179. bias_cf*=0.998;        //陀螺儀零飄低通濾波;500次均值;

  180. bias_cf+=gyro_m_cf*0.002;

  181. angle_dot=gyro_m_cf-bias_cf;

  182. angle=(angle+angle_dot*dt)*0.90+angle_m_cf*0.05;       

  183. //加速度低通濾波;20次均值;按100次每秒計(jì)算,低通5Hz;

  184. }

  185. */       

  186. //-------------------------------------------------------

  187. //AD采樣;

  188. //以角度表示;

  189. //加速度計(jì):1.2V=1g=90°;滿量程:1.3V~3.7V;

  190. //陀螺儀:0.5V~4.5V=-80°~+80°;滿量程5V=200°=256=200°;

  191. //-------------------------------------------------------

  192. static float gyro,acceler;

  193. //-------------------------------------------------------

  194. void AD_calculate(void)

  195. {

  196. acceler=ADport(2)+28;        //角度校正

  197. gyro=ADport(3);       

  198. acceler*=0.004069;        //系數(shù)換算:2.5/(1.2*512); // 5/(1.2*1024);5為參考電壓5V;1.2V靈敏度對(duì)應(yīng)加速度1g;1024為AD精度

  199. acceler=asin(acceler);        //反正弦求角度

  200. gyro*=0.00341;        //角速度系數(shù):(3.14/180)* 100/512=0.01364;//(3.14/180)*    (200*0.025)/1024*0.025既5/1024*0.025       

  201. //求得角速度 單位 角度/秒

  202. Kalman_Filter(acceler,gyro);        //卡爾曼濾波 帶入角度。角速度

  203. //complement_filter(acceler,gyro);

  204. }

  205. //-------------------------------------------------------

  206. //PWM輸出

  207. //-------------------------------------------------------

  208. void PWM_output (int PWM_LH,int PWM_RH)

  209. {

  210. if (PWM_LH<0)

  211. {

  212. PORTD|=BIT(6);

  213. PWM_LH*=-1;

  214. }

  215. else

  216. {

  217. PORTD&=~BIT(6);

  218. }

  219. if (PWM_LH>252)

  220. {

  221. PWM_LH=252;

  222. }

  223. if (PWM_RH<0)

  224. {

  225. PORTD|=BIT(7);

  226. PWM_RH*=-1;

  227. }

  228. else

  229. {

  230. PORTD&=~BIT(7);

  231. }

  232. if (PWM_RH>252)

  233. {

  234. PWM_RH=252;

  235. }

  236. OCR1AH=0;

  237. OCR1AL=PWM_LH;        //OC1A輸出;

  238. OCR1BH=0;

  239. OCR1BL=PWM_RH;        //OC1B輸出;

  240. }

  241. //-------------------------------------------------------

  242. //計(jì)算PWM輸出值

  243. //車輛直徑:76mm; 12*64pulse/rev; 1m=3216pulses;

  244. //-------------------------------------------------------       

  245. //static int speed_diff,speed_diff_all,speed_diff_adjust;

  246. //static float K_speed_P,K_speed_I;

  247. static float K_voltage,K_angle,K_angle_dot,K_position,K_position_dot;

  248. static float K_angle_AD,K_angle_dot_AD,K_position_AD,K_position_dot_AD;

  249. static float position,position_dot;

  250. static float position_dot_filter;

  251. static float PWM;

  252. static int speed_output_LH,speed_output_RH;

  253. static int Turn_Need,Speed_Need;

  254. //-------------------------------------------------------       

  255. void PWM_calculate(void)       

  256. {

  257. if ( 0==(~PINA&BIT(1)) )        //左轉(zhuǎn)

  258. {

  259. Turn_Need=-40;

  260. }

  261. else if ( 0==(~PINB&BIT(2)) ) //右轉(zhuǎn)

  262. {

  263. Turn_Need=40;

  264. }

  265. else        //不轉(zhuǎn)

  266. {

  267. Turn_Need=0;

  268. }

  269. if ( 0==(~PINC&BIT(0)) )        //前進(jìn)

  270. {

  271. Speed_Need=-2;

  272. }

  273. else if ( 0==(~PINC&BIT(1)) )        //后退

  274. {

  275. Speed_Need=2;

  276. }

  277. else        //不動(dòng)

  278. {

  279. Speed_Need=0;

  280. }

  281. K_angle_AD=ADport(4)*0.007;

  282. K_angle_dot_AD=ADport(5)*0.007;

  283. K_position_AD=ADport(6)*0.007;

  284. K_position_dot_AD=ADport(7)*0.007;

  285. position_dot=PWM*0.04;

  286. position_dot_filter*=0.9;        //車輪速度濾波

  287. position_dot_filter+=position_dot*0.1;       

  288. position+=position_dot_filter;

  289. //position+=position_dot;       

  290. position+=Speed_Need;

  291. if (position<-768)        //防止位置誤差過大導(dǎo)致的不穩(wěn)定

  292. {

  293. position=-768;

  294. }

  295. else if  (position>768)

  296. {

  297. position=768;

  298. }

  299. PWM = K_angle*angle *K_angle_AD + K_angle_dot*angle_dot *K_angle_dot_AD +

  300. K_position*position *K_position_AD + K_position_dot*position_dot_filter *K_position_dot_AD;

  301. speed_output_RH = PWM;// - Turn_Need;

  302. speed_output_LH = - PWM;// - Turn_Need ;

  303. /*

  304. speed_diff=speed_real_RH-speed_real_LH;        //左右輪速差PI控制;

  305. speed_diff_all+=speed_diff;

  306. speed_diff_adjust=(K_speed_P*speed_diff+K_speed_I*speed_diff_all)/2;

  307. */

  308. PWM_output (speed_output_LH,speed_output_RH);       

  309. }

  310. //-------------------------------------------------------

  311. //定時(shí)器2中斷處理

  312. //-------------------------------------------------------

  313. static unsigned char temp;

  314. //-------------------------------------------------------

  315. #pragma interrupt_handler T2INT_fun:4

  316. void T2INT_fun(void)       

  317. {

  318. AD_calculate();

  319. PWM_calculate();

  320. if(temp>=4)        //10ms即中斷;每秒計(jì)算:100/4=25次;

  321. {       

  322. if (USART_State==0X30)        //ASCII碼:0X30代表字符'0'

  323. {

  324. USART_Transmit(angle*57.3+128);

  325. USART_Transmit(angle_dot*57.3+128);

  326. USART_Transmit(128);       

  327. }

  328. else if(USART_State==0X31)        //ASCII碼:0X30代表字符'1'

  329. {

  330. USART_Transmit(speed_output_LH+128);

  331. USART_Transmit(speed_output_RH+128);       

  332. USART_Transmit(128);

  333. }

  334. else if(USART_State==0X32)        //ASCII碼:0X30代表字符'2'

  335. {

  336. USART_Transmit(speed_real_LH+128);

  337. USART_Transmit(speed_real_RH+128);

  338. USART_Transmit(128);

  339. }

  340. else if(USART_State==0X33)        //ASCII碼:0X30代表字符'3'

  341. {

  342. USART_Transmit(K_angle+128);

  343. USART_Transmit(K_angle_dot+128);

  344. USART_Transmit(K_position_dot+128);

  345. }       

  346. temp=0;       

  347. }

  348. speed_real_LH=0;

  349. speed_real_RH=0;       

  350. temp+=1;       

  351. }

  352. //-------------------------------------------------------

  353. int i,j;

  354. //-------------------------------------------------------

  355. void main(void)

  356. {

  357. PORT_initial();

  358. T2_initial();

  359. INT_initial();

  360. USART_initial ();

  361. SEI();

  362. K_position=0.8 * 0.209;        //換算系數(shù):(256/10) * (2*pi/(64*12))=0.20944;//256/10:電壓換算至PWM,256對(duì)應(yīng)10V;

  363. K_angle=34 * 25.6;        //換算系數(shù):256/10 =25.6;

  364. K_position_dot=1.09 * 20.9;        //換算系數(shù):(256/10) * (25*2*pi/(64*12))=20.944;

  365. K_angle_dot=2.2 * 25.6;        //換算系數(shù):256/10 =25.6;

  366. for (i=1;i<=500;i++)        //延時(shí)啟動(dòng)PWM,等待卡爾曼濾波器穩(wěn)定

  367. {

  368. for (j=1;j<=300;j++);;

  369. }

  370. T1_initial();

  371. while(1)

  372. {

  373. ;

  374. }

  375. }
復(fù)制代碼





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

使用道具 舉報(bào)

沙發(fā)
ID:82588 發(fā)表于 2015-6-10 10:06 | 只看該作者
先收藏再說,謝謝分享
回復(fù)

使用道具 舉報(bào)

板凳
ID:82588 發(fā)表于 2015-6-14 11:25 | 只看該作者
先收藏備用,謝謝分享
回復(fù)

使用道具 舉報(bào)

地板
ID:65957 發(fā)表于 2017-4-13 13:11 | 只看該作者
好復(fù)雜,先備著。謝謝樓主
回復(fù)

使用道具 舉報(bào)

5#
ID:205843 發(fā)表于 2017-7-11 03:47 來自手機(jī) | 只看該作者
謝謝分享,很好的學(xué)習(xí)資料
回復(fù)

使用道具 舉報(bào)

6#
ID:48413 發(fā)表于 2017-8-16 10:33 | 只看該作者
學(xué)習(xí)一下謝謝!!!!!!!!!!!!!!!!!!!
回復(fù)

使用道具 舉報(bào)

7#
ID:962686 發(fā)表于 2022-3-23 23:12 | 只看該作者
感覺有點(diǎn)復(fù)雜啊,有點(diǎn)頭痛
回復(fù)

使用道具 舉報(bào)

8#
ID:1083996 發(fā)表于 2023-9-7 11:42 | 只看該作者
有沒有防止電動(dòng)車摩托車自行車這種,左右歪倒的東西,比如陀螺儀啥的;
網(wǎng)上貌似很多了,腳踢也不會(huì)傾倒
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩无| 日韩成人在线播放 | 青青久久 | 国产欧美综合在线 | 亚洲欧美一区二区三区国产精品 | 网站黄色在线免费观看 | 97超碰人人草 | 国产在线一区观看 | 国产精品视频在线观看 | 亚洲精品乱码久久久久久久久 | 欧美日韩精品免费观看 | 一级毛片网 | 视频在线一区 | 欧美精品欧美精品系列 | 99视频在线 | 欧日韩不卡在线视频 | 国产精品久久久久久久久久三级 | 美女亚洲一区 | 在线观看中文字幕一区二区 | 免费成人在线网站 | 日日操夜夜操天天操 | 国产一区999 | 欧美一级特黄aaa大片在线观看 | 国产一级片精品 | 91麻豆精品国产91久久久久久 | 欧美精产国品一二三区 | 人人干人人玩 | 午夜久久久 | 伊人久操| 欧美成人aaa级毛片在线视频 | 欧美一区二区久久 | 欧美视频一区二区三区 | 97av在线| 成人在线观看欧美 | 狠狠爱免费视频 | 国产亚洲精品综合一区 | 一级欧美一级日韩片 | 国产精品视频网址 | 日本电影韩国电影免费观看 | 亚洲国产精品久久久久久 | 欧美aⅴ |