這份代碼是國賽的時候用的,也算是一個豪華的平衡車,里面有很多算法值得初學者學習。
所有的輸入設備建議加一個二極管
STC8G8K64S4主板IO分配推薦
編碼器2個
DIR P50
LSB CTIM0_P34
DIR P51
LSB CTIM3_P04
ICM20602:
SPC P25
SDI P23
SDO P24
CS P27
SPI屏幕引腳:
SCL P25
SDA P23
RST P32
DC P33
CS P35
BL P36
2個電機:
P00
P01
P22
P26
線性CCD(第一個):
CLK: P20
SI: P21
AO:P05
線性CCD(第二個):
CLK: P20
SI: P21
AO:P06
單片機源程序如下:
- /********************* 節能管腳分配 *******************************************
- REST P54
- LED P47
- LED P15
- ---------------------------------------------------------------------------
- 下載口:
- R P30
- T P31
- UART3: 調試口
- R P50
- T P51
- UART4: 上位機
- R P52
- T P53
- ---------------------------------------------------------------------------
- 模擬MPU6050:
- SCL P32
- SDA P33
- MPUIT
- ---------------------------------------------------------------------------
- ENCODER:
- L DIR:P05 TIM3_CIN:P04
- R DIR:P07 TIM4_CIN:P06
- ---------------------------------------------------------------------------
- MOTOR_PWMXX: select P2
- L P20 P21
- R P22 P23
- 備用 P24 P25 P26 P27
- STC8A 一共1個PWM模塊 可以輸出8路頻率相同的PWM波 這8路PWM每路可以映射在三個管腳上面
- channel n = 2 n = 1 n = 6
- PWM00 P2_0 P1_0 P6_0
- PWM01 P2_1 P1_1 P6_1
- PWM02 P2_2 P1_2 P6_2
- PWM03 P2_3 P1_3 P6_3
- PWM04 P2_4 P1_4 P6_4
- PWM05 P2_5 P1_5 P6_5
- PWM06 P2_6 P1_6 P6_6
- PWM07 P2_7 P1_7 P6_7
- ---------------------------------------------------------------------------
- ADCX: select P1
- 0 P1.0
- 1 P1.1
- 2 P1.2
- 3 P1.3
- 4 P1.4
- 5 P1.5
- 6 P1.6
- 7 P1.7
- SCT8G/STC8A 有15個ADC通道 每個通道對應管腳如下
- 0 P1.0 8 P0.0
- 1 P1.1 9 P0.1
- 2 P1.2 10 P0.2
- 3 P1.3 11 P0.3
- 4 P1.4 12 P0.4
- 5 P1.5 13 P0.5
- 6 P1.6 14 P0.6
- 7 P1.7 15 測試內部 1.19V
- ---------------------------------------------------------------------------
- INT:
- INT0 P32
- INT1 P33
- INT2 P36
- INT3 P37
- ---------------------------------------------------------------------------
- timer:
- timer0
- timer1
- tiemr2 串口波特率發生器
- timer3 P37
- timer4
- ---------------------------------------------------------------------------
- */
- #include "headfile.h"
- //board.h文件中FOSC設置內部晶振頻率為35Mhz
- //使用stc-isp工具下載程序的時候需要將IRC頻率設置為35Mhz
- int16 send[6]; //上位機數組
- int16 sec; //小車運行時間
- float power; //電源的電壓值
- char rec; //調試串口值
- float K1=0.04; //互補濾波加權值 注意:這里原始值是0.03,可能需要更改
- float Balance_Kp=600,Balance_Kd=-10,Velocity_Kp=-6,Velocity_Ki=-0.05;//PID參數
- float Angle_Balance,Gyro_Balance,Gyro_Turn; //平衡傾角 平衡陀螺儀 轉向陀螺儀
- int Encoder_Left,Encoder_Right; //左右編碼器的脈沖計數
- long int Balance_Pwm,Velocity_Pwm,Turn_Pwm; //直立環 速度環 轉向環的pwm
- char delay_50,delay_flag;
- char oled_show,rtu_show;
- Inductance ppInductance;
- Inductance *psInductance;
- float Kp=30,Kd=12; //轉向環PD參數
- int Velocity_target;
- float zhongzhi;
- int distance_garage,distance_huandao;
- char flag,strong_flag,huandao_flag_num;
- float power_bili;
- char stop_flag;
- void main()
- {
- RSTCFG = 0x50; //自動下載和復位
-
- /**********數據初始化****************/
- psInductance=&ppInductance;
- stop_flag=0;
- sec=0;
- power=0;
- rec='p';
- Encoder_Left=Encoder_Right=0;
- oled_show=1;
- rtu_show=1;
- Velocity_target=1000;
- Velocity_Pwm=0;
- zhongzhi=-6;
- flag=2;
- strong_flag=2;
- distance_garage,distance_huandao=0;
- psInductance->InductanceGYHC_MAX=0;
- psInductance->dir_sum=0;
- huandao_flag_num=0;
- /***********************************/
-
- DisableGlobalIRQ(); //關閉總中斷
- board_init(); //初始化內部寄存器
-
-
- /**********硬件外設初始化************/
- gpio_mode(led1, GPO_PP);
- gpio_mode(led2, GPO_PP);
- gpio_mode(key1, GPI_IMPEDANCE);
- gpio_mode(key2, GPI_IMPEDANCE);
- gpio_mode(key3, GPI_IMPEDANCE);
- gpio_mode(key4, GPI_IMPEDANCE);
- gpio_mode(P00, GPI_IMPEDANCE);
- gpio_mode(P01, GPI_IMPEDANCE);
- gpio_mode(P02, GPI_IMPEDANCE);
- gpio_mode(P03, GPI_IMPEDANCE);
- gpio_mode(P05, GPI_IMPEDANCE);
- gpio_mode(P07, GPI_IMPEDANCE);
- gpio_mode(P10, GPI_IMPEDANCE);
- gpio_mode(P16, GPI_IMPEDANCE);
-
- gpio_mode(P04, GPI_IMPEDANCE);
- gpio_mode(P34, GPI_IMPEDANCE);
-
- gpio_mode(P06, GPI_IMPEDANCE);
- gpio_mode(P35, GPI_IMPEDANCE);
-
- gpio_mode(P23, GPO_PP);
- gpio_mode(P22, GPO_PP);
- gpio_mode(P21, GPO_PP);
- gpio_mode(P20, GPO_PP);
- gpio_mode(P44, GPO_PP);
- gpio_mode(PWM1_P11, GPO_PP);
- gpio_mode(PWM1_P12, GPO_PP);
- gpio_mode(PWM1_P13, GPO_PP);
- gpio_mode(PWM1_P14, GPO_PP);
-
- pwm_init(PWM1_P11,500, 0);
- pwm_init(PWM1_P12,500, 0);
- pwm_init(PWM1_P13,500, 0);
- pwm_init(PWM1_P14,500, 0);
-
- adc_init(ADC_P10, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P00, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P01, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P02, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P03, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P05, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P16, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- mpu6050_init();
- oled_init();
-
- ctimer_count_init(CTIM0_P34);
- ctimer_count_init(CTIM4_P06);
- //uart_init(UART_3, UART3_RX_P50,UART3_TX_P51, 115200, TIM_2);
- uart_init(UART_4, UART4_RX_P52,UART4_TX_P53, 115200, TIM_2);
-
- /***********************************/
-
- /**********軟件外設初始化************/
- exit_init(INT2_P36,FALLING_EDGE);
- // exit_init(INT3_P37,FALLING_EDGE);
- pca_dealy_init();
- // pca_init_interrupt_ms(PCA_0, 40); //使用PCA_0作為周期中斷,時間1ms一次
- pit_timer_ms(TIM_1,10); //定時器1
- /***********************************/
-
- adc_init(ADC_P10, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P00, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P01, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P02, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P05, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- adc_init(ADC_P16, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
- while(power<6.4)
- {
- power=12.12*adc_once(ADC_P16, ADC_10BIT)/1050;
- oled_printf_float(80,6,power,3,2);
- if(key1==0) Velocity_target=130;
- if(key2==0) Velocity_target=160;
- if(key3==0) Velocity_target=200;
- }
-
- EnableGlobalIRQ(); //開啟總中斷
-
- while(1) //50ms一個精確循環
- {
- if(oled_show==1)
- {
- oled_uint16(0,0, psInductance->InductanceAveNowA);
- oled_uint16(0,1, psInductance->InductanceAveNowB);
- oled_uint16(0,2, psInductance->InductanceAveNowC);
- oled_uint16(0,3, psInductance->InductanceAveNowD);
- oled_uint16(0,4, psInductance->InductanceAveNowE);
- oled_int16(0,5, psInductance->dir);
- oled_int16(0,6, mpu_acc_x/48);
- // oled_uint16(0,4, psInductance->InductanceAveNowE);
- //
- oled_uint16(60,0, psInductance->InductanceGYHA);
- oled_uint16(60,1, psInductance->InductanceGYHB);
- oled_uint16(60,2, psInductance->InductanceGYHC);
- oled_uint16(60,3, psInductance->InductanceGYHD);
- oled_uint16(60,4, psInductance->InductanceGYHE);
- oled_uint16(60,5,flag);
- oled_printf_float(60,6,power,3,2);
- }
- if(rtu_show==1)
- {
- send[0]=Velocity_Pwm; //mpu_gyro_z
- send[1]=Balance_Pwm;
- send[2]=Encoder_Left;
- send[3]=Encoder_Right; //注意這是平衡方向的加速度計
- send[4]=Angle_Balance; //注意這是平衡方向的加速度計
- rtu_send_data(send,5);
- }
- if(rec=='A')
- {
- Balance_Kd+=0.5;
- rec='p';
- }
- if(rec=='B')
- {
- Balance_Kd-=0.5;
- rec='p';
- }
- delay_flag = 1;
- delay_50 = 0;
- while(delay_flag);
- }
- }
- //三電感AC先比較判斷偏左還是偏右 然后用左循跡AB或者右循跡BC差比和
復制代碼
所有程序51hei提供下載:
8.12 2.2米.zip
(863.79 KB, 下載次數: 57)
2021-1-8 16:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|