STM32F030编码器模式不能正常工作,STM32F103上面可以正常运行 解决方案

本文主要是介绍STM32F030编码器模式不能正常工作,STM32F103上面可以正常运行 解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32F030编码器模式不能正常工作,STM32F103上面可以正常运行 解决方案

    • STM32F103程序
    • STM32F030程序
    • 原理图纸
    • 找到原因,开始解决问题
    • 解决方案

STM32F030编码器模式不能正常工作,STM32F103上面可以正常运行 解决方案

STM32F103程序

void Position_Encoder_Init(void)//time3
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;	//定时器捕获结构体定义
//	NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定时器4的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PA6和PA7设置为编码器AB相GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);   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向上计数  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 10;TIM_ICInit(TIM3, &TIM_ICInitStructure);TIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新标志位TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
/*	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器*///Reset counterTIM_SetCounter(TIM3,0);TIM_Cmd(TIM3, ENABLE); TIM3->CNT = 0;
}

STM32F030程序

void Position_Encoder_Init(void)//time3
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;	//定时器捕获结构体定义
//	NVIC_InitTypeDef NVIC_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能GPIO时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PA6和PA7设置为编码器AB相GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;	//设置为输入模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定时器3的时钟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向上计数  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 6;TIM_ICInit(TIM3, &TIM_ICInitStructure);TIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新标志位TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
//	TIM3->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; /* (1)*/
//	TIM3->CCER &= (uint16_t)(~(TIM_CCER_CC1P | TIM_CCER_CC2P)); /* (2) */
//	TIM3->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; /* (3) */
//	TIM3->CR1 |= TIM_CR1_CEN; /* (4) */
//		
//	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
//	NVIC_InitStructure.NVIC_IRQChannelPriority = 1;  //先占优先级2级
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
//	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//	//Reset counterTIM_SetCounter(TIM3,0);
//	TIM3->CNT = 0; 两个同一个效果TIM_Cmd(TIM3, ENABLE); 
}

中断代码

void TIM3_IRQHandler(void)
{ 		    		  			    if(TIM3->SR&0X0001)//溢出中断{LED2 = 0;}TIM3->SR&=~(1<<0);//清除中断标志位 	    
}

原理图纸

用的是差分编码器,现在用的程序模拟输出然后接入光耦输入。
光耦信号输出正常,单片机IO口输入也正常,程序可以读取电平信号输入
现在就是不知道到底哪个环节出了问题

编码器差分输入
STM32F030C8T6编码器输入IO口
在这里插入图片描述
STM32F030的TIM3也有挂在APB1总线上,资源也没有问题

尝试了好久,不知道为什么不运行,TIM_GetCounter(TIM3)获取编码器计数值一直是0,有没有遇到此问题的,路过帮忙解决下。
不然只能用中断IO做了

找到原因,开始解决问题

1.TIME3定时器的TI1、TI2没有没有重映射到相关引脚

解决方案

1.设置相关IO口为复用模式,浮空输入。
  不设置复用模式,编码器计数值返回0。

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能GPIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PA6和PA7设置为编码器AB相
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;	//设置为复用模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);

2.设置相关IO 重映射

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6 , GPIO_AF_1); //PA6-->TIM3_CH1
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_1); //PA7-->TIM3_CH2

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
  第一个参数GPIOx: 传入我们要进行映射的GPIO端口,这里使用的是GPIOA。
  第二个参数GPIO_PinSource: 设置要进行重映射的IO口号GPIO_PinSourceX,最后一个X就是对应设置的IO号(0-15),这是使用的是GPIO_PinSource6、GPIO_PinSource7。
  第三个参数GPIO_AF: 也就是下面定义的映射关系,这里重映射的是TIM3找到所对应的就是GPIO_AF_1,那就传入GPIO_AF_1啦。

#define GPIO_AF_0            ((uint8_t)0x00) /* WKUP, EVENTOUT, TIM15, SPI1, TIM17,MCO, SWDAT, SWCLK, TIM14, BOOT,USART1, CEC, IR_OUT, SPI2 */                   
#define GPIO_AF_1            ((uint8_t)0x01) /* USART2, CEC, Tim3, USART1, USART2,EVENTOUT, I2C1, I2C2, TIM15 */                                         
#define GPIO_AF_2            ((uint8_t)0x02) /* TIM2, TIM1, EVENTOUT, TIM16, TIM17 */
#define GPIO_AF_3            ((uint8_t)0x03) /* TS, I2C1, TIM15, EVENTOUT */
#define GPIO_AF_4            ((uint8_t)0x04) /* TIM14 */
#define GPIO_AF_5            ((uint8_t)0x05) /* TIM16, TIM17 */
#define GPIO_AF_6            ((uint8_t)0x06) /* EVENTOUT */
#define GPIO_AF_7            ((uint8_t)0x07) /* COMP1 OUT and COMP2 OUT */

注意一定不要写成,不然还是不会正常工作,只会计数一次

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6 | GPIO_PinSource7 , GPIO_AF_1);

这篇关于STM32F030编码器模式不能正常工作,STM32F103上面可以正常运行 解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/253950

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

SpringBoot集成LiteFlow工作流引擎的完整指南

《SpringBoot集成LiteFlow工作流引擎的完整指南》LiteFlow作为一款国产轻量级规则引擎/流程引擎,以其零学习成本、高可扩展性和极致性能成为微服务架构下的理想选择,本文将详细讲解Sp... 目录一、LiteFlow核心优势二、SpringBoot集成实战三、高级特性应用1. 异步并行执行2

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM