这份代码是国赛的时候用的,也算是一个豪华的平衡车,里面有很多算法值得初学者学习。
所有的输入设备建议加一个二极管
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)
|