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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

Atmega16+mpu6050平衡小車源碼 卡爾曼濾波

[復制鏈接]
跳轉到指定樓層
樓主
代碼測試通過,卡爾曼濾波
Anyway2.0_新驅動_客戶例程->default->Anyway_main.hex  此文件為燒寫代碼


單片機源程序如下:
  1. //方能儀器平衡車程序V2.0***************************
  2. //Landforcer 方能儀器版權所有
  3. /*使用到的單片機模塊有:
  4. 1、一路定時器中斷用于給定卡爾曼濾波周期,大約10ms
  5. 2、七路AD,其中ADC0用于檢測轉向電位器輸出(備用擴展,小車有接口),
  6. ADC1用于檢測左輪電機的電流(備用),
  7. ADC2連接外部滑動變阻器RK0,用于調整小車的平衡角度,也就是調零,ADC3連接
  8. RK1用于調節角度的比例系數,ADC4連接RK2用于調節角度的微分系數,ADC5連接
  9. RK3用于調節位置的比例系數,ADC6連接RK4用于調節位置的微分系數,ADC7用于檢測
  10. 右輪電機的電流(備用)
  11. 3、兩路外部中斷,用于檢測編碼器的輸出脈沖數,進而測得車速
  12. 4、兩路PWM輸出,PWM驅動直流伺服電機
  13. 5、一般IO口,通過發送高低電平控制電機的正反轉,
  14. 6、iic接口用于讀取MPU6050六軸傳感器的數據
  15. 使用到的外部硬件模塊有:MPU6050六軸傳感器
  16. 電機驅動模塊,車輪檢測編碼器模塊和主控板*/
  17. //*************************AnyWay調試說明**********************//
  18. /*RK0為小車的平衡角度調節,也就是零點調節,
  19.   RK1為角度比例系數,順時針變小,逆時針變大,系數越大車子越有力,但是系數太大會導致抖動造成自激,建議大小為2.0V
  20.   RK2為角度微分系數,順時針變小,逆時針變大,系數越大車子反應越靈敏,能一定程度上消除RK1導致的自激,但是不能太大,建議為3.6V
  21.   RK3為位置微分系數,順時針變小,逆7時針變大,系數越大車子越穩定,但是太大會導致自激,建議為0.6V
  22.   RK4為位置比例系數,順時針變小,逆時針變大,系數越大車子回到原點的速度越快,但是太大也會導致自激,建議為1.0V
  23. */
  24. #include<avr/io.h>
  25. #include<avr/interrupt.h>
  26. //#include<avr/signal.h>
  27. #include "Anyway_uart.h"
  28. #include "Anyway_Kalman.h"
  29. #include "Anyway_mup6050.h"
  30. #include"Anyway_twi.h"
  31. #include <math.h>
  32. #define uchar unsigned char
  33. #define uint unsigned int
  34. /////////////////變量定義區
  35. extern float angle, angle_dot;
  36. volatile unsigned int AD_data;
  37. volatile float PWM;
  38. volatile unsigned char flager,reger;
  39. volatile int speed_output_RH,speed_output_LH,NUMBER;
  40. volatile int speed_real_LH,speed_real_RH;
  41. volatile float gyro,acc,adc_v,angle_t;
  42. volatile int Kp_angle,Kd_angle,Kd_position;
  43. volatile float Kp_position;
  44. volatile float position,position_dot;
  45. volatile float position_dot_filter;
  46. volatile int Turn_Need,Speed_Need;
  47. unsigned char cdis[14]={0,}; //讀緩存區
  48. unsigned int aaa,ggg;
  49. #define xtal 16 //以MHz為單位,不同的系統時鐘要修改。

  50. void delay_1ms(void)
  51. {
  52. unsigned int i;
  53. for(i=0;i<(unsigned int)(xtal*143-2);i++);
  54. }

  55. void delay_nms(unsigned int num)
  56. {
  57. unsigned int i;
  58. for(i=0;i<num;i++)
  59. delay_1ms();
  60. }
  61. ///////////////////中斷初始化
  62. void T1_initial(void)                                       
  63. {
  64.         TCCR1A|=(1<<COM1A1)|(1<<WGM10)|(1<<COM1B1);                                //T1:8位快速PWM模式、匹配時清0,TOP時置位
  65.         TCCR1B|=(1<<WGM12)|(1<<CS11);                        //PWM:8分頻:16M/8/256=8KHz;
  66. }

  67. //-------------------------------------------------------
  68. //定時器2初始化
  69. void T2_initial(void)                        //T2:計數至OCR2時產生中斷
  70. {
  71.         OCR2=0x30;//0X5E;                        //T2:10ms時產生中斷;
  72.         TIMSK|=(1<<OCIE2);
  73.         TCCR2|=(1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20);                        //CTC模式,1024分頻
  74. }


  75. //-------------------------------------------------------
  76. //外部中斷初始化
  77. void INT_initial(void)
  78. {
  79.         MCUCR|=(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10);                        //INT0、INT1上升沿有效
  80.         GICR|=(1<<INT0)|(1<<INT1);                        //外部中斷使能
  81. }
  82. ///////////////////////ad轉換
  83. int mega16_ad(uchar Ch1)
  84. {
  85.      uint addata;
  86.          ADMUX = 0x00 | Ch1;//這個地方注意設置,外部基準源
  87.          ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);;
  88.          while(!(ADCSRA & (1 << ADIF)));
  89.          addata=ADCL;
  90.          addata=addata+ADCH*256;
  91.         // AD_data-=512;
  92.          ADCSRA &= ~(1 << ADIF);
  93.      ADCSRA &= ~(1 << ADEN);
  94.         return addata;
  95. }
  96. void AD_calculate(void)
  97. {aaa=cdis[2]*256+cdis[3]+32768;        
  98. //acc=(mega16_ad(0)-mega16_ad(2))*3.286/800;
  99. acc=(32768-aaa*1.0)/16384;//+(512-mega16_ad(2))*0.004;;
  100. if(acc>1)                 ///這個地方必須限幅,不然會出問題
  101. acc=1;
  102. else if(acc<-1)
  103. acc=-1;
  104. acc=57.3*acc;
  105. //gyro=-(mega16_ad(1)-380)*4.9;
  106. ggg=cdis[10]*256+cdis[11]+32768;
  107. gyro=(32768-ggg*1.0)/131;
  108. angle_t=mega16_ad(7)/5.3;
  109. //Kalman_Filter(acc,gyro);
  110. angle=0.95*(angle)+0.05*acc;
  111. angle_dot=gyro;

  112. }
  113. ////////////////////////////////PWM發送
  114. void PWM_output (int PWM_LH,int PWM_RH)
  115. {
  116.         if (PWM_LH<0)
  117.         {
  118.                 PORTB|=1<<7;
  119.                 PWM_LH*=-1;
  120.         }
  121.         else
  122.         {
  123.                 PORTB&=~(1<<7);
  124.         }
  125.         
  126.         if (PWM_LH>252)
  127.         {
  128.                 PWM_LH=252;
  129.         }
  130.         
  131.         
  132.         if (PWM_RH<0)
  133.         {
  134.                 PORTB|=1<<6;
  135.                 PWM_RH*=-1;
  136.         }
  137.         else
  138.         {
  139.                 PORTB&=~(1<<6);
  140.         }
  141.         
  142.         if (PWM_RH>252)
  143.         {
  144.                 PWM_RH=252;
  145.         }
  146.         
  147.                
  148.         OCR1AH=0;
  149.         OCR1AL=PWM_LH;                        //OC1A輸出;
  150.         
  151.         OCR1BH=0;
  152.         OCR1BL=PWM_RH;                        //OC1B輸出;
  153.         
  154. }
  155. ///////////////////////////////////PWM 計算
  156. void PWM_calculate(void)        
  157. {
  158.         
  159. //        PORTB|=(1<<6);
  160. /*        if (0x10==(PINB&1<<4) )        //前進
  161.         {
  162.                 Speed_Need=-4;
  163.         }
  164.         else if (0x20==(PINB&1<<5) )        //后退
  165.         {
  166.                 Speed_Need=4;
  167.         }
  168.         else        //不動
  169.         {
  170.                 Speed_Need=0;
  171.         }
  172. */
  173. //position_dot=(speed_real_LH-speed_real_RH)*0.5;     ///B
  174. //                position_dot=(-speed_real_LH-speed_real_RH)*0.5;///D
  175. //        position_dot=(speed_real_LH+speed_real_RH)*0.5; ///A
  176.   position_dot=(-speed_real_LH+speed_real_RH)*0.5;    ///C        
  177.         position_dot_filter*=0.85;                //車輪速度濾波
  178.         position_dot_filter+=position_dot*0.15;        
  179.         
  180.         position+=position_dot_filter;
  181.         position+=Speed_Need;
  182.         position+=Turn_Need;
  183.                 if (position<-768)                //防止位置誤差過大導致的不穩定
  184.         {
  185.                 position=-768;
  186.         }
  187.         else if  (position>768)
  188.         {
  189.                 position=768;
  190.         }
  191.                 PWM =-Kp_angle*angle-Kd_angle*angle_dot/*+Kp_position*position*/+Kd_position*(position_dot_filter-Speed_Need);        

  192.         speed_output_RH = PWM+Turn_Need;
  193.         speed_output_LH = PWM-Turn_Need;
  194.         PWM_output (speed_output_LH,speed_output_RH);        
  195. }
  196. ////////////////////////////////////主程序
  197. int main()
  198. {//uchar a;
  199.         DDRB=0B11000000;
  200. //        PORTB=0;
  201.         DDRB &= ~(1<<0 | 1<<1|1<<2|1<<3|1<<4|1<<5);
  202.         PORTB |= 1<<0 | 1<<1|1<<2|1<<3|1<<4|1<<5;
  203.     DDRA=0;
  204.     PORTA=0;
  205.            DDRD=0B11110010;//這個地方不能加PIN,不然會出問題
  206. DDRC |=((1<<PC0)|(1<<PC1));
  207. PORTC|=((1<<PC0)|(1<<PC1));
  208. TWBR=0x0a; //I2C 初始化,400kbps
  209. TWSR|=(1<<TWPS0);

  210. T1_initial();
  211. T2_initial();

  212. USART_Init();

  213. //        PIND=0X00;
  214. //        PORTD=0X00;
  215. //        PORTD|=~(1<<6);
  216.   // SFIOR|=1<<PUD;
  217.   INT_initial();
  218.    sei();
  219. MPU_Init();
  220.          Kp_angle=mega16_ad(3)/10.0;
  221.         Kd_angle=mega16_ad(4)/250.0;
  222.         Kp_position=mega16_ad(5)/500.0;
  223.         Kd_position=mega16_ad(6)/5.0;
  224.         angle_t=mega16_ad(7)/5.3;
  225.    while(1)
  226. {
  227. if(flager==1)
  228. {MPU_6050_Read(cdis);
  229. AD_calculate();
  230. /*flager=0;
  231. AD_calculate();
  232. PWM_calculate();
  233. MPU_6050_Read(cdis);
  234. speed_real_LH=0;//速度計數清零
  235. speed_real_RH=0;
  236. }*/
  237. /*
  238. Putc(0xfd);
  239. Putc(0);
  240. Putc(angle*2+120);
  241. */
  242. Putc(0xff);
  243. Putc(angle+128); //紅
  244. Putc(angle_t+10);//綠
  245. Putc(acc+128);   //藍
  246.   }
  247.    }
  248.    return 0;
  249. }

  250. ISR(TIMER2_COMP_vect)//定時器2中斷服務函數
  251. {
  252. flager=1;
  253. NUMBER++;
  254. //MPU_6050_Read(cdis);
  255. //AD_calculate();
  256. }
  257. ISR(INT0_vect)
  258. {
  259.         if (0==(PINB&1<<0))
  260. ……………………

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

所有資料51hei提供下載:
Anyway2.0_新驅動_客戶例程.zip (96.57 KB, 下載次數: 35)


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

使用道具 舉報

沙發
ID:30708 發表于 2019-10-13 15:12 | 只看該作者
感謝上傳代碼
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美精品久久久久久久久老牛影院 | 欧美亚洲视频在线观看 | 精品日韩一区二区 | 91免费小视频 | 国产精品久久国产精品 | 密乳av| 韩日一区二区 | 久久久久久久久久久高潮一区二区 | 在线免费观看欧美 | 一区二区三区免费 | 亚洲精品v | 国产免费色| 一区在线观看视频 | 日韩欧美手机在线 | 国产精品免费看 | 欧美精品一区在线 | 久久成人精品视频 | 日韩av免费在线观看 | 青青草视频网站 | 青青草免费在线视频 | 欧美一区二区三区在线视频 | 国产精品免费看 | 久久久www成人免费精品 | 人人鲁人人莫人人爱精品 | 99视频免费在线 | 成人特级毛片 | 久久久久久久一区二区三区 | 精品国产乱码久久久久久闺蜜 | 九九热精品视频在线观看 | 精品一区二区三区免费视频 | 久久电影一区 | 国产成人99久久亚洲综合精品 | 中文字幕日韩欧美一区二区三区 | av国产在线观看 | jdav视频在线观看免费 | 性高湖久久久久久久久 | 精品不卡 | 天天天天天天天干 | 精品久久久久久国产 | 亚洲精久 | 国产999精品久久久 午夜天堂精品久久久久 |