stm32两轮平衡车-01

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

小车指示灯代码如下

cs 复制代码
#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;
    }

}

定时器:

cs 复制代码
​
#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);                                                //陀螺仪零偏校准
}



​

按键:

cs 复制代码
#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 分钟前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计14 分钟前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦2 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报2 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业2 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能2 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
czwxkn2 小时前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件
Love Song残响2 小时前
NVIDIA显卡终极优化指南
stm32·单片机·嵌入式硬件
qq_672592753 小时前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉82183 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车