STM32-微项目07-旋转编码器计数及测速

一、微项目实现目标:

检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加cout,转速值为正,一侧转动减少count,转速值为负;

STM32-微项目07-旋转编码器计数及测速_第1张图片

 

二、微项目硬件配置需求:

1,stm32F103C8T6核心板一块

2,0.96寸OLED显示,用于显示计数

3,旋转编码器,反馈正交信号脉冲

STM32-微项目07-旋转编码器计数及测速_第2张图片STM32-微项目07-旋转编码器计数及测速_第3张图片

三、前置知识:

1,编码器计数模式框图

STM32-微项目07-旋转编码器计数及测速_第4张图片

 ①信号流:

两路GIPO输入---滤波器----边沿检测极性选择---输入TI1FP1和TI2FP2给到编码器接口---根据相位模式(T1和T2的相位之差)判断CNT是向上计数还是向下计数-----经过分频器处理,最后实现计数

②计数模式

STM32-微项目07-旋转编码器计数及测速_第5张图片

 如果一直向下计数到0,在继续计数时,则寄存器数据由于无符号整型缘故,会变成65535,由于数据以补码的形式存储,则强转为int时刻,会变成-1;

③旋转编码器的输入波形情况

正转时刻,A相输出超出B相输出90度

反转时刻,A相输出滞后B相输出90度

STM32-微项目07-旋转编码器计数及测速_第6张图片

 ④设置正相模式与反相模式

就是对于计数模式的一次反向处理,并对应到原本的计数模式上(一般用的较少)

STM32-微项目07-旋转编码器计数及测速_第7张图片

反向之后

STM32-微项目07-旋转编码器计数及测速_第8张图片

 

 

四、代码逻辑分析:

①打开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 );
 }
 
 

你可能感兴趣的:(stm32,嵌入式硬件,单片机)