关于STM32的编码器计数及溢出处理调试总结

发布者:心想的45号最新更新时间:2018-09-16 来源: eefocus关键字:STM32  编码器  计数  溢出处理 手机看文章 扫描二维码
随时随地手机看文章

错误1、pc6 pc7被用作其他用途,GPIO模式配置错误。导致计数不准确;

错误2、引脚模式设置错误,应该设置为GPIO_Mode_IPD;//GPIO_Mode_IPU GPIO_Mode_IN_FLOATING  都可以;

错误3  引脚重映射没有开启AFIO时钟;

总结

关于编码器的溢出处理:

网上的检测数值突变的方法不可靠,会有漏检的情况。在滴答定时器中检测encoder的值突变

void SysTick_Handler(void)

{// systick中断,1ms一次

 static int encoder[2] = {0 , 0};// 两次编码器读值,用以计算溢出方向

 static int N = 0;// 圈数

 encoder[1] = TIM3->CNT;

  if((encoder[1] - encoder[0] ) > 0x7FFF)

  {

    N--;

  }

 else if( (encoder[0] - encoder[1] ) > 0x7FFF)

  {

   N++;

  }

 EncCnt = N * 0xFFFF + encoder[1];

 encoder[0] = encoder[1];

}

 

我采用了两种方法处理:一种是采用另一个定时器实时的检测溢出标志及方向标志,这种方法是可行的。即使速度很快的时候依然计数准确。但是出现了新的问题,用作定时器的时钟,当定时周期设置的很小的时候才可以计数准确,但是由于中断的优先级高,导致无法进入主循环程序。附上检测代码。这样的处理方法,在速度慢的时候可以检测正确。但是定时周期要设置足够小。CR1的bit4代表计数方向标志,1代表减二代表加;SR的bit0代表溢出中断标志,1代表溢出。该位是硬件置1软件清零。另一种是使用编码器溢出中断。中断的时候对编码器溢出方向进行判断,然后根据方向进行累加。

void TIM2_IRQHandler(void)

{

      

   if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )

    {

       TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);

                           

              encoder= TIM3->CNT;

          if((TIM3->CR1&0x10) == 0x10)//向下计数

          {          

               if(TIM3->SR&0x01 == 0x01)//tim3计数溢出

                 {

                            TIM3->SR= TIM3->SR&0xFE;//sr的bit0清零

                            N--;

                     }                    

          }

          else if((TIM3->CR1&0x10) == 0x00)//向上计数

          {

               if(TIM3->SR&0x01 == 0x01)//tim3计数溢出

                 {

                            TIM3->SR= TIM3->SR&0xFE;//sr的bit0清零

                            N++;

                     }                   

          }

              EncCnt= N * 65536 + TIM3->CNT;  

          //        encoder[0] = encoder[1];

       }                

      

}

 

最后,我找到了更简单的检测编码器溢出中断并进行累计的方法。

其实当编码器的定时器溢出的时候,会导致进入中断。这样直接用编码器的中断函数即可。但是需要注意的是,需要在编码器的定时器配置的时候,配置中断。如果不配置,就会导致程序一运行就死机。一直停在DMA2_Channel4_5_IRQHandler这一句。

附上最终测试验证完成的代码

编码器初始化配置 ( 注意。如果不适用中断溢出的方法,无需配置

NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

这部分。。。)

并且我适用的是tim3重定义到pc7  pc6的。也可以使用部分重映射和默认引脚。

void EncoderTimInit()

{

//     对TIM_ICInitStructure的配置和对TIM_EncoderInterfaceConfig函数的使用实际上是冲突的,两个语句中的极性的设置是重复的

       //--------------1

       GPIO_InitTypeDefGPIO_InitStructure;

   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

   TIM_ICInitTypeDef TIM_ICInitStructure;

   NVIC_InitTypeDef NVIC_InitStructure;

      

      

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM3时钟

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIOC时钟

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  //AFIO时钟

      

       GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);       //TIM选择全复用功能使能

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//PC6 PC7浮空输入

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//GPIO_Mode_IPU  GPIO_Mode_IN_FLOATING

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOC,&GPIO_InitStructure);

      

      

       TIM_DeInit(TIM3);       //TIM3初始化

   /* Timer configuration in Encoder mode */

   TIM_TimeBaseStructure.TIM_Prescaler = 0; // 不分频

   TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM3_PERIOD-1;  //计数40000  定时 T = 1/72000000 *40000 S=  1/1.8ms

   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分频系数:不分频

   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式

   TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

      

//     //编码配置                        编码模式   

   TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //TIM_ICPolarity_Rising上升沿捕获

   TIM_ICStructInit(&TIM_ICInitStructure);       //输入捕获模式配置为硬件默认值

   TIM_ICInitStructure.TIM_ICFilter = 0x06;//ICx_FILTER;  //比较滤波器

   TIM_ICInit(TIM3, &TIM_ICInitStructure);//调用库函数把配置信息填充进去

 

   NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

 

//     TIM_ARRPreloadConfig(TIM3,ENABLE);

//     TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Disable);

 

       //Clear all pending interrupts

//     TIM_SetAutoreload(TIM3,0xffff);

       TIM_ClearFlag(TIM3,TIM_FLAG_Update);//清除TIM3的更新标志位

       TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能中断                                                                                                    

 

   //Reset counter  计数初始值

   TIM3->CNT = 0;

   TIM_Cmd(TIM3, ENABLE);

}

 

编码器计数模块

void TIM3_IRQHandler(void)

{     

       if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)

   {

    TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);

          if((TIM3->CR1&0x10) == 0x10)//向下计数

          {          

                     N--;               

          }

          else if((TIM3->CR1&0x10) == 0x00)//向上计数

          {

                     N++;            

          }

              EncCnt= N * 65536 + TIM3->CNT;        

   }           

}

注: N 和EncCnt变量最好定义为volatile


关键字:STM32  编码器  计数  溢出处理 引用地址:关于STM32的编码器计数及溢出处理调试总结

上一篇:stm32中编码器模式读出“负数”的问题
下一篇:STM32F103之实验2控制1个电机并采用编码器读取电机转速

推荐阅读最新更新时间:2024-03-16 16:14

STM32:DMA实例之串口(USART)通信
硬件平台:stm32f10xZET6 开发环境:keil MDK uVision v4.10 开发语言:C、ST_lib_3.5固件库 /* 代码演示 main.c */ #include stm32f10x.h #include bsp_usart1.h #include bsp_led.h extern uint8_t SendBuff ; static void Delay(__IO u32 nCount); /** * @brief 主函数 */ int main(void) { /* USART1 config 115200 8-N-1 */
[单片机]
STM32的LED灯实验
实验目的: 让我的开发板的LED灯亮灭闪烁 实验程序: /*******************************led.c*********************************/ #include stm32f4xx.h //在SYSTEM目录下可以找到,把ST官方的部分库抽取出来,组成了一个SYSTEM目录 #include sys.h void LED_Init(void){ RCC- AHB1ENR = 1 5; //使能GPIO端口的F时钟 /* 方法一: */ // GPIOF- ODR |= 0x1 9; // GPIOF-
[单片机]
STM32 TIM触发ADC 定时采样-笔记
用TIM3的update触发adc,只需勾选Internal clock就可以了 ADC设置,关键是选TIM3 TRIGGER OUT TIM3 设置时间间隔然后关键选Update event 程序代码 记得开启TIM3 HAL_ADCEx_Calibration_Start(&hadc1); //STM32F1 HAL_TIM_Base_Start(&htim3); HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value,1024); 然后重写callback 函数 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* h
[单片机]
<font color='red'>STM32</font> TIM触发ADC 定时采样-笔记
STM32应用-简单的串口接收与发送程序
简介:与上位机的串口通信是一个很常用的程序。碧海蓝天在刚刚接触stm32芯片时写的第一个简单程序就是串口通信,现在把程序代码甩出来与大家分享。完整的程序哦。 库版本 :ST3.0.0 文件:mian.c //功能:串口初始化、打开定时器中断,然后一直接收数据状态就好了。发送在中断中实现 #include stm32f10x.h #include usart.h u8 USART_rx_data; int main(void) { RCC_Configuration(); //系统时钟配置 GPIO_Configuration(); //端口初始化 NVIC_Configuration();
[单片机]
演示STM32中PWM的配置与应用
打开CubeMX软件,新建工程。 输入芯片型号。 根据封装选择列表中的芯片,我的是LQFP144封装,双击此项。 在Project Manager选项卡中,配置工程名、编译工具,如下图所示。 在Pinout&Configuration选项卡中,配置System的Debug为Serial Wire,否则可能无法下载程序。 RCC选择高速外部时钟。 根据电路原理图,可知LED7对应PC6管脚。 本实验要让PC6管脚输出PWM波形,实现LED7呼吸灯效果。 找到PC6,选中TIM3_CH1。 找到TIM3,通道1配置PWM输出。 查找STM32参考手册时钟图,找到TIM3时钟的位置在APB1上。
[单片机]
演示<font color='red'>STM32</font>中PWM的配置与应用
数字电位器的应用特性分析
   1 引言      SOC(片上系统)和模拟数字混合信号处理技术是现代信息技术应用中的两个重要电子技术基础。     一般来说,纯数字系统的SOC实现技术比较成熟,而模拟-数字混合信号处理系统的SOC实现起来则比较困难,其主要原因就是模拟部分难以实现高度集成。     对于模拟电子系统,由于信号和参数具有连续与分散特征,因此在进行系统集成和数字程控时会遇到比较大的困难。特别是当需要通过调整电阻值来连续调整电路特性时,其困难可能会更大。例如用数字方式调整滤波器截止频率时,就必须对电阻值进行比较精确的连续调整。     为了实现模拟电路参数的程控连续调整,解决混合信号处理中的问题,美国Xicor公司研制出程控电位器,利
[模拟电子]
STM32开发笔记57: 复位电路设计
本篇文章针对所有的STM32芯片,网上有不少文章叙述了有关STM32复位电路的相关内容,也有很多推荐电路,例如ALIENTEK给出的复位电路,如下图所示。 不过还有一些推荐电路,不需加上拉电阻,或者电容也不加,那到底应该如何设计呢?还需看一下官方手册的推荐电路,如下图所示。 可看到,复位电路具有内部上拉电阻,外部只需接0.1uf电容即可,不需在外部电路上拉10K电阻,上拉后只会使上拉电阻变小,减小复位时间,或会导致复位不正常。内部上拉电阻阻值和其它参数如下表所示,供参考。
[单片机]
<font color='red'>STM32</font>开发笔记57: 复位电路设计
STM32定时器中断-库函数
程序要求:通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED实现LED1状态取反 下面给出几个主要文件的程序模板 timer.h: #ifndef __TIMER_H #define __TIMER_H #include sys.h void TIM3_init(u16 arr, u16 psc); #endif timer.c #include timer.h #include led.h //tim的相关函数去stm32f4xx_tim.h中去找 void TIM3_init(u16 arr, u16 psc) { TIM_TimeBaseInitTypeD
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved