OpenEdv-开源电子网

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

STM32+编码器相关的问题(Timer3)

[复制链接]

29

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2015-4-26
在线时间
5 小时
发表于 2015-7-21 22:47:51 | 显示全部楼层 |阅读模式
5金钱
最近开始做智能小车相关项目,需要测试小车行走时两电动机的速度,来控制小车的走向。
我用STM32+L298N电机驱动板,后来又在淘宝上买了两个光偶装在两电机旁边的木质轮子上(20个空槽),从而组成一个类似光电开关的传感器,之后硬件调试完全OK,在示波器上可以清晰的看到左右轮子的方波,结果显示一个轮子的频率大概在90hz左右,而另一个轮子的频率只有70hz,那么确定电机转速的确是有问题的。于是我就开始了小车测速方面的驱动调试(代码主要是各位大神的)

先上timer3相关代码
#include "encoder.h"
#include "stm32f10x.h"
[mw_shl_code=c,true]extern u16 v_counter; extern float v; #define TIMx_PRE_EMPTION_PRIORITY 0 //2 #define TIMx_SUB_PRIORITY 0 #define ENCODER_TIMER TIM3 // Encoder unit connected to TIM3 #define ENCODER_PPR (u16)(1000) // number of pulses per revolution #define ICx_FILTER (u8) 6 // 6<-> 670nsec #define COUNTER_RESET (u16)0 #define U16_MAX ((u16)65535u) static volatile u16 hEncoder_Timer_Overflow; void ENC_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Encoder unit connected to TIM3, 4X mode */ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* TIM3 clock source enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM3时钟 /* Enable GPIOA, clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOB时钟 GPIO_StructInit(&GPIO_InitStructure); /* Configure PB.8 as encoder input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 pin6 pin7 /* Enable the TIM4 Update Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM4中断 /*中断一级优先级设置*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY; //先占优先级0级 /*中断二级优先级设置*/ NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY; //从优先级 0级 /*中断使能*/ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 /*中断赋值*/ NVIC_Init(&NVIC_InitStructure); /* Timer configuration in Encoder mode */ TIM_DeInit(ENCODER_TIMER); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); /*不需要任何预分频*/ //Tout=(arr+1)*(psc+1)/Tclk; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; //设定计数器重装值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割 T_dts = T_ck_int TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数 TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure); /*设置为编码器模式*/ TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式4 /*filter设置*/ TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;//选择输入比较滤波器 /*TIM_ICFilter选择输入比较滤波器。该参数取值在0x0和0xF之间*/ TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure); // Clear all pending interrupts TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update); /*开启编码器溢出中断*/ TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE); //Reset counter /*复位编码器*/ TIM3->CNT = COUNTER_RESET; /*使能编码器*/ TIM_Cmd(ENCODER_TIMER, ENABLE); } /******************************************************************************* Timer3的Update中断处理程序 * Function Name : TIM3_IRQHandler * Description : This function handles TIMx Update interrupt request. Encoder unit connected to TIM2 * Input : None * Output : None * Return : None *******************************************************************************/ /*中断溢出处理(测速),这里是网上找的,和我的20格木质...不匹配*/ void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 v_counter=TIM_GetCounter(TIM3); TIM_SetCounter(TIM3, 0); v=(float)v_counter*120/400; //定时为0.5s v_counter=v; } } void TIM_Init(void) { ENC_Init(); } [/mw_shl_code]
主函数
[mw_shl_code=c,true]u16 v=0; u16 v_counter=0; volatile s16 encoder_num; volatile s16 encoder_num1; volatile s16 encoder_num2; //volatile s16 encoder_num; int main(void) { SystemInit(); //系统时钟配置函数通过不同的定义 来选择不同的主频 这里设置是72m LED_GPIO_Init(); //初始化与LED连接的硬件I/O接口 Motor_GPIO_Init(); //初始化与电机连接的硬件I/O接口 /**********************************************************/ TIM_Init(); //定时器初始化,以后集中到一起!!!!!!!!! /**********************************************************/ delay_init(); //延时函数初始化 NVIC_Configuration(); //设置中断优先级分组 uart_init(9600); //串口初始化为9600 while(1) { TIM_SetCompare2(TIM2,0);//定时器2的通道1和2来驱动左右两个电机 [/mw_shl_code] [mw_shl_code=c,true] encoder_num=TIM_GetCounter(TIM3);//定时器3捕捉那个... 算是比较的信号(我也不太懂) printf("\r\nR_编码器计数值为:%d\n",encoder_num); TIM_SetCompare1(TIM2,0);//定时器2的通道1和2来驱动左右两个电机 encoder_num1=TIM_GetCounter(TIM3); printf("\r\nL_编码器计数值为:%d\n",encoder_num1); encoder_num2=TIM_GetCounter(TIM2); printf("\r\ntest_编码器计数值为:%d\n",encoder_num2); } }[/mw_shl_code]
小车(程序运行)后,
encoder_num  ,encoder_num1 数字一个偏大,一个偏小(因为中断处理原因,都小于150)
1.这就算是定时器3的计数值吗?
2.那么我要必出两个小电机的转速不同,该怎么办?
3.还有这两个10进制的数换成二进制形式,是不是我从示波器上扑捉到的那个高低电平,那个平率很快,感觉那个高低电平应该是叠加上去后,才打印出现在这样的十进制数(我的猜测对不对)?

encoder_num2,这个是我心血来潮加上去了,然后得出的结果整个人都凌乱了,有个规律就是一只高,一只低,这该是两个电机不同的频率问题了,可问题是,对于定时器2,关于编码驱动的问题我什么都没做,就出现这样的结果了,(用示波器测量不像测速度那样高低都有,都只能看到高电平)

PS:
还有我看各位一直说编码器的问题,请问编码器是怎么定义的,我的那个小车电机上的两个20格木质转盘+两个光电传感器组成的光电开关(电机转动时,上面的光电传感器会闪烁,这个大家应该都清楚的)算不算编码器?这个网上居然搜索不到,又不想糊糊涂涂项目做完还不知道,所以就确定一下。

由于这方面是第一次搞,加上接触的时间不多,所以求各位大神帮忙解答一下疑惑,谢了!

















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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-21 23:30:55 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

29

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2015-4-26
在线时间
5 小时
 楼主| 发表于 2015-7-22 08:15:05 | 显示全部楼层
有人吗?求指导
回复

使用道具 举报

29

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2015-4-26
在线时间
5 小时
 楼主| 发表于 2015-7-25 19:46:55 | 显示全部楼层
来个个拉~~
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 11:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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