OpenEdv-开源电子网

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

stm32 定时器中断和io控制问题

[复制链接]

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
发表于 2014-4-8 14:38:00 | 显示全部楼层 |阅读模式
硬件连接PB5为高电平点亮led
要实现的功能,定时器3定时1s,中断函数中对led取反,读取脉冲计数值。
结果仿真发现LED_Init()初始化后点亮led,持续大约0.6ms后变为低电平。如图3


具体函数如下
main函数
int main(void)
u8 i=0; 
u8 *s=tab;
RCC_Configuration();   
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 
GPIO_Configuration();
LED_Init();//PB5指示灯
//LCD_init(); //lcd初始化    
//LCD_prints(1,0,s); //lcd第一行输出Lcd Test!
TIM1_Configuration();    //TIM1对PA12输入脉冲计数
TIM2_Configuration();   //TIM2对PA0输入脉冲计数
TIM3_Int_Init(10000-1,7200-1);//10Khz的计数频率,计数到10000为1s
//TIM3_Int_Init(2000-1,72-1);//1M的计数频率,计数到2000为2ms
   while(1)
 {
      for(i = 0; i < 4; i ++) // 软件延时产生pwm,tim1 正常计数
  {  //
  GPIO_SetBits(GPIOE, GPIO_Pin_5);  //200us
  Delay(1000);      //
  GPIO_ResetBits(GPIOE, GPIO_Pin_5);  //
  Delay(1000);
  }    //                                         
  }
}
Led初始化函数
void LED_Init(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);//使能PB,PE端口时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->B.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
 GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;     //LED1-->E.5 端口配置, 推挽输出
 GPIO_Init(GPIOE, &GPIO_InitStructure);   //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 
}

中断函数
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
// LED0=!LED0;  ///
counter=TIM_GetCounter(TIM2);   //
LCD_dispnum(counter);
TIM_SetCounter(TIM1, 0);
TIM_Cmd(TIM3, DISABLE);  //使能TIMx
}
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-8 14:59:22 | 显示全部楼层
定时器初始化后,会进入一次中断,这个你得剔除。
或者你多仿真一下,看多几个波形。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-8 15:09:36 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
这么说第一次中断读取的脉冲计数值也不准确。该怎么剔除了?
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-8 15:13:25 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
老师,为什么会这样了?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-8 17:00:02 | 显示全部楼层
回复【3楼】fangxiaoyanzhou:
---------------------------------
程序做处理,等待一点时间,再去开启脉冲计数,或者第一次计数丢弃。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-11 19:09:39 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
现在处理时没有记第一次的数值。加入pwm-off、tim1\tim2的配置后,定时器tim4初始化后pb0\pb1同样又被拉低,如图2


老师,step over时到tim4时,引脚变成了低电平。。去掉tim4初始化,得到图5,


中断对其他的引脚貌似有影响,这在哪可以找到资料了?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 00:04:13 | 显示全部楼层
回复【6楼】fangxiaoyanzhou:
---------------------------------
看你在定时器初始化里面做了什么事情了。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-12 09:17:11 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
tim4初始化配置定时参数,中断服务里tim2计数器的值,并显示出来
void TIM4_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

//定时器TIM4初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位  //////tim3
 
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

TIM_Cmd(TIM4, ENABLE);  //使能TIMx  
}
//定时器4中断服务程序
void TIM4_IRQHandler(void)   //TIM4中断
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中断标志 
counter=TIM_GetCounter(TIM2);   // 读取计数值
LCD_dispnum(counter);
TIM4_Vic(counter);  // 计数值转为速度
LCD_dispnum(Vic);  // 显示速度
TIM_SetCounter(TIM2, 0); //重新计数
}
}
void TIM4_Vic(u16 counter)
{
 Vic=60*counter/Pmo;
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 10:12:01 | 显示全部楼层
定时器没问题,怀疑问题出在:LCD_dispnum函数里面。
你最好可以单步跟踪调试下代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-12 10:27:14 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
刚看了这个显示函数的管脚定义如下
#define LCD_RS_1 GPIOD->BSRR=GPIO_Pin_10 //PD.10--(LCD)RS
#define LCD_RS_0 GPIOD->BRR =GPIO_Pin_10
#define LCD_RW_1 GPIOD->BSRR=GPIO_Pin_9//PD.9--(LCD)RW
#define LCD_RW_0 GPIOD->BRR =GPIO_Pin_9
#define LCD_EN_1 GPIOD->BSRR=GPIO_Pin_8//PD.8--(LCD)E
#define LCD_EN_0 GPIOD->BRR =GPIO_Pin_8
#define DATAOUT  GPIOB->ODR             //PB[8..15]--(LCD)D0~D7
显示初始化的时候
void LCD_ini_cmd(u8 cmd)
{
    LCD_RS_0;        //GPIOD->BRR = LCD_RS;
    delay_nus(1);   
    LCD_RW_0;       // GPIOD->BRR = LCD_RW;
    delay_nus(1);   
    LCD_EN_0;        //GPIOD->BRR = LCD_EN;
    delay_nus(300);
    DATAOUT = 0XFF00 & (cmd << 8);//看数据线接的是高8位,还是低8位,要做出更改
//    LCD_EN_1;
    delay_nus(300);   
    LCD_EN_1;        //GPIOC->BSRR = LCD_EN;
    delay_nus(300);   // GPIOC->BRR = LCD_EN;
    LCD_EN_0;
delay_nus(100);
}
影响了输出。。想想怎么不让他们冲突。。

回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-12 10:45:52 | 显示全部楼层


回复【9楼】正点原子:
---------------------------------
老师,发现了另外一个奇怪的问题。。systick计数总是不产生计数完成标志。跳不出循环圈。。怎么查看systick_val的值了?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 20:34:30 | 显示全部楼层
回复【11楼】fangxiaoyanzhou:
---------------------------------
你在延时之后,设置一个断点,直接运行到断点处,试试。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-12 20:58:51 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
在延时函数里面断点的情况如图1.



在调用延时函数里面设置断点情况如图2.


直接出了循环,计数完成时读取标志位,标志位应该是清0了啊

回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-12 21:11:26 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
老师,软件调试的基本思路是什么?每次不知道错在哪里?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 23:29:23 | 显示全部楼层
回复【14楼】fangxiaoyanzhou:
---------------------------------
说明你的延时函数可以运行...
仿真器跟踪是最好调试的了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-13 15:39:00 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
恩,清白了,3q。。
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2014-4-19 11:16:10 | 显示全部楼层
回复【13楼】fangxiaoyanzhou:
---------------------------------
http://www.openedv.com/posts/list/24557.htm,楼主这篇帖子可能有用。
最近也遇到过这样的问题,特别是硬件仿真的时候。在Keil MDK 硬件仿真,观察定时器的SR寄存器,peripherals,总感觉与理解的不一样,不知楼主是佛遇到过这种情况。
http://www.openedv.com/posts/list/31002.htm,4楼有描述。
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-22 16:43:23 | 显示全部楼层
回复【17楼】BULELJ:
---------------------------------
怎么查看寄存器?我一般直接看变量值。。
回复 支持 反对

使用道具 举报

10

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2012-12-27
在线时间
0 小时
发表于 2014-4-23 16:48:11 | 显示全部楼层
Keil MDK工具栏上,有个peripherals,点进去就可以查看各个模块的寄存器了,硬件和软件仿真都查看可以。
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2014-3-5
在线时间
0 小时
 楼主| 发表于 2014-4-24 15:28:03 | 显示全部楼层
回复【19楼】BULELJ:
---------------------------------
谢楼主。。正用上了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-10 03:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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