OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6961|回复: 19

F429的,通过HAL函数配置编码器,使用编码器模式,准确判断圈数(正负)。通过串口打印。

[复制链接]

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2017-10-17
在线时间
18 小时
发表于 2018-3-24 13:23:22 | 显示全部楼层 |阅读模式
最近在调编码器,网上的大多没有F429 的HAL例程,并且没有圈数的准确计算。此例程在其他的基础上进行编码器圈数的准确计算。圈数通过串口打印小数形式。
欢迎大家讨论!
附件上传不了???
主要是main和timer 。我贴出来吧!


#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "timer.h"
/************************************************
ALIENTEK 阿波罗STM32F429开发板实验7
定时器中断实验-HAL库函数版
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/
/************************************************
A、B 相的接PD12 和PD13 ,由于编码器能正反转,具体的接法看实际需求
这里只是一个编码器例程,其他需要只需要在配置几个定时器和引脚即可使用
************************************************/

int main(void)
{
        HAL_Init();                     //初始化HAL库
        Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
        delay_init(180);                //初始化延时函数
        uart_init(9600);              //初始化USART
        LED_Init();                     //初始化LED
        KEY_Init();                     //初始化按键
        TIM4_Init(2000,3);       //定时器3初始化,定时器时钟为60M
        Interupt_Num=0 ;
        Pulse_Num =0 ;
        Circle_NUm =0;
        while(1)
        {
                Circle_Print();
                delay_ms(100);
                LED0 = !LED0;
        }
}



/////////////////////////////////////////timer.h///////////////////////////////////////////////////////////////////////////////
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//定时器驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        
extern TIM_HandleTypeDef TIM3_Handler;      //定时器句柄
extern TIM_Encoder_InitTypeDef Code_Config;
extern TIM_MasterConfigTypeDef Master_Config;

extern long Interupt_Num ;         //因为编码器配置的定时器数值溢出进入中断次数
extern long Pulse_Num ;                 //计算得到的所有的脉冲数
extern float Circle_NUm ;          //计算得到的所有圈数,有正负之分

void TIM4_Init(u16 arr,u16 psc);
void Circle_Print();
#endif


/////////////////////////////////////////timer.c///////////////////////////////////////////////////////////////////////////////
#include "timer.h"
#include "led.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//定时器中断驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        

TIM_HandleTypeDef TIM4_Handler;      //定时器句柄
TIM_Encoder_InitTypeDef TIM4_Encoder_Handler;

//通用定时器3中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!(定时器3挂在APB1上,时钟为HCLK/2)

long Interupt_Num=0 ;
long Pulse_Num =0 ;
float Circle_NUm =0;  

void TIM4_Init(u16 arr,u16 psc)
{  
        TIM4_Handler.Instance=TIM4;
        TIM4_Handler.Init.Prescaler=psc;                     //分频系数
        TIM4_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
        TIM4_Handler.Init.Period=arr;                        //自动装载值
        TIM4_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频银子
       
        //HAL_TIM_Base_Init(&TIM4_Handler);        //HAL_TIM_OC_Init(&TIM4_Handler);
        //不要用这句话,他是基本定时器的设置,这里使用了编码器模式,没必要配置
       
        TIM4_Encoder_Handler.EncoderMode=TIM_ENCODERMODE_TI12;
        TIM4_Encoder_Handler.IC1Filter=0;
        TIM4_Encoder_Handler.IC1Polarity=TIM_ICPOLARITY_RISING;
        TIM4_Encoder_Handler.IC1Prescaler=TIM_ICPSC_DIV1;
        TIM4_Encoder_Handler.IC1Selection=TIM_ICSELECTION_DIRECTTI;
               
        TIM4_Encoder_Handler.IC2Filter=0;
        TIM4_Encoder_Handler.IC2Polarity=TIM_ICPOLARITY_RISING;
        TIM4_Encoder_Handler.IC2Selection=TIM_ICSELECTION_DIRECTTI;
        TIM4_Encoder_Handler.IC2Prescaler=TIM_ICPSC_DIV1;
        HAL_TIM_Encoder_Init(&TIM4_Handler,&TIM4_Encoder_Handler);
       
        HAL_TIM_Encoder_Start(&TIM4_Handler,TIM_CHANNEL_ALL);
        HAL_TIM_Encoder_Start_IT(&TIM4_Handler,TIM_CHANNEL_ALL);//开启中断
        TIM4->CNT=1000;
    __HAL_TIM_ENABLE_IT(&TIM4_Handler,TIM_IT_UPDATE);   //使能更新中断
    __HAL_TIM_ENABLE(&TIM4_Handler);

}

void TIM4_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM4_Handler);
}

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
{   
        GPIO_InitTypeDef GPIO_Initure;
        if(htim->Instance==TIM4)
  {
    __HAL_RCC_TIM4_CLK_ENABLE();            //使能TIM4时钟
        HAL_NVIC_SetPriority(TIM4_IRQn,1,3);    //设置中断优先级,抢占优先级1,子优先级3
        HAL_NVIC_EnableIRQ(TIM4_IRQn);          //开启ITM4中断   
        HAL_TIM_Base_Start_IT(&TIM4_Handler); //使能定时器4和定时器4更新中断:TIM_IT_UPDATE   

    __HAL_RCC_GPIOD_CLK_ENABLE();                        //开启GPIOD时钟          
    GPIO_Initure.Pin=GPIO_PIN_12|GPIO_PIN_13;         
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;      //输入
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Alternate=GPIO_AF2_TIM4;   
    HAL_GPIO_Init(GPIOD,&GPIO_Initure);
        }       
}

//回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

        if(htim==(&TIM4_Handler))
        {
                LED1 = !LED1 ;
                if ( (TIM4->CR1&0x0010) == 0 )  //向上计数溢出
                {
                        Interupt_Num++ ;
                }
                else //向下计数溢出
                {
                        Interupt_Num-- ;
                }               
        }
}

void Circle_Print()
{
        if (Interupt_Num ==0 )                        //CNT从1000开始,刚开始的时候计算脉冲的方法
                Pulse_Num = TIM4->CNT-1000 ;
        else
        {  
                Pulse_Num = 1000 + (Interupt_Num - 1) *2000 +TIM4->CNT ; //在第一圈完成之后,计算脉冲数多的方法
        }
        Circle_NUm =  Pulse_Num/1000.0f                ;                 //所有人脉冲除以细分数就可以得到转的圈数(正负之分)
        printf("Interupt_Num的值是:%ld--捕获到的总数是%ld*****转过的圈数是%f\r\n" , Interupt_Num, Pulse_Num , Circle_NUm );
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2017-10-17
在线时间
18 小时
 楼主| 发表于 2018-3-24 13:27:50 | 显示全部楼层
每个人都尽力帮助别人,共同营造一个好的网络学习环境
回复 支持 1 反对 0

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2017-10-17
在线时间
18 小时
 楼主| 发表于 2018-4-9 18:09:08 | 显示全部楼层
今天发现能上传了

F429编码器例程.zip

10 MB, 下载次数: 908

回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2018-4-11
在线时间
1 小时
发表于 2018-4-11 09:32:47 | 显示全部楼层
你好 能加一下你的qq么   有一些问题想请教你。
回复 支持 反对

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2017-10-17
在线时间
18 小时
 楼主| 发表于 2018-4-13 20:14:52 | 显示全部楼层
路人戊5 发表于 2018-4-11 09:32
你好 能加一下你的qq么   有一些问题想请教你。

好吧,3539199611
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2018-7-26
在线时间
24 小时
发表于 2018-11-12 14:49:17 | 显示全部楼层
学习学习,谢谢分享
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2019-4-21
在线时间
17 小时
发表于 2019-7-3 21:29:51 | 显示全部楼层
楼主好人!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-7-17
在线时间
11 小时
发表于 2019-7-16 09:40:30 | 显示全部楼层
万分感谢
回复 支持 反对

使用道具 举报

3

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2019-3-31
在线时间
17 小时
发表于 2019-7-31 20:12:36 | 显示全部楼层
想问一下楼主,用的编码器是5线还是8线的
回复 支持 反对

使用道具 举报

3

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2019-3-31
在线时间
17 小时
发表于 2019-7-31 23:48:01 | 显示全部楼层
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

        if(htim==(&TIM4_Handler))
        {
                LED1 = !LED1 ;
                if ( (TIM4->CR1&0x0010) == 0 )  //向上计数溢出
                {
                        Interupt_Num++ ;
                }
                else //向下计数溢出
                {
                        Interupt_Num-- ;
                }               
        }
}
中断处理为什么要这样做。每中断一次就判断一次,定时器一直都是向上计数的,所以我觉得CR1的值一直都是0x0001。条件一直成立,Interupt_Num会一直加。楼主可以解释一下吗
回复 支持 反对

使用道具 举报

3

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2019-3-31
在线时间
17 小时
发表于 2019-8-1 09:48:05 | 显示全部楼层
TiramisuL 发表于 2019-7-31 23:48
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

编码器模式是上下计数的。我知道了
回复 支持 反对

使用道具 举报

0

主题

131

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2019-7-1
在线时间
6 小时
发表于 2019-8-1 13:49:50 | 显示全部楼层
收藏学习
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2019-8-12
在线时间
24 小时
发表于 2019-9-13 10:46:58 | 显示全部楼层
学学习学习<**>
回复 支持 反对

使用道具 举报

2

主题

474

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6414
金钱
6414
注册时间
2018-6-27
在线时间
543 小时
发表于 2019-9-16 10:59:17 | 显示全部楼层
谢谢分享,学习学习。
回复 支持 反对

使用道具 举报

16

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
290
金钱
290
注册时间
2019-9-4
在线时间
52 小时
发表于 2019-9-28 16:46:42 | 显示全部楼层
两个直流电机,使能位接在了一起,用于PWM的输出来改变速度,使用按键控制
电机二的编码器接在PD12 PD13上。
当电机通电后,电机正常运作,但是每当电机二转过4圈左右,电机一会暂停,然后重新转动。
楼主知道是为什么吗

回复 支持 反对

使用道具 举报

16

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
290
金钱
290
注册时间
2019-9-4
在线时间
52 小时
发表于 2020-1-10 19:40:17 | 显示全部楼层
邵茂峰 发表于 2019-9-28 16:46
两个直流电机,使能位接在了一起,用于PWM的输出来改变速度,使用按键控制
电机二的编码器接在PD12 PD13上 ...

唔  好久之前的错误了,我当时的PB1接的是电机,而回调函数里 有一句PB1!=PB1,所以才会停止。
回复 支持 反对

使用道具 举报

16

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
290
金钱
290
注册时间
2019-9-4
在线时间
52 小时
发表于 2020-1-10 19:40:58 | 显示全部楼层
最近复习编码器,再来看看
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2020-2-6
在线时间
1 小时
发表于 2020-2-6 12:24:10 | 显示全部楼层
我用的学习板是H7的,初始化TIM4_Init(0xFFFF,200-1)时,电机只要转动一点点,数值5000+变化,数值是不对的,这是为什么
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2020-7-7
在线时间
14 小时
发表于 2020-7-23 22:17:03 | 显示全部楼层
太感谢楼主了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 19:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表