CH32V103单片机开发板连接旋转编码器测速

CH32V103单片机开发板/评估板连接旋转编码器测速

编码器参数

  • 型号:OMRON E6B2-CWZ1X
  • 接线定义:
    • 棕:5VDC
    • 蓝:0V
    • 黑:A相----PA0
    • 白:B相----PA1

参考

移植代码

仅需要修改 main.c,注意TIM2溢出中断,与STM32不同,TIM2中断是INTFR,而不是SR


/*
 *@Note
 串口打印调试例程:
 USART1_Tx(PA9)。
 本例程演示使用 USART1(PA9) 作打印调试口输出。

*/
/*
编码器型号:OMRON E6B2-CWZ1X
接线定义:
    棕:5VDC
    蓝:0V
    黑:A相----PA0
    白:B相----PA1
*/

#include "debug.h"

/* Global typedef */

/* Global define */
#define ENCODER_TIM_PERIOD (u16)(65535)   //不可大于65535 因为的定时器是16位的。

void Encoder_Init_TIM2(void);
int Read_Encoder(void);
void TIM2_IRQHandler(void);

/* Global Variable */


/*******************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Return         : None
*******************************************************************************/
int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Delay_Init();
	USART_Printf_Init(115200);
	printf("SystemClk:%d\r\n",SystemCoreClock);

	printf("This is printf example\r\n");
	Encoder_Init_TIM2();
	while(1)
	{
	    int a,b,c,d,rpm;
	    // 此款编码器每转1000个信号,放大4倍是4000个信号,需要注意int16溢出问题
	    int32_t sum;
	    a = Read_Encoder();
        Delay_Ms(250);
        b = Read_Encoder();
        Delay_Ms(250);
        c = Read_Encoder();
        Delay_Ms(250);
        d = Read_Encoder();
        Delay_Ms(250);
        sum = (a+b+c+d);
        rpm = sum/200*3;
//        printf("%d %d\r\n", sum, e);
        printf("%4d\r\n", rpm); // 格式化输出转速,4位整数

	}
}



/*把TIM2初始化为编码器接口模式*/
void Encoder_Init_TIM2(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;  //端口配置 PA0, PA1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                        //根据设定参数初始化GPIOA

    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器
    TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//边沿计数模式
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  //初始化定时器2

    TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3

    TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入
    TIM_ICInitStructure.TIM_ICFilter = 10;  //设置滤波器长度
    TIM_ICInit(TIM2, &TIM_ICInitStructure);//根据 TIM_ICInitStruct 的参数初始化外设   TIMx

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能定时器中断

    TIM_SetCounter(TIM2,0);
    TIM_Cmd(TIM2, ENABLE); //使能定时器2
}


/**************************************************************************
函数功能:单位时间读取编码器计数
返回 值:计数值
**************************************************************************/
int Read_Encoder(void)
{
    int Encoder_TIM = 0;
    Encoder_TIM= (short)TIM2 -> CNT;
    TIM2 -> CNT=0;
    return Encoder_TIM;
}

/* 函数功能:TIM2中断服务函数*/
void TIM2_IRQHandler(void)
{
    if(TIM2->INTFR&0X0001)  //溢出中断,与STM32不同,这里的中断别名是INTFR,而不是SR
    {
    }
    TIM2->INTFR&=~(1<<0);   //清除中断标志位
}



posted on 2021-09-28 21:17  lixiaole  阅读(1008)  评论(0编辑  收藏  举报

导航