华大HC32L13x系列定时器的正交编码功能笔记

MCU:HC32L130
引脚:PB06,PB07,端口复用af4,af5;定时器:TIM0
实现功能:正确识别旋钮编码器步进,实现挡位调节

官方例程对这个的描述很少,一步一步踩出来的!!

1.编码器认识
1.1结构

1.2接线

编码器规格书额定电压5V,实际可以当作普通按键来用,3V也能正常使用。

DE端相当于普通按键,

AB端接上拉电阻到VCC,C端接GND,

A,B端建议加滤波电容,实测10nf效果挺好,太大会影响波形

1.3波形

正向旋扭时波形

反向旋钮时波形

2.程序实现
2.1定时器配置:

1.基本功能配置:时钟使能,计数方式,周期设置,计数值设置,重载值,定时器功能等

2.正交编码器功能配置,此项配置完成会记录编码器波形边沿个数

3.通道配置:输入捕获,触发方式,滤波设置

4.触发中断使能

/*******************************************************************************
* Function Name  : encoder_Capture_Init();
* Description    : 编码器正交编码计数
* Input          : PB6 PB7
*								 
* Output         : None
* Return         : None
* Attention		 	 : None
*******************************************************************************/
void encoder_Capture_Init(void)
{
		uint16_t                   u16ArrValue;
    uint16_t                   u16CntValue;
    stc_bt_mode23_cfg_t        stcBtBaseCfg;
    stc_bt_m23_master_slave_cfg_t     stcBtmasterslaveCfg;
	  stc_bt_m23_input_cfg_t     stcBtPortCapCfg;

    
    //结构体初始化清零
    DDL_ZERO_STRUCT(stcBtBaseCfg);
    DDL_ZERO_STRUCT(stcBtPortCapCfg);
    
    Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能
    
    stcBtBaseCfg.enWorkMode    = BtWorkMode2;              //锯齿波模式
    stcBtBaseCfg.enCT          = BtTimer;                  //定时器功能,计数时钟为内部PCLK
    stcBtBaseCfg.enPRS         = BtPCLKDiv64;              //PCLK/64
    stcBtBaseCfg.enCntDir      = BtCntUp;                  //向上计数,在三角波模式时只读
    Bt_Mode23_Init(TIM0, &stcBtBaseCfg);                   //TIM0 的模式2功能初始化
	
	  u16ArrValue = 0XFFFF;
    Bt_M23_ARRSet(TIM0, u16ArrValue, TRUE);                //设置重载值,并使能缓存
    
    u16CntValue = 0;
    Bt_M23_Cnt16Set(TIM0, u16CntValue);                    //设置计数初值
    
		stcBtmasterslaveCfg.enMasterSlaveSel = BtSlaveMode;					///< 从模式   此项不配置对功能不影响
		stcBtmasterslaveCfg.enSlaveModeSel = BtSlaveCodeCnt3;				///< 正交编码计数模式3
		stcBtmasterslaveCfg.enTsSel = BtTs0ETR;										///<  外部输输入滤波后的相位选择信号
//		stcBtmasterslaveCfg.enMasterSrc	= BtMasterOCA0Ref;
		Bt_M23_MasterSlave_Set(TIM0,&stcBtmasterslaveCfg);

    stcBtPortCapCfg.enCH0ACapSel   = BtCHxCapFallRise;     //CHA通道上升沿下降沿捕获都使能
    stcBtPortCapCfg.enCh0ACmpCap   = BtCHxCapMode;         //CHA通道设置为捕获模式
    stcBtPortCapCfg.enCH0AInFlt    = BtFltPCLKDiv64Cnt3;   //PCLK/16 3个连续有效
    stcBtPortCapCfg.enCH0APolarity = BtPortPositive;       //正常输入输出 
		
    stcBtPortCapCfg.enCH0BCapSel   = BtCHxCapFallRise;     //CHB通道上升沿下降沿捕获都使能
    stcBtPortCapCfg.enCh0BCmpCap   = BtCHxCapMode;         //CHB通道设置为捕获模式
    stcBtPortCapCfg.enCH0BInFlt    = BtFltPCLKDiv64Cnt3;   //PCLK/16 3个连续有效		//滤波设置 16us
    stcBtPortCapCfg.enCH0BPolarity = BtPortPositive;       //正常输入输出 
    Bt_M23_PortInput_Cfg(TIM0, &stcBtPortCapCfg);          //端口输入初始化配置
   
    

		Bt_M23_EnSwTrigCapCmpA(TIM0);											//捕获比较A软件触发  使能
		Bt_M23_EnSwTrigCapCmpB(TIM0);											//捕获比较B软件触发	 使能
		
	  Bt_ClearAllIntFlag(TIM0);                              //清中断标志
    Bt_Mode23_EnableIrq(TIM0,BtCA0Irq);                    //使能TIM0 CB0比较/捕获中断		
    Bt_Mode23_EnableIrq(TIM0,BtCB0Irq);                    //使能TIM0 CB0比较/捕获中断
    EnableNvic(TIM0_IRQn, IrqLevel3, TRUE);                //TIM0中断使能
		
		Bt_M23_Run(TIM0);
}

5.中断处理

注意:清中断方式要AB通道分别清除,如果直接清楚定时器中断,会同时清两个通道,会出现问题的

最后获得,TIM0_COUNT会是边沿的个数,编码器一个步进,AB端会分别产生一个下降沿和上升沿,共计4个

正向旋转1步,A通道的值:BtCCR0A_VAL会比TIM0_COUNT  多 1,BtCCR0A_VAL会比BtCCR0B_VAL 多 1;TIM0_COUNT + 4;

反向向旋转1步,B通道的值:BtCCR0B_VAL会比TIM0_COUNT 多 1,BtCCR0A_VAL会比BtCCR0B_VAL 少 1;TIM0_COUNT + 4;

/*******************************************************************************
 * TIM0中断服务函数
 ******************************************************************************/
uint8_t  ENCODER_CNT;
void Tim0_IRQHandler(void)
{
    static uint16_t BtCCR0A_VAL,BtCCR0B_VAL,TIM0_COUNT;
//Timer0 模式23 捕获中断A
	  if(TRUE == Bt_GetIntFlag(TIM0, BtCA0Irq))
    {
				Bt_ClearIntFlag(TIM0,BtCA0Irq); //清除中断标志
    }
//    //Timer0 模式23 捕获中断B
    if(TRUE == Bt_GetIntFlag(TIM0, BtCB0Irq))
    {
        Bt_ClearIntFlag(TIM0,BtCB0Irq); //清除中断标志
    }
    
			TIM0_COUNT = Bt_M23_Cnt16Get(TIM0);
			BtCCR0B_VAL = Bt_M23_CCR_Get(TIM0,BtCCR0B);
			BtCCR0A_VAL = Bt_M23_CCR_Get(TIM0,BtCCR0A);		
		
		if(TIM0_COUNT%4 == 0)
		{
				
				if((BtCCR0B_VAL+1 == TIM0_COUNT)&&(BtCCR0A_VAL + 1 == BtCCR0B_VAL))
				{
					if(ENCODER_CNT < 10)ENCODER_CNT++;
				}
				if((BtCCR0A_VAL - 1 == TIM0_COUNT)&&(BtCCR0B_VAL - 1 == BtCCR0A_VAL))
				{
					if(ENCODER_CNT > 0)ENCODER_CNT--;	
				}
		}
}
3.个人理解,有问题恳请指正!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值