记录下做stm32平衡车项目时遇到的坑
本文最后更新于7 天前,其中的信息可能已经过时,如有错误请发送邮件到3449421627@qq.com

遇到的坑

hal库获取定时器的cnt值,函数

寄存器是

TIM->CNT

=============

HAL库
__HAL_TIM_GET_COUNTER(&htim2);
设置cnt值(置为0)
__HAL_TIM_SET_COUNTER(&htim2,0);

设置pwm的值



ECB01出厂固件就有了,直接就能用,国产的,主打一个简单易用

uart发送字符串,变长和定长的函数不一样



adc模块进行计算的时候,要先进行校准
HAL_ADCEx_Calibration_Start(&hadc1);
虽然但是这个校验不要放在函数调用里一直校准呀,这样会导致一些参数被重新配置,结果不正确,所以只校准一次就行,放main函数
    
导入库,本来要导入math库结果导入main库

UART_hal库的变长中断数据接收

例子,就是测试串口1发到串口二,再传回串口1

uint8_t buff[100] = {0};
uint16_t  size = 0;  
HAL_UARTEx_ReceiveToIdle_IT(&huart1,buff,100);//这里的100是填的接收数据缓冲区的长度为100,传递具体长度要通过回调获取
HAL_UARTEx_ReceiveToIdle_IT(&huart2, buff, 100);
  while (1)
  {
  }
//下面这个是回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
  if (huart->Instance ==USART1)
  {
    size = Size;
    HAL_UART_Transmit(&huart2,buff,size,1000);
  }
  if (huart->Instance ==USART2)
  {
    size = Size;
    HAL_UART_Transmit(&huart1,buff,size,1000);
  }
  HAL_UARTEx_ReceiveToIdle_IT(&huart1,buff,100);
  HAL_UARTEx_ReceiveToIdle_IT(&huart2, buff, 100);
}

上面就是变长的

对于MPU6050

像这种用通信协议来通讯的硬件,一般都会有读写单个,多个数据,然后还有初始化,最好将硬件的地址,和寄存器封装成宏。

uint8_t Int_MPU6050_ReadByte(uint8_t reg_addr, uint8_t *receive_byte)
{
    return HAL_I2C_Mem_Read(&hi2c2, MPU_IIC_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, receive_byte, 1, 2000);
}

uint8_t Int_MPU6050_ReadBytes(uint8_t reg_addr, uint8_t *receive_buff, uint8_t size)
{
    return HAL_I2C_Mem_Read(&hi2c2, MPU_IIC_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, receive_buff, size, 2000);
}


uint8_t Int_MPU6050_WriteByte(uint8_t reg_addr, uint8_t write_byte)
{
    return HAL_I2C_Mem_Write(&hi2c2, MPU_IIC_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &write_byte, 1, 2000);
}


uint8_t Int_MPU6050_WriteBytes(uint8_t reg_addr, uint8_t *write_bytes, uint8_t size)
{
    return HAL_I2C_Mem_Write(&hi2c2, MPU_IIC_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, write_bytes, size, 2000);
}

uart定长的中断

用到的 库函数

HAL_UART_Receive_IT(&huart1,buff,10)
回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

OLED 这里用的SPI

PID调参 直立环

我这里调P的大小,要的是推一下有低频振荡,如果不出现震荡就太小了

然后在调D的时候,如果太大了,会出现高频震荡,高频振荡就类似抽搐一样,不能出现这种情况,这种情况还坏烧坏mos管,所以,出现这种情况后,应该立马关掉

PID调参 速度环

速度环的作用是让直立环保持直立的同时,不一直向前移动,测试这个速度环极性的时候,把直立环的参数先置零,然后先给速度环的P一个值,然后转动轮子,然后他自己转起来了,那就是对的,方向正确,因为,当直立环为了平衡的时候会往前追,速度增加他追的速度,这样的话,就很快回到平衡点,就不会向前移动了。

然后速度环只做了p i p一般是i的一百倍,这是经验值,i很小个位数

总体架构

image-20250419131828242

分层

应用层(小车控制、任务调度)

中间层(freertos)

硬件接口层(MPU6050,TB6612,ECB01,OLED)

驱动层(SPI,IIC,TIM,ADC等,这些都可以用hal库生成)

公共层(卡尔曼滤波,PID算法)

image-20250419132016038
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇