一、微项目实现目标:
检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加cout,转速值为正,一侧转动减少count,转速值为负;
二、微项目硬件配置需求:
1,stm32F103C8T6核心板一块
2,0.96寸OLED显示,用于显示计数
3,旋转编码器,反馈正交信号脉冲
三、前置知识:
1,编码器计数模式框图
①信号流:
两路GIPO输入---滤波器----边沿检测极性选择---输入TI1FP1和TI2FP2给到编码器接口---根据相位模式(T1和T2的相位之差)判断CNT是向上计数还是向下计数-----经过分频器处理,最后实现计数
②计数模式
如果一直向下计数到0,在继续计数时,则寄存器数据由于无符号整型缘故,会变成65535,由于数据以补码的形式存储,则强转为int时刻,会变成-1;
③旋转编码器的输入波形情况
正转时刻,A相输出超出B相输出90度
反转时刻,A相输出滞后B相输出90度
④设置正相模式与反相模式
就是对于计数模式的一次反向处理,并对应到原本的计数模式上(一般用的较少)
反向之后
四、代码逻辑分析:
①打开TIM3和GPIOA的时钟
②配置GPIOA的PA5和PA6
③初始化时基模块(注意,在编码器模式下,不需要配置时钟源,输入的TI1FP1或TI2FP2作为时钟),主要是指ARR和PSC
④初始化输入捕获模块,通道1 和通道2都需要配置
⑤配置配置编码器接口
⑥开启时钟模块
五、代码示例:
①打开TIM3和GPIOA的时钟
//初始化时钟TIM3 ,PA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
②配置GPIOA的PA5和PA6,上拉输入
//配置PA6\PA7输入GPIO
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStruct);
③初始化时基模块(注意,在编码器模式下,不需要配置时钟源,输入的TI1FP1或TI2FP2作为时钟),主要是指ARR和PSC
//初始化时基模块
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//在编码器模式下,此参数无作用
TIM_TimeBaseInitStruct.TIM_Period=65536-1;//ARR
TIM_TimeBaseInitStruct.TIM_Prescaler=1-1;//PSC,不分频
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);
④初始化输入捕获模块,通道1 和通道2都需要配置
//输入捕获单元配置
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICStructInit(& TIM_ICInitStruct);//先进行默认初始化
TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter=0xf;
TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH1通道
TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
TIM_ICInitStruct.TIM_ICFilter=0xf;
TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH2通道
⑤配置配置编码器接口
//配置编码器接口
TIM_EncoderInterfaceConfig( TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising
, TIM_ICPolarity_Rising);
⑥开启时钟模块
TIM_Cmd(TIM3,ENABLE);
⑦获取速度模块
本质上,获取的是CNT的计数值,但是如果1S读取一次,并且清空为0 ,则实现了速度测算的功能
1-注意此处的强制转化为有符号数据(反码存储)
2-需要配合定时器中断1S使用(或者延时1S执行一次,当然中断的形式更佳)
int16_t getspeedn(void)
{
int16_t temp;
temp= TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return temp;
}
⑧主函数中配置
1-TIM2_IRQHandler()一秒执行文章来源:https://www.toymoban.com/news/detail-475626.html
2-speed要整除4,原因是数据采样时刻,一次转动被采样4次文章来源地址https://www.toymoban.com/news/detail-475626.html
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "OLED.H"
#include "encode.h"
#include "timer.h"
int16_t speed=0;
int main()
{
OLED_Init();
encoder_init();
timer_init();
OLED_ShowString(1,1,"count:000");
OLED_ShowString(2,1,"speed:0000rpm");
while(1)
{
OLED_ShowSignedNum(2,7,speed/4,3);
}
}
//中断服务函数
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
speed= getspeedn();
}
TIM_ClearITPendingBit( TIM2,TIM_IT_Update );
}
到了这里,关于STM32-微项目07-旋转编码器计数及测速的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!