嵌入式学习--step12 外部中断与定时器中断学习

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wangwangmoon_light/article/details/52317886

/*********************/
外部中断:
1、STM32F4的每个IO都可以作为外部中断输入。
这里写图片描述
STM32F4供IO使用的中断线只有16个。EXT0–EXT15
但是STM32F4xx系列的IO口有112个。16*7=112( (A–I) 7个)
下面讲,它们的映射关系:
GPIOx.0 映射到 EXTI0
2、对于每个中断线,我们可以设置触发方式。
这里写图片描述
3、并不是16个中断线就有16个中断服务函数呢?
IO口外部中断在中断向量表中只分配了7个中断向量,也就只能使用7个中断服务函数。
这里写图片描述
IO口外部中断在中断向量表中只分配了7个中断,EXTI9_5 就是中断5到中断9在一起,中断10-中断15在一起。这样以来,就只能使用7个中断服务函数。
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI5_10_IRQHandler
//////////////////////////////////////////////////////////////
下面是讲讲外部中断常用库函数:
1、void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx,uint8_t EXTI_PinSoucex);
//设置IO口与中断线的映射关系**
例如:
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2);
2、void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//初始化中断线:触发方式等。
3、ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//判断中断线中断状态,是否发生
4、void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
//清除中断线上的中断标志位
5、RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
//使能SYSCFG时钟
/////////////////////////////////////////////////////////////////

外部中断的一般配置步骤
1、使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
2、初始化IO口为输入
GPIO_Init();
3、设置IO口与中断线的映射关系
void SYSCFG_EXTILineConfig();
4、初始化线上中断,设置触发条件等
EXTI_Init();
5、配置中断分组(NVIC),并使能中断
NVIC_Init();
6、编写中断服务函数
EXTIx_IRQHandler();
7、清除中断标志位
EXTI_ClearITPendingBit();
///////////////////////////////////////////
讲解使用库函数配置外部中断的步骤:
1)使能IO口时钟,初始化IO口为输入
2)开启SYSCFG时钟,设置IO口与中断线的映射关系
首先,打开SYSCFG时钟,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
注意,只要我们使用外部中断,就必须打开SYSCFG时钟
接下来,配置GPIO与中断线的映射关系,配置GPIO与中断线的映射关系的函数SYSCFG_EXTILineConfig()来实现的:
例如:SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA , EXTI_PinSource0) ;这样就将中断线0与GPIOA映射起来。
3)初始化线上中断,设置触发条件等
中断线上中断的初始化时通过函数EXTI_Init()实现的,EXTI_InitTypeDef EXTI_InitStructure;
EXTI_Init(&EXTI_InitStructure);
4)配置中断分组(NVIC),并使能中断
我们设置好中断线和GPIO映射关系,又设置好了中断的触发模式等初始化参数,既然是外部中断,所以还要设置NVIC中断优先级。
5)编写中断服务函数
配置完优先级后,接下来就是编写中断服务函数。
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{….
EXTI_ClearITPendingBit(EXTI_Line3);//清除LINE上的中断标志位
….
}
}

定时器中断讲解:
1、通用定时器讲解
这里写图片描述
STM32F4 通用定时器(TIM2、TIM3、TIM4、TIM5)功能与特点包括:
1、16/32位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器。
2、16位可编程预分频器(TIMx_PSC),计数器时钟频率的分频系数为1—65535之间的任意数值。
3、4个独立通道(TIMx_CH1-4)输入捕获、输出比较、PWM生成、单脉冲模式输出
4、可使用外部信号控制定时器和定时器互连(可用1个定时器控制另外一个定时器)
2、如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器)
1、更新,计数器溢出,计数器初始化
2、触发事件
3、输入捕获
4、输出比较
5、支持针对定位的增量编码器和霍尔传感器电路
6、触发输入作为外部时钟或者按周期的电流管理

这里写图片描述

这里写图片描述

三种计数器模式:
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

/*****************************************/
PWM波
PWM是指脉冲宽度调制,“Pulse Width Modulation”,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制。
这里写图片描述
STM32F4的定时器除了TIM6和TIM7,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出,而通用定时器也能同时产生多达4路的PWM输出,这里我们仅用TIM14的CH1产生一路PWM输出。
这里写图片描述

展开阅读全文

外部中断定时器中断同时的问题

08-10

我在外部中断做的是红外遥控处理,P3^2口进入,下降沿触发,里面还有一个timer0,显示用12864,已经成功,可以显示123456789,我用定时器做的是一个小游戏俄罗斯方块一步步下移的定时,用矩阵键盘控制上下移动,rn部分程序如下,高手解决下,谢谢rnrnrnrnrnrnvoid time0() interrupt 5定是器中断rn TF2=0;清除溢出标志rn t++;rn if(t==(50-5guan1)t100tquick)rn rn t=0;rn flagtime=1;rn rnvoid exter0() interrupt 0//外部中断0服务函数rnrn EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号rn TH0=0; //定时器T0的高8位清0rn TL0=0; //定时器T0的低8位清0rn TR0=1; //开启定时器T0 rn while(IR==0); //如果是低电平就等待,给引导码低电平计时rn TR0=0; //关闭定时器T0 rn LowTime=TH0*256+TL0; //保存低电平时间rn TH0=0; //定时器T0的高8位清0rn TL0=0; //定时器T0的低8位清0rn TR0=1; //开启定时器T0rn while(IR==1); //如果是高电平就等待,给引导码高电平计时rn TR0=0; //关闭定时器T0rn HighTime=TH0*256+TL0; //保存引导码的高电平长度rn if((LowTime>3600)&&(LowTime<4700)&&(HighTime>3600)&&(HighTime<4700))rn rn //如果是引导码,就开始解码,否则放弃,引导码的低电平计时rn //次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.rn if(DeCode()==1) // 执行遥控解码功能rn rn redex();rn rn rn EX0=1; //开启外中断EX0rnrnvoid time0() interrupt 5//定是器中断rn TF2=0;//清除溢出标志rn t++;rn if(t==(50-5*guan1)||t>100||t>quick)rn rn t=0;rn flagtime=1;rn rn主程序是rn EA = 1; //开总中断rn EX0 = 1; //使能外部中断rn ET0=1; //开中断rn IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)rn TMOD=0x01;//定时器0工作方式2,TH0是重装值,TL0是初值rn TR0=0; rn PT2=1;rn PT0=0;rnrnrnrnrn我想让我的timer2一直运行,而不被外部中断0影响,我就设置了PT2=1;高优先级,但程序的timer2不能正常运行,timer2的工作方式为自动重装,迷惑中,或者别的方法。 rn 论坛

外部中断中使用定时器中断---中断电子钟

03-19

在进入外部中断后,在中断程序中是否还可以调用定时器中断,我打算在外部中断后用定时器做一个电子钟的,可是 ,做了就是不走字,很纠结啊 ,跟中断优先级有关系吗,还是中断嵌套的问题,是在不行的话 估计得使用goto语句强制返回到main() 中的时钟函数了,但是这样一来就降低了程序的可读性,各位大侠能不能给指点指点[code]#includern#includern#define uchar unsigned charrn#define uint unsigned intrnsbit K1=P3^3;rnsbit wei0=P2^0;rnsbit wei1=P2^1;rnsbit wei2=P2^2;rnsbit wei3=P2^3;rnsbit wei4=P2^4; //位选rnuchar code disp[]=0x48,0x40,0x12,0x06,0x78,0x06,0x2b,0x21,0x23,0x47,0x40,0x08,0x21,0xff;rnuchar code tdisp[]=0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e;rnvolatile uint cs,m_v,h_v;//主程序与中断子程序共用变量 volatile关键字声明rnuint a,b,c,d,n,z;rnvoid cdisp(uint th,uint tm);rnvoid delay(unsigned int z);rnvoid v_time_go();rnvoid main()rnrn TMOD=0x11;//工作方式为 T0 工作rn TH0=(65536-55000)/256; //为高位赋初值rn TL0=(65536-55000)%256; rn EA=1;//全中断开rn ET0=1; //允许T0定时中断rn TR0=1;rn cs=1200;rn EX1=1;rn IT1=0;rnrnrnrnvoid ding() interrupt 1rnrn TH0=(65536-55000)/256;rn TL0=(65536-55000)%256;rn rn rn cs--;rn if(!cs)rn rn cs=1200;rn rn rnrnrn rnrnrnvoid delay(unsigned int z)rnrn unsigned int j;rn for(;z>0;z--)rn rn for(j=0;j<100;j++)rn ;rn rnrnrnvoid wuxian() interrupt 2 //P3.3 无线中断后 电子钟rn cs=1200;rnh_v=12;rnm_v=0;rnrn while(1)rn rnrnrnrn v_time_go();rn rnrn rn rnrnrnrnvoid v_time_go()rnrn rn rn if(!cs)rn rn cs=1200;rn if(m_v>59)rn rn m_v=0;rn h_v++;rn rn elsern rn m_v++;rn rn rn if(h_v>23)rn rn h_v=0;rnrn rn elsern rn h_v++;rn rn rnrn rn rn cdisp(h_v,m_v);rnrnrnvoid cdisp(uint th,uint tm) //rn rn rn rn a=th/10;rn b=th%10;rn c=tm/10;rn d=tm%10;rnrn P1=0xff;rn n=cs/20;rn rn if(((n%2)==0)&&((cs%20)>=0)&&((cs%20)<=19))rn rn rn wei0=0;rn P1=tdisp[a];rn delay(1);rn P1=0xff;rn wei0=1;rn wei1=0;rn P1=tdisp;rn delay(1);rn P1=0xff;rn wei1=1;rn wei2=1;rn rn rn rn rn rn delay(2);rn P1=0xff;rn wei3=0;rn P1=tdisp[c];rn delay(1);rn P1=0xff;rn wei3=1;rn wei4=0;rn P1=tdisp[d];rn delay(1);rn P1=0xff;rn wei4=1;rn rn elsern rn wei0=0;rn P1=tdisp[a];rn delay(1);rn P1=0xff;rn wei0=1;rn wei1=0;rn P1=tdisp;rn delay(1);rn P1=0xff;rn wei1=1;rn wei2=0;rn P1=0x3f;rn delay(1);rn P1=0xff;rn wei2=1;rn wei3=0;rn P1=tdisp[c];rn delay(1);rn P1=0xff;rn wei3=1;rn wei4=0;rn P1=tdisp[d];rn delay(1);rn P1=0xff;rn wei4=1;rn rn[/code]rn 论坛

没有更多推荐了,返回首页