STM32 |
您所在的位置:网站首页 › pr编码一直是0 › STM32 |
一、微项目实现目标: 检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加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()一秒执行 2-speed要整除4,原因是数据采样时刻,一次转动被采样4次 #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 ); } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |