img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

5.编码器跟单片机共地
6.编码器5V接单片机5V
7.编码器A,B相接单片机的TIM4的CH1跟CH2就是PD12,PD13
三、核心模块TIM定时器编码器模式讲解
参考STM32f4中文参考手册
编码器模式的好处:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
编码器模式是TIM自带的对编码处理的一种特殊的输入捕获模式
好处很直接:
在这里插入图片描述
1.当编码器出现抖动,它能够防止抖动,不影响计数,并且它可以采用四倍频的方法,使得误差减小4倍。
2.能通过检测TIMx_CR1的第四位DIR来判断电机的转动方向:正转还是反转,这功能很强
在这里插入图片描述
3.重要备注:当定时器检测到一个正向脉冲计数值**+1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!**这很重要划重点
所以我们并不能知道检测一个脉冲用了多少时间,所以还要再开一个定时器。
网上搜到的配置STM32F1编码器模式的方法不适用于F4
四、代码编写
思路:TIM13用来提供10khzPWM波跟占空比
TIM4配置编码器模式来实现对AB相编码器的处理
鉴于所以我们并不能知道检测一个脉冲用了多少时间,所以还要再开一个定时器TIM5
配置TIM4代码如下

void Encoder\_Init\_TIM4(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef  NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;    

  RCC\_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);    
  RCC\_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);  
		
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13;          
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                    
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;              
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                  
  GPIO\_Init(GPIOD, &GPIO_InitStructure);                          

  GPIO\_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);           
	GPIO\_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);           
	
  TIM_TimeBaseStructure.TIM_Period = arr; 	                      
	TIM_TimeBaseStructure.TIM_Prescaler=psc;                        
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;       
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;           
	TIM\_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);                  
	
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;                  
  TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;	      
  TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   
  TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;	            
  TIM_ICInitStructure.TIM_ICFilter =0;                            
  TIM\_ICInit(TIM4,&TIM_ICInitStructure);
	
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;                  
  TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;	      
  TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   
  TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;	            
  TIM_ICInitStructure.TIM_ICFilter=0;                             
  TIM\_ICInit(TIM4,&TIM_ICInitStructure);
	
	TIM\_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );
		
  NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;                   
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;                   
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;      
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;            
	NVIC\_Init(&NVIC_InitStructure);                                 
		
	TIM\_ITConfig(TIM4,TIM_IT_Update,ENABLE);                        
	TIM\_Cmd(TIM4,ENABLE);   
}




最难配置的已经告诉大家了
最重要的是这个函数TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );
配置的编码器模式,具体模式为TIM_EncoderMode_TI12
其它timer.h里代码如下

void TIM5\_Int\_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC\_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);            	
	
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  										TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; 	
	TIM_TimeBaseInitStructure.TIM_Period=arr;   										
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM\_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
	
	TIM\_ITConfig(TIM5,TIM_IT_Update,ENABLE); 										     
	TIM\_Cmd(TIM5,ENABLE); 																           
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn; 									 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; 			 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02; 						 
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC\_Init(&NVIC_InitStructure);
	
}




void TIM4\_IRQHandler(void)
{
		if(TIM\_GetITStatus(TIM4,TIM_IT_Update)==SET)                    
	{   
		Encoder_Timer_Overflow++;     		
	}
	TIM\_ClearITPendingBit(TIM4,TIM_IT_Update);  

}

u32 Read\_Encoder(void)
{
  u32 Count;                                                      
  u16 Current_Count;                                              
	u16 Enc_Timer_Overflow_one;	                                   

  Enc_Timer_Overflow_one=Encoder_Timer_Overflow;                  
  Current_Count = TIM\_GetCounter(TIM4);                           
  Encoder_Timer_Overflow=0;                                       
	if((TIM4->CR1&0x0010) == 0x0010)                                
    Count = (u32)((-1\*Enc_Timer_Overflow_one)\*(4\*ENCODER_PPR-4) + (Current_Count - Previous_Count));  
	else                                                            
		Count = (u32)(Current_Count - Previous_Count + (Enc_Timer_Overflow_one) \* (4\*ENCODER_PPR-4)); 
		     
  Previous_Count = Current_Count;  
  return(Count);
}


这里面
if((TIM4->CR1&0x0010) == 0x0010)
Count = (u32)((-1Enc_Timer_Overflow_one)(4*ENCODER_PPR-4) + (Current_Count - Previous_Count));
else
Count = (u32)(Current_Count - Previous_Count + (Enc_Timer_Overflow_one) * (4乘以ENCODER_PPR-4));
用来得到脉冲的数量并通过DIR位来判断给不给脉冲数量加正负号
主函数代码如下
main.c

	#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "timer.h"
#include "pwm.h"
#include "gpio.h"
#include "math.h"
#include "stdio.h"
#include "control.h"


int encode;
float speed,t;
extern int Encoder_Timer_Overflow;
 u8 key;
int duty=50;   
void keyscan(void);
	int main(void)
{ 	
	
	
	delay\_init(168);		
	uart\_init(115200);	
	KEY\_Init();
	\_GPIO\_Init();
	
	  NVIC\_PriorityGroupConfig(NVIC_PriorityGroup_2);
						
	    TIM13\_PWM\_Init(8400-1,0);  // 84mhz->10khz
			TIM\_SetCompare1(TIM13,(int)(8400\*(duty/100.0)));
	
	Encoder\_Init\_TIM4((ENCODER_PPR-1)\*4,1-1);        
	TIM5\_Int\_Init(500-1,8400-1);                     
	          
	           
											
							while(1)
								{  
								  keyscan();
					        delay\_ms(200);
}
}



void keyscan(void)
{
	key=KEY\_Scan(0);
	if(key)
		{						   
						switch(key)
				 {				 
					case WKUP_PRES:	
					 GPIO\_ToggleBits(GPIOF,GPIO_Pin_6);
					 GPIO\_ToggleBits(GPIOF,GPIO_Pin_4);
					 break;
			


![img](https://img-blog.csdnimg.cn/img_convert/f4e9fa1dd8f1a6211e0ce65688f0eb34.png)
![img](https://img-blog.csdnimg.cn/img_convert/b2c9aa185293492e8f0e8ccb8943b2ce.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐