STM32HAL学习笔记六-定时器之正交解码
本次实验使用STM32F103ZET6开发板的TIM2对带霍尔编码器的减速电机进行计数,然后将输出计数值通过串口打印,因此本次实验是在实验二的基础上进行修改。参考:https://blog.csdn.net/ASWaterbenben/article/details/115588689?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164308693616781685356407%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164308693616781685356407&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-3-115588689.first_rank_v2_pc_rank_v29&utm_term=hal%E6%AD%A3%E4%BA%A4%E8%A7%A3%E7%A0%81&spm=1018.2226.3001.4187
,并根据自己的情况做了相应修改。
1.将组合通道设置为计数模式
2.参数配置
2.1修改计数模式
因为霍尔编码器有AB相,所以选择在TI1和TI2上计数模式(表77),同时根据TI1和TI2输入脉冲的相交差确定计数方向(图133)
2.2计数极性
根据表77,在TI1和TI2上计数模式,无论计数极性是下降沿还是上升沿,TI1和TI2都会进行计数只是计数的方向不同。
2.3计数设置
由于我使用的带编码器减速电机的减速比是30,线束为13,而且在在TI1和TI2上计数模式,无论计数极性是下降沿还是上升沿,TI1和TI2都会进行计数,所以这里将计数值修改成13 X 30 X 4 - 1 = 1559。如果这里将分频系数设置成4,那么计数值应为13 X 30 - 1。
3.使能中断
4.程序编写
4.1变量定义
uint8_t Direction;//计数方向
uint16_t enc1 = 0,enc1_old = 0;//当前计数值 上次计数值,用于判断是否转过一圈
int16_t enc2 = 0;//记录转过圈数
int32_t enc;//总计数值enc2*1560 + enc1
uint16_t counter;//用于分频打印的计数值
4.2初始化
HAL_UART_Receive_IT(&huart1,RxBuf1,sizeof(RxBuf1));//开启串口接收中断
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);//打开计数器
printf("Hello World\r\n");
4.3调试打印
Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2);
enc1 = (uint32_t)(__HAL_TIM_GET_COUNTER(&htim2)); //获取定时器的值
if((Direction == 0) &(enc1 < enc1_old)) //正向旋转数值变小,说明进位
{
enc2++;
}
if((Direction == 1) &(enc1 > enc1_old)) //反向旋转数值变小,说明借位
{
enc2--;
}
enc1_old = enc1; //更新enc1_old,便于下次计算
enc = enc2*1560 + enc1; //计算当前计数总值,带+-号
counter++; //主函数计数
if(counter>1000) //主函数每次运行约1ms,此处用于每1000ms发送一次数
{
counter = 0; //计数值清零
printf("Dir %d, Enc2 %d, Enc1 %d, ENC %d\r\n",Direction,enc2,enc1,enc);//打印相关计数数据
}
HAL_Delay(1);
5.调试结果
结果貌似有点不符合,我也不知道是不是电机的问题,还是与标准库不同。