OpenEdv-开源电子网

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

用两个外部中断分别计数左右轮编码盘脉冲问题

[复制链接]

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-9-3
在线时间
8 小时
发表于 2014-3-22 10:04:57 | 显示全部楼层 |阅读模式

用外部中断计数编码盘脉冲,当我用一个轮子测试时,应该只会进入到一个中断里,并将相应计数脉冲通过串口传输到PC机,实际上两个中断都进去了。另外我用原子提供的外部中断实验,在两个中断函数里分别添加printf(“。。。。。。”),用一个管脚测试时,实际上也进入到两个中断里,并通过串口都打印出了相应信息。以下程序是编码盘测脉冲的程序,以及串口打印的信息截取如下。望大神指点,不甚感激。

#include "pulsecount.h"
#include "delay.h"
#include "usart.h"

u32 Left_Count,Right_Count;   //左右轮脉冲计数值

//左右轮计数相应管脚PB.0和PB.1初始化及外部中断4,5初始化
void PULSECOUT_Init(void)
{
   EXTI_InitTypeDef EXTI_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟

   //GPIOB.0 中断线以及中断初始化配置   下降沿触发
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);

   EXTI_InitStructure.EXTI_Line = EXTI_Line0; //左轮
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
   EXTI_Init(&EXTI_InitStructure);   //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

  //GPIOB.1 中断线以及中断初始化配置 下降沿触发
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
   EXTI_InitStructure.EXTI_Line=EXTI_Line1;  //右轮
   EXTI_Init(&EXTI_InitStructure);    //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
 
   NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;    //使能左轮计数所在的外部中断通道
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级1,
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;   //子优先级0
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //使能外部中断通道
   NVIC_Init(&NVIC_InitStructure);

   NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;    //使能右轮计数所在的外部中断通道
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级1,
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;   //子优先级1
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //使能外部中断通道
   NVIC_Init(&NVIC_InitStructure);
}

void EXTI0_IRQHandler(void)
{
 printf("The left wheel counting is %d\r\n",Left_Count);
 Left_Count++;
 EXTI_ClearITPendingBit(EXTI_Line0);  //清除LINE0上的中断标志位
}

void EXTI1_IRQHandler(void)
{
 printf("The right wheel counting is %d\r\n",Right_Count);
 Right_Count++;
 EXTI_ClearITPendingBit(EXTI_Line1);  //清除LINE1上的中断标志位  
}

 

QQ截图20140322095604.png
好好学习,天天向上。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2014-3-22 11:25:16 | 显示全部楼层
//初始化PC0,PC1为中断输入.
void EXTIX_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;


   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //关闭JTAG

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//IO口的时钟配置

  //初始化 S2-->GPIOC.0,S3-->GPIOC.1  上拉输入
   GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
   GPIO_Init(GPIOC, &GPIO_InitStructure);

  //按键S2的GPIOC.0      中断线以及中断初始化配置
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource0); //选择相应引脚作为中短线

   EXTI_InitStructure.EXTI_Line=EXTI_Line0;    //配置为外部中断线0
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //配置外部中断线为中断请求
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //下降沿触发
   EXTI_InitStructure.EXTI_LineCmd = ENABLE;  //使能中断
   EXTI_Init(&EXTI_InitStructure);   //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

 //GPIOC.1   中断线以及中断初始化配置
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource1);

   EXTI_InitStructure.EXTI_Line=EXTI_Line1;    //配置为外部中断线0
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //配置外部中断线为中断请求
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
   EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
   EXTI_Init(&EXTI_InitStructure);    //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
/*
  //GPIOA.0   中断线以及中断初始化配置
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

  EXTI_InitStructure.EXTI_Line=EXTI_Line0;  //配置为外部中断线0
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //配置外部中断线为中断请求
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
   EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
   EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

  */
   NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能按键S3所在的外部中断通道
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, 
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
   NVIC_Init(&NVIC_InitStructure); 
  
   NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键S2所在的外部中断通道
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2 
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2 
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
   NVIC_Init(&NVIC_InitStructure);     //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}

 
void EXTI0_IRQHandler(void)
{
    delay_ms(10);     //消抖
   if(EXTI_GetITStatus(EXTI_Line0) != RESET)   //检查指定的EXT0线路触发请求发生与否
{   
LED1;
LED2;
}
EXTI_ClearITPendingBit(EXTI_Line0);  //清除EXTI0线路挂起位
}
 
void EXTI1_IRQHandler(void)
{
   delay_ms(10);    //消抖  
    if(EXTI_GetITStatus(EXTI_Line1) != RESET)    //检查指定的EXT1线路触发请求发生与否
{
  CLED1;
CLED2;
}
 EXTI_ClearITPendingBit(EXTI_Line1);  //清除EXTI1线路挂起位
}


这样试试
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

2

主题

34

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2013-7-19
在线时间
0 小时
发表于 2014-3-22 12:07:34 | 显示全部楼层
回复【楼主位】澜沧衣:
---------------------------------
GPIO配置了吗
ShawnLu
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-9-3
在线时间
8 小时
 楼主| 发表于 2014-3-22 14:43:48 | 显示全部楼层
回复【2楼】745021926:

//初始化PC0,PC1为中断输入.
void EXTIX_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //关闭JTAG
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//IO口的时钟配置
  //初始化 S2-->GPIOC.0,S3-->GPIOC.1  上拉输入
   GPIO_InitStructure.GPIO_
......
---------------------------------
回复【2楼】745021926:
---------------------------------
还是不行,两个中断都能进去。还是都能打印出信息,两个计数值同时增加。如果是按键的话进去中断后,还要判断是哪个按下的,这个看不出什么问题。
好好学习,天天向上。
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-9-3
在线时间
8 小时
 楼主| 发表于 2014-3-22 14:45:30 | 显示全部楼层
回复【3楼】LforeverX:
---------------------------------
嗯,把管脚配置也加上去了,问题还是一样,明明是测量一个中断,两个中断好像都进去了,都能打印出相应信息。
好好学习,天天向上。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2014-3-22 15:17:20 | 显示全部楼层
回复【4楼】澜沧衣:
---------------------------------
你这太诡异了...不行你把我的那个改改试试,,该不会是硬件问题吧,比如连一起了?  换个引脚再测
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-9-3
在线时间
8 小时
 楼主| 发表于 2014-3-22 22:39:22 | 显示全部楼层
回复【6楼】745021926:
---------------------------------
今天我用战舰测试没问题,但是用最小板测(100管脚和144管脚都测试过),就出现我所说的问题。开始我觉得芯片一样的,应该不会有所差异。明天再测测,辨辨有什么不同。
好好学习,天天向上。
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-9-3
在线时间
8 小时
 楼主| 发表于 2014-3-23 09:47:50 | 显示全部楼层
回复【6楼】745021926:
---------------------------------
非常谢谢你解答。今天我测试了一下,主要原因是红外传感器电源(提供5V,实际上3.3V也行)接在战舰上,而脉冲测量管脚是接在最小板上,当我将红外传感器的电源接在最小板上时,就不会出现上述情况。
好好学习,天天向上。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2014-3-23 10:05:37 | 显示全部楼层
回复【8楼】澜沧衣:
---------------------------------
恩,呵呵,恭喜!
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-13 10:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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