stm32两轮平衡车-01

  代码有点多,分好几章进行分享,可关注哦。

小车指示灯代码如下

#include "led.h"
#include "imu.h"
#include "mpu6050.h"
#include "imath.h"

/*
 * 函数名:led_on_all
 * 描述  :打开LED灯显示
 * 输入  : 
 * 返回  : 
 */
void led_on_all(void)
{
    led_on(1);
    led_on(2);  
}
/*
 * 函数名:led_off_all
 * 描述  :关闭LED灯
 * 输入  : 
 * 返回  : 
 */
void led_off_all(void)
{
    led_off(1);
    led_off(2);    
}

/*
 * 函数名:led_init
 * 描述  :LED指示灯初始化
 * 输入  : 
 * 返回  : 
 */
void led_init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(led1_rcc | led2_rcc , ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = led1_pin;
    GPIO_Init(led1_port, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = led2_pin;
    GPIO_Init(led2_port, &GPIO_InitStructure);  
    
    led_on_all();
}

/*
 * 函数名:led_on
 * 描述  :点亮LED
 * 输入  :led_num指示灯号数
 * 返回  : 
 */
void led_on(uint8_t led_num)
{
    if(led_num==1)
        led1_port->BRR  = led1_pin;
    if(led_num==2)
        led2_port->BRR  = led2_pin;
}

/*
 * 函数名:led_off
 * 描述  :关闭LED
 * 输入  :led_num指示灯号数
 * 返回  : 
 */
void led_off(uint8_t led_num)
{
    if(led_num==1)
        led1_port->BSRR  = led1_pin;
    if(led_num==2)
        led2_port->BSRR  = led2_pin;
}

/*
 * 函数名:led_toggle
 * 描述  :翻转LED状态
 * 输入  :led_num指示灯号数
 * 返回  : 
 */
void led_toggle(uint8_t led_num)
{
    if(led_num==1)
        led1_port->ODR ^= led1_pin;    
    if(led_num==2)
        led2_port->ODR ^= led2_pin;
}

_LED_STATES _led ={0};


//无任何操作时状态灯
void _no_operation(void)
{
    static uint16_t l_cnt = 0;
    
    if(++l_cnt>100)
    {
        l_cnt = 0;
        led_toggle(1);         
    }
}
//校准陀螺仪时的指示灯状态
void _cal_operation(void)
{
    static uint16_t l_cnt = 0;
    
    if(++l_cnt>10)
    {
        l_cnt = 0;
        led_toggle(1);         
    }
}
//_CAR_STATES _car = {0};


void led_blink(void )
{
    switch(_led.sta)
    {
        case 1:
            _no_operation(); break;
        case 2:
            _cal_operation();break;
        default:break;
    }

}

定时器:

​
#include "timer.h"
#include "led.h"
#include "systick.h"
#include "iic.h"
#include "mpu6050.h"
#include "imu.h"
#include "pwm.h"
#include "controller.h"
#include "usart1.h"
#include "imath.h"
#include "key.h"
#include "ps2.h"
#include "ultrasonic.h"
#include "Infrared.h"

/* SystemFrequency / 100     10ms中断一次
*  SystemFrequency / 1000    1ms中断一次
*  SystemFrequency / 100000	 10us中断一次
*  SystemFrequency / 1000000 1us中断一次
*/
uint32_t tick_count;
/*
 * 函数名:systick_init
 * 描述  :系统滴答定时器配置初始化
 * 输入  : 
 * 返回  : 
 */
void systick_init(void)
{
	SystemCoreClockUpdate();
    //时钟频率:72Mhz , 每秒可以计数72000000次,一次的时间则为:1/72000(ms),10ms需要的次数:10/(1/72000) = 720000 -> 5ms需要的次数则为:360000
	if (SysTick_Config(SystemCoreClock / 200))	        //1000 -> 1ms
	{ 
		/* Capture error */ 
		while (1);
	}
        
	SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;          //使能
}


uint32_t softTimes[5] = {0,0,0,0,0};                        //软定时时间存储
/*
 * 函数名:softTimesCountdown
 * 描述  :软定时器倒计时
 * 输入  : 
 * 返回  : 
 */
void softTimesCountdown(void)
{
	uint8_t i;
	for(i = 0;  i < 5; i++)
    {
		if(softTimes[i] > 0)
            softTimes[i]--;
	} 
}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    softTimesCountdown();                                                   //软件定时倒计时
    UltrasonicCheck();                                                      //超声波在位检测
    get_gyro_raw();                                                         //陀螺仪数据
    get_deg_s(&gyro_raw_f,&Mpu.deg_s);                                      //陀螺仪原始数据转为度为单位的速率    
    get_rad_s(&gyro_raw_f,&Mpu.rad_s);                                      //陀螺仪原始数据转为弧度为单位的速率
    get_acc_raw();                                                          //加速度数据
    acc_iir_lpf(&acc_raw_f,&acc_att_lpf,Mpu.att_acc_factor);                //姿态解算时加速度低通滤波 
    get_acc_g(&acc_att_lpf,&Mpu.acc_g);  
                                                                            //姿态解算
    mahony_update(Mpu.rad_s.x,Mpu.rad_s.y,Mpu.rad_s.z,Mpu.acc_g.x,Mpu.acc_g.y,Mpu.acc_g.z); 
    Matrix_ready();                                                         //姿态解算相关矩阵更新

    encoder_val_a = read_encoder(ENCODER_A);                                //A编码器值读取
    encoder_manage(&encoder_val_a);                                         //编码器值处理
    encoder_val_b = read_encoder(ENCODER_B);                                //B编码器值读取    
    encoder_manage(&encoder_val_b);                                         //编码器值处理

    ctr.pwm[0] = ctr_bal(att.rol,Mpu.deg_s.y);                              //角度直立平衡控制器
    ctr.pwm[1] = ctr_vel(-encoder_val_a,encoder_val_b);                     //速度控制器
    ctr.pwm[2] = ctr_turn(-encoder_val_a,encoder_val_b,Mpu.deg_s.z);        //转向控制器
   
    ctr.out[0] = ctr.pwm[0] + ctr.pwm[1] + ctr.pwm[2];                      //电机1匹配输出           
    ctr.out[1] = ctr.pwm[0] + ctr.pwm[1] - ctr.pwm[2];                      //电机2匹配输出

    i_limit(&(ctr.out[0]),AMPLITUDE);                                       //输出限幅
    i_limit(&(ctr.out[1]),AMPLITUDE);                                       //输出限幅
     
    dir_config(&(ctr.out[0]),&(ctr.out[1]));                                //根据正负设置方向

    _ctr_out();                                                             //控制器输出
    
    ANO_DMA_SEND_DATA();                                                    //地面站波形显示
    gyro_cal(&gyro_raw_cal);                                                //陀螺仪零偏校准
}



​

按键:

#include "key.h"
#include "systick.h"
#include "imath.h"

_KEY key = {0};

//初始化IO
void key_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
        
    RCC_APB2PeriphClockCmd(key_right_rcc, ENABLE);

    GPIO_InitStructure.GPIO_Pin = key_right_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU  ;          
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(key_right_port, &GPIO_InitStructure); 
}

//按键扫描
//0:不支持连续按
//1:支持连续按
uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1;
    
    if(mode)  
        key_up = 1;
    if(key_up&&(key_right==0))
    {
        tdelay_ms(5);
        key_up = 0;
    
        if(key_right==0)    return 1;
    }
    else if(key_right==1)
    {
        key_up = 1;
    }
    return 0;
}


//按键处理任务
void key_info(void)
{
    key.value = key_scan(0);                //获取键值
    if(key.value==1)    key.flag = 1; 
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值