OpenEdv-开源电子网

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

TIM3设置为编码器接口读不回正确数据

[复制链接]

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
发表于 2016-5-4 09:52:04 | 显示全部楼层 |阅读模式
1金钱
我将TIM3设置为编码器接口模式后;用TIM1设置为PWM输出模式控制小直流电机;用光电码盘连接TIM3的编码器接口,用液晶显示读回的参数;用TIM6设置为普通定时功能,定期读回TIM3的数据,但读回的数据却不是真实的数据。下面是我的部分程序:1、TIM3 的初始化程序:void TIM3_Configuration(void)//编码器接口设置(TIM3)/PA6-A相  PA7-B相{
        //定义需要定义的结构体
  GPIO_InitTypeDef        GPIO_InitStructure;                              //定义端口设置结构体
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;                   //定义定时器时钟设置结构体
  TIM_ICInitTypeDef       TIM_ICInitStructure;                            //定义PWM设置结构体
       
        //第一步:配置时钟       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);            //使能A端口时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,  ENABLE);            //使能定时器3时钟
       
        //第二步:配置GPIO端口
       
        GPIO_StructInit(&GPIO_InitStructure);//将GPIO_InitStruct中的参数按缺省值输入
       
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;          //配置应引脚:PC6、PC7
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //配置速度50MHz
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;            //配置上拉输入      
  GPIO_Init(GPIOA, &GPIO_InitStructure);                            //根据配置初始化相应的GPIO引脚
        GPIO_WriteBit(GPIOA, GPIO_Pin_6, Bit_SET);                        //PA6置1
        GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);                        //PA7置1
       
        //第三步:配置定时器基本设置  
       
        TIM_DeInit(TIM3);
        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
       
        TIM_TimeBaseStructure.TIM_Period        = PWMPeriod;              //配置重载值
        TIM_TimeBaseStructure.TIM_Prescaler     = 0;                      //配置预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;           //设置时钟分割 T_dts = T_ck_int
        TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;     //配置向上计数
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                   //根据配置初始化定时器3
       
        //第四步:设置定时器3为编码器模式  IT1 IT2为上升沿计数
        TIM_EncoderInterfaceConfig(TIM3,                                  //配置定时器3编码界面、选择模式3、上升沿计数
                                   TIM_EncoderMode_TI12,                  //
                                                                                                                 TIM_ICPolarity_BothEdge,               //
                                                                                                                 TIM_ICPolarity_BothEdge);              //
        TIM_ICStructInit(&TIM_ICInitStructure);                           //把TIM_ICStructInit中的 每一个参数按缺省值填入
  TIM_ICInitStructure.TIM_ICFilter = 6;                             //输入滤波器
  TIM_ICInit(TIM3, &TIM_ICInitStructure);                           //初始化定时器3
  TIM_ClearFlag(TIM3, TIM_FLAG_Update);                             //清除所有标志位
  TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);                        //允许中断更新
        TIM_SetCounter(TIM3, 0);                                          //清除计数器值       
        TIM_Cmd(TIM3, ENABLE);                                            //使能定时器3
}
2、TIM6的中断服务函数:
//定时器6中断服务函数
void TIM6_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)               //检查指定的TIM中断发生与否:TIM 中断源(P253/368)
        {
                s32 CNT2, CNT3, CNT4, CNT2_last = 0, CNT3_last = 0, CNT4_last = 0, m;
               
                TIM_ClearITPendingBit(TIM6, TIM_IT_Update);                   //清除TIMx的中断待处理位:TIM 中断源
                CNT3 = TIM_GetCounter(TIM3);
                                               
                if(CNT3 >=  CNT3_last) spv1 = CNT3 - CNT3_last;
          else spv1 = PWMPeriod + CNT3 - CNT3_last;
          CNT3_last = CNT3;
                LED0 = !LED0;
        }
}
3、spv1送液晶显示。
不知道是哪里出来问题,读回的数是0


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

使用道具 举报

2

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2015-6-18
在线时间
7 小时
发表于 2016-5-4 11:35:30 | 显示全部楼层
tim1和tim6的使能和初始化没看到
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-5-4
在线时间
1 小时
发表于 2016-5-4 15:02:56 | 显示全部楼层
你的编码器用的是什么型号?集电极开路形式的么?
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:02:59 | 显示全部楼层
TIM1的设置:
void TIM1_Configuration(void)//TIM1四通道分别输出PWM1/PWM2/PWM3/PWM4,对应引脚为PA8、PA11
{
        //定义需要定义的结构体
  GPIO_InitTypeDef GPIO_InitStructure;                              //定义端口设置结构体
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;                    //定义定时器时钟设置结构体
  TIM_OCInitTypeDef TIM_OCInitStructure;                            //定义PWM设置结构体
       
        //第一步:配置时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);             //使能A端口时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);              //使能定时器1时钟
       
        //第二步:配置GPIO端口
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11;           //配置应引脚:PA8、PA11
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //配置速度50MHz
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;                  //配置复用功能,复用满负载输出为3.3V      
  GPIO_Init(GPIOA, &GPIO_InitStructure);                            //根据配置初始化相应的GPIO引脚
  
  //第三步:配置定时器基本设置  
        TIM_TimeBaseStructure.TIM_Period        = PWMPeriod;              //配置重载值
        TIM_TimeBaseStructure.TIM_Prescaler     = 0;                      //配置预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;                      //配置时钟分割(采样分频)
        TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;     //配置向上计数
        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                  //周期寄存器,用于自动更新pwm占空比
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);                   //根据配置初始化定时器1
       
        //第四步:PWM输出配置
        TIM_OCInitStructure.TIM_OCMode       = TIM_OCMode_PWM2;           //配置输出模式为PWM2
        TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Enable;    //配置比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity   = TIM_OCPolarity_Low;        //配置输出极性为低
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;  //配置不使能互补输出
  TIM_OCInitStructure.TIM_OCNPolarity  = TIM_OCNPolarity_High;      //配置互补输出极性为高
        TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCIdleState_Set;       //配置输出空闲状态
        TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;     //配置互补输出空闲状态

        TIM_OC1Init(TIM1, &TIM_OCInitStructure);                          //根据配置初始化定时器1比较通道1初始化
        TIM_OC4Init(TIM1, &TIM_OCInitStructure);                          //根据配置初始化定时器1比较通道4初始化
       
        TIM_SetCompare1(TIM1,0);                                          //赋比较寄存器初值,PA8  上理论能输出0.33V电压  误差0.1V
        TIM_SetCompare4(TIM1,0);                                          //赋比较寄存器初值,PA11 上理论能输出0.33V电压  误差0.1V
       
  TIM_CtrlPWMOutputs(TIM1, ENABLE);                                        //使能定时器1主输出
        TIM_Cmd(TIM1, ENABLE);                                            //使能定时器1外设
}
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:03:46 | 显示全部楼层
TIM6的设置:
void TIM6_Configuration(void)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;                   //定义定时器时钟设置结构体
   
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);              //使能定时器6时钟

   TIM_TimeBaseStructure.TIM_Period        = 1000-1;                 //配置重载值
   TIM_TimeBaseStructure.TIM_Prescaler     = 7200-1;                   //配置预分频值
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;                      //配置时钟分割(采样分频)
   TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;     //配置向上计数
   TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure);                    //根据配置初始化定时器6
   
   TIM_UpdateRequestConfig(TIM6,TIM_UpdateSource_Global);            //更新请求源(生成重复的脉冲:在更新事件时计数器不停止)
   TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);                          //允许中断更新
   TIM_Cmd(TIM6,ENABLE);                                             //使能定时器6
}
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:07:02 | 显示全部楼层
中断设置:
void UserNVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;                      //定义配置中断结构体

   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                       //中断分组2 两位抢占(0-3)  两位响应(0-3)

   //*****************************************************

   NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;           //定时器3全局中断                  
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //响应优先级1
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能定时器中断
   NVIC_Init(&NVIC_InitStructure);                           //根据以上配置初始化定时器中断优先级

   //*******************************************************

   NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;                  //定时器6全局中断
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级2
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //响应优先级0
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能定时器中断
   NVIC_Init(&NVIC_InitStructure);                           //根据以上配置初始化定时器中断优先级
}
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:21:28 | 显示全部楼层
PWM驱动是网上买的L9110,买了两块,只用了1/4;直流电机是CD机光头组件中光盘驱动电机,编码器是网上买的ITR9606传感器 ITR9606-F 槽型光耦;
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:23:56 | 显示全部楼层
这是驱动组件

图片

图片
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-4 16:26:21 | 显示全部楼层
码盘是从旧鼠标拆卸下的光栅改制的。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-5-4 21:13:51 | 显示全部楼层
帮顶
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-8 06:10:46 | 显示全部楼层
大家都没有空啊。
回复

使用道具 举报

8

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
156
金钱
156
注册时间
2012-12-22
在线时间
65 小时
发表于 2016-5-21 14:50:24 | 显示全部楼层
你先确定下你的这个码盘有没有问题~!
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2016-4-27
在线时间
10 小时
发表于 2016-5-22 20:36:34 | 显示全部楼层

不知楼主成功了没有
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2016-4-27
在线时间
10 小时
发表于 2016-5-22 21:54:07 | 显示全部楼层
定时器6中断服务函数中的         CNT3_last = CNT3; 表示什么
回复

使用道具 举报

5

主题

184

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1050
金钱
1050
注册时间
2016-5-13
在线时间
111 小时
发表于 2016-5-23 09:31:37 | 显示全部楼层
PA6 和PA7 用在TIM3是复用功能。
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-29 08:12:28 | 显示全部楼层
我用示波器看编码器输出波形正常。
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-29 08:37:52 | 显示全部楼层
裴宇758 发表于 2016-5-22 21:54
定时器6中断服务函数中的         CNT3_last = CNT3; 表示什么

保存当前值为下次计算用
回复

使用道具 举报

3

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
371
金钱
371
注册时间
2015-6-23
在线时间
112 小时
 楼主| 发表于 2016-5-29 08:42:43 | 显示全部楼层
zhuifeng8911 发表于 2016-5-23 09:31
PA6 和PA7 用在TIM3是复用功能。

没有考虑这个问题,我现在还没有成功,因为我忙其他东西了,谢谢大侠帮我找到一个问题,我会努力验证这个问题,另外定时器分频也是要考虑的,因为个人定义的宏不一样。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-12 07:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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