我们经常会使用旋转编码器EC11作为系统输入,或者用电磁或光电编码器对电机进行测速,例如平衡车项目中的测速反馈。
本次我们去查看CH32V307的手册,看到对高级定时器
有如下描述:
本次我们使用高级定时器TIM9
和串口UART1
,接线按照下表接线:
旋转编码器 | CH32V307 | 功能 |
---|---|---|
A | A2 | 编码器A相 |
B | A3 | 编码器B相 |
M | A1 | 编码器按键 |
接线后如图:
main.c
:/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : Main program body.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/*
*@Note
编码器例程EC11
*/
#include "debug.h"
/*********************************************************************
* @fn Input_Capture_Init
*
* [url=home.php?mod=space&uid=2666770]@Brief[/url] Initializes TIM9 Encoder mode.
*
* [url=home.php?mod=space&uid=3142012]@param[/url] arr - the period value.
* psc - the prescaler value.
* ccp - the pulse value.
*
* [url=home.php?mod=space&uid=1141835]@Return[/url] none
*/
void Input_Capture_Init( u16 arr, u16 psc )
{
GPIO_InitTypeDef GPIO_InitStructure={0};
TIM_ICInitTypeDef TIM_ICInitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM9, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure);
GPIO_ResetBits( GPIOA, GPIO_Pin_2);
GPIO_ResetBits( GPIOA, GPIO_Pin_3);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
// 计数值
TIM_TimeBaseInitStructure.TIM_Period = arr;
// 分频系数
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
// 数字滤波器分频为0
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
// 向上计数
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM9, &TIM_TimeBaseInitStructure);
TIM_EncoderInterfaceConfig(TIM9, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
// 滤波器
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM9, &TIM_ICInitStructure);
TIM_ClearFlag(TIM9, TIM_FLAG_Update);//清除TIM的更新标志位
TIM_ITConfig(TIM9, TIM_IT_Update, ENABLE);
//Reset counter
TIM_SetCounter(TIM9,0);
// 使能TIM9
TIM_Cmd( TIM9, ENABLE );
}
/*********************************************************************
* @fn GPIO_Toggle_INIT
*
* @brief Initializes GPIOA.0
*
* @return none
*/
void GPIO_KEY_M_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************
* @fn main
*
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\n\r",SystemCoreClock);
// 计数值,分频系数
Input_Capture_Init( 0xFFFF, 0);
GPIO_KEY_M_INIT();
uint16_t counter = 0;
while(1)
{
if(TIM_GetCounter(TIM9) != counter)
{
counter = TIM_GetCounter(TIM9);
printf("counter = %d\n\r",counter);
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)!=1)
{
Delay_Ms(5);
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)!=1)
{
printf("key is press!\n\r");
}
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)!=1);
}
}
}
旋转EC11,或者按下EC11的按键,即可看到串口输出如图:
更多回帖