输入捕捉中断编程实例

合集下载

单片机中断触发方式代码

单片机中断触发方式代码

单片机中断触发方式代码【实用版】目录1.单片机中断概述2.中断触发方式3.代码实例解析正文【单片机中断概述】单片机中断是指在程序运行过程中,由于某种原因导致的程序执行流程被暂时打断,转去处理其他任务,待处理完毕后再回到原程序继续执行。

中断在单片机系统中具有重要作用,例如按键、传感器、通信等外部事件的处理,以及系统异常情况的监测等。

【中断触发方式】在单片机中,中断可以通过以下几种方式触发:1.硬件触发:外部硬件设备通过引脚触发中断,例如按键、传感器等。

2.软件触发:程序内部通过函数或指令触发中断,例如定时器溢出、计数器溢出等。

3.串行通信触发:通过串行通信接口接收到的数据触发中断,例如UART 接收到数据。

4.异常触发:单片机内部检测到异常情况触发中断,例如复位、看门狗超时等。

【代码实例解析】以硬件触发方式为例,使用单片机的定时器触发中断。

以下是一个简单的示例代码:#include <reg52.h>#include <intrins.h>sbit T0_TRG = P1^0; // 定时器 0 触发端口定义void timer0_isr() interrupt 1 // 定时器 0 中断服务函数{TH0 = 0x00; // 清除定时器 0 中断标志TL0 = 0x00; // 清除定时器 0 中断标志// 在这里添加中断处理代码}void main(){TMOD = 0x20; // 定时器 0 工作在方式 2,即 16 位自动重装模式TH0 = 0x00; // 设置定时器 0 计数值为 0TL0 = 0x00; // 设置定时器 0 计数值为 0EA = 1; // 开总中断ET0 = 1; // 开定时器 0 中断TR0 = 1; // 启动定时器 0while (1){// 在这里添加主程序代码}```在上述代码中,定时器 0 的触发端通过引脚 P1^0 连接到外部硬件设备,当外部硬件设备产生触发信号时,定时器 0 会触发中断。

PLC中断功能

PLC中断功能

PLC中断功能plc这样理解中断功能,在理解中断时,首先要清楚plc的运算周期或者说是扫描周期,有必要说下plc顺控循环执行的流程,这是理解中断的前提,必须要掌握,分为三部分,输入处理、程序处理、输出处理1、输入处理,可编程控制器在执行程序前,将可编程控制器的所有输入端子的ON/OFF状态读入输入映像区,程序执行过程中即使输入发生变化,输入映像区的内容也不会变化,在执行下一个循环的输入处理时读取该变化。

2、程序处理、plc根据程序内存中的指令内容,从输入映像区和其他软元件的映像区中读出各软元件的ON/OFF状态,然后从0步依次开始运算,并将每次得出的结果写入到映像区中。

因此,各软元件的映像区随着程序的执行逐步改变其内容,此外,输出继电器的内部触点根据输出映像区的内容而执行动作。

3、输出处理,所有指令执行结束后,输出Y映像区中的,ON/OFF状态会传送至输出锁存内存,这个就作为可编程控制器的实际输出。

执行以一次动作所需要的时间就是运算周期也叫扫描时间,那么中断与扫描周期有什么联系呢,中断就是不按照从上到下顺序的完整执行,而是中断程序优先单独运行程序处理而且是立即输出不参与整个周期运算。

中断的作用是什么呢,我们知道plc扫描周期是很短的,因此我们很难看出plc顺控执行过程,这里我们不妨假设扫描周期为10s的时间,就是执行全部的程序需要10s的时间,有一个很简单的程序LD X0,OUT Y0,根据上图当X0为ON时,Y0不是马上就有输出的,而是等到10s后才输出,断开X0后,同样Y0也不是马上就关闭的,都需要得到扫描完后才有结果。

那么这样在我们实际应用中plc就没什么使用了设备就无法进行工作了,这时候就需要中断处理了,采用输入中断功能,立即执行输入。

实际上plc的运算时间是很短只有几毫秒,完全能够满足需要,但一些如高频脉冲输入、脉冲捕捉等时间在微秒级的肯定要受到周期运算的影响了。

因此如果在一个周期内要完成很多次ON/OFF状态处理时,必须使用中断功能了。

STM32F407通用定时器输入捕获

STM32F407通用定时器输入捕获

通用定时器输入捕获通用定时器作为输入捕获的使用。

我们用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽(用KEY_UP按键输入高电平),通过串口来打印高电平脉宽时间。

输入捕获模式可以用来测量脉冲宽度或者测量频率。

我们以测量脉宽为例,用一个简图来说明输入捕获的原理:如图所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中t1~t2时间,就是我们需要测量的高电平时间。

测量方法如下:首先设置定时器通道x为上升沿捕获,这样,t1时刻,就会捕获到当前的CNT值,然后立即清零CNT,并设置通道x为下降沿捕获,这样到t2时刻,又会发生捕获事件,得到此时的CNT值,记为CCRx2。

这样,根据定时器的计数频率,我们就可以算出t1~t2的时间,从而得到高电平脉宽。

在t1~t2之间,可能产生N次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。

如图所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以CNT的计数周期,即可得到t2-t1的时间长度,即高电平持续时间。

STM32F4的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。

STM32F4的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。

同时还可以配置捕获时是否触发中断/DMA等。

这里我们用TIM5_CH1来捕获高电平脉宽。

=================================================================================== 捕获/比较通道(例如:通道 1 输入阶段)=================================================================================== 接下来介绍我们需要用到的一些寄存器配置,需要用到的寄存器:TIMx_ARR、TIMx_PSC、TIMx_CCMR1、TIMx_CCER、TIMx_DIER、TIMx_CR1、TIMx_CCR1 (这里的x=5)。

输入捕捉

输入捕捉
uint count;
/********以下是延时函数********/
void Delay_ms(uint xms)
{
int i,j;
for(i=0;i<xms;i++)
{ for(j=0;j<1140;j++) ; }
}
/********以下是端口初始化函数********/
void port_init()
6. avr定时器/计数器1 --TC1 --输入捕捉模式(捕获外部事件模式)
T/C的输入捕捉单元可用来捕获外部事件,并为其赋予时间标记以说明此时间的发生时刻。外部事件发生的触发信号由引脚ICP1 (PD6)输入,也可通过模拟比较器单元来实现。时间标记可用来计算频率、占空比及信号的其它特征,以及为事件创建日志。当引脚ICP1上的逻辑电平(事件)发生了变化,或模拟比较器输出ACO电平发生了变化,并且这个电平变化为边沿检测器所证实,输入捕捉即被激发:16位的TCNT1数据被拷贝到输入捕捉寄存器ICR1,同时输入捕捉标志位ICF1置位。如果此时ICIE1 = 1,输入捕捉标志将产生输入捕捉中断。中断执行时ICF1自动清零,或者也可通过软件在其对应的I/O位置写入逻辑"1”清零。读取ICR1时要先读低字节ICR1L,然后再读高字节ICR1H。读低字节时,高字节被复制到高字节临时寄存器TEMP。CPU读取ICR1H时将访问TEMP寄存器。
操作步骤:
一、捕获输入端口初始化:捕获输入端ICP1(PD6)设为输入,DDRD&=(0<<PD6);
并使能PD6口的内部上拉电阻,PORTD|=(1<<PD6);
二、设置定时器的工作模式:TCCR1A=0X00 //普通模式,计数最大值为65535

stm32PWM输入捕获

stm32PWM输入捕获

stm32PWM输入捕获tm32定时器pwm输入捕获输入捕捉的功能是记录下要捕捉的边沿出现的时刻,如果你仅仅捕捉下降沿,那么两次捕捉的差表示输入信号的周期,即两次下降沿之间的时间。

如果要测量低电平的宽度,你应该在捕捉到下降沿的中断处理中把捕捉边沿改变为上升沿,然后把两次捕捉的数值相减就得到了需要测量的低电平宽度。

如果要的测量低电平太窄,中断中来不及改变捕捉方向时,或不想在中断中改变捕捉方向,则需要使用PWM输入模式,或使用两个TIM某通道,一个通道捕捉下降沿,另一个通道捕捉上升沿,然后对两次捕捉的数值相减。

PWM输入模式也是需要用到两个通道。

使用两个通道时,最好使用通道1和通道2,或通道3和通道4,这样上述功能只需要使用一个I/O管脚,详细请看STM32技术参考手册中的TIM某框图。

//0-----------------------一、概念理解PWM输入捕获模式是输入捕获模式的特例,自己理解如下1.每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。

且IC1IC2一组,IC3IC4一组。

并且可是设置管脚和寄存器的对应关系。

2.同一个TI某输入映射了两个IC某信号。

3.这两个IC某信号分别在相反的极性边沿有效。

4.两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。

5.当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获“一个PWM周期(即连续的两个上升沿或下降沿)”,它等于包含TIM时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。

6.同样另一个捕获通道捕获触发信号和下一个相反极性的边沿信号的计数个数m,即(即高电平的周期或低电平的周期)7.由此可以计算出PWM的时钟周期和占空比了frequency=f(TIM时钟频率)/n。

dutycycle=(高电平计数个数/n),若m为高电平计数个数,则dutycycle=m/n若m为低电平计数个数,则dutycycle=(n-m)/n 注:因为计数器为16位,所以一个周期最多计数65535个,所以测得的最小频率=TIM时钟频率/65535。

第五章 IO端口、输入捕捉

第五章   IO端口、输入捕捉
• 注: 为了将PORTB 引脚用作数字I/O,ADPCFG 寄 存器中的相应位必须置为“1”(即使关闭了A/D 模块 也应如此)。
• 图5-2: 共用的端口结构框图
• 5.3.1 I/O 与多个外设复用
• 对于有些dsPIC30F 器件,尤其是那些带有少量 I/O 引脚数较少的器件,其每个I/O 引脚可能要 复用多种外设功能。图5-2 所示为两个外设与同 一个I/O 引脚复用的示例。
• 和TRISx 寄存器以及该端口引脚将读作0
5.3 外设复用
• 当某个外设使能时,与其相关的引脚将被禁止作为通 用I/O 引脚使用。可以通过输入数据路径读该I/O 引脚, 但该I/O 端口位的输出驱动器将被禁止。
• 与另一个外设共用一个引脚的I/O 端口总是服从于该外 设。外设的输出缓冲器数据和控制信号提供给一对多 路开关。该多路开关选择是外设还是相关的端口拥有 输出数据的所有权以及I/O 引脚的控制信号。图11-2 显示了端口如何与其他外设共用,以及与外设连接的 相关I/O 引脚。
• 参照图5-2,外设多路开关的结构将决定外设输 入引脚是否可以通过使用PORT 寄存器用软件控 制。
• 当图中所示的概念化的外设在功能被使能时,会断开 I/O 引脚与端口数据的连接。一般而言,下列外设允许 通过PORT 寄存器手动控制它们的输入引脚:
• 外部中断引脚 • 定时器时钟输入引脚 • 输入捕捉引脚 • PWM 故障引脚 • 大多数串行通信外设在使能时,将完全控作0 • bit 13 ICSIDL:输入捕捉模块在空闲时停止控制位 • 1 = 输入捕捉模块在CPU 空闲模式将停止 • 0 = 输入捕捉模块在CPU 空闲模式将继续工作 • bit 12-8 未用:读作0 • bit 7 ICTMR:输入捕捉定时器选择位 • 1 = 捕捉事件时捕捉TMR2 的内容 • 0 = 捕捉事件时捕捉TMR3 的内容 • 注: 可供选择的定时器可能会和上述不同。 更多详细

51单片机中断程序例子

51单片机中断程序例子

51单片机中断程序例子
1. 外部中断:当外部信号引脚检测到高电平时,单片机会触发外部中断服务程序。

可以利用外部中断实现按键扫描功能,当按键按下时,触发中断程序对按键进行处理。

2. 定时器中断:利用定时器中断可以实现精确的时间控制。

例如,我们可以设置定时器中断为1秒,当定时器溢出时,触发中断程序,实现1秒钟执行一次的任务。

3. 串口中断:当接收到串口数据时,单片机会触发串口中断服务程序,可以利用串口中断实现串口通信功能。

4. ADC中断:当模数转换器完成一次转换时,单片机会触发ADC中断服务程序,可以利用ADC中断实现模拟信号的采集和处理。

5. 看门狗中断:看门狗定时器溢出时,单片机会触发看门狗中断服务程序,可以利用看门狗中断实现系统复位或其他相关功能。

6. 外部中断优先级:当多个外部中断同时触发时,可以通过设置外部中断的优先级来确定触发的顺序和优先级。

7. 定时器中断优先级:当多个定时器中断同时触发时,可以通过设置定时器中断的优先级来确定触发的顺序和优先级。

8. 中断嵌套:单片机支持中断嵌套,即在一个中断服务程序中触发
另一个中断服务程序,可以通过中断嵌套实现复杂的任务处理。

9. 中断屏蔽:单片机支持对中断的屏蔽,即可以通过设置中断屏蔽标志位来屏蔽某些中断,使其暂时不被触发。

10. 中断标志位:单片机提供中断标志位,用于标识中断是否被触发。

在中断服务程序中,可以通过读取和清除中断标志位来判断中断是否发生。

以上是根据51单片机中断程序的例子进行的描述,这些例子涵盖了常见的中断类型和相关功能。

通过学习和理解这些例子,可以更好地掌握51单片机中断编程的原理和方法。

中断程序的编程实例

中断程序的编程实例

中断程序的编程实例哎呀,今天真是忙得不可开交,一大早就被老板叫去开会,说是要讨论一个新项目的编程实例。

我心里嘀咕着,这项目可不简单,得好好琢磨琢磨。

一进会议室,就看到老张坐在那儿,手里拿着杯咖啡,眉头紧锁。

我走过去拍了拍他的肩膀,笑着说:“老张,怎么了?又被代码折磨了?”老张抬头看了我一眼,叹了口气:“可不是嘛,这中断程序的编程实例,简直是个大坑。

我昨晚熬到半夜,愣是没搞定。

”我坐下来,拿起桌上的资料翻了翻,心里也有些打鼓。

这中断程序可不是闹着玩的,稍有不慎,整个系统都得崩溃。

我一边翻资料,一边和老张讨论起来。

“你说,这中断程序的核心是什么?”我问道。

老张想了想,说:“我觉得关键是中断处理函数的编写,得确保它能在最短的时间内完成任务,不影响系统的正常运行。

”我点点头,觉得老张说得有道理。

“对,而且还得考虑中断的优先级,不能让低优先级的中断打断高优先级的任务。

”正说着,小李也进来了,手里拿着笔记本,一脸疲惫。

“你们在讨论什么呢?”他问道。

“我们在说中断程序的编程实例,”我回答,“你有什么想法吗?”小李坐下来,揉了揉太阳穴,说:“我觉得我们可以考虑用状态机来管理中断,这样能更好地控制中断的流程。

”我眼前一亮,觉得小李的建议挺有创意。

“好主意!状态机确实能提高中断处理的效率。

”老张也点头表示赞同:“对,我们可以试试用状态机来实现中断处理函数。

”我们三个人你一言我一语,讨论得热火朝天。

时间不知不觉就过去了,转眼间已经到了中午。

我看了看手表,笑着说:“走吧,先去吃饭,下午再继续讨论。

”老张和小李也站了起来,我们一边往外走,一边还在讨论中断程序的细节。

虽然任务艰巨,但有伙伴们的支持,我觉得信心满满。

下午回到办公室,我们继续投入到编程实例的编写中。

虽然过程中遇到了不少困难,但我们互相鼓励,互相帮助,最终还是顺利完成了任务。

当最后一个bug被修复,程序成功运行时,我们三个人都松了一口气,相视而笑。

老张拍了拍我的肩膀,说:“兄弟,干得不错!”我笑着回应:“都是大家的功劳,没有你们的帮助,我一个人可搞不定。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//请修改下表中的相应项目
#pragma abs_address:0xffdc
void (* const _vectab[])(void) = {
isrDummy,//Timebase
isrDummy,//ADC
isrDummy,//KBI
isrDummy,//SCI TC/TE
isrDummy,//SCI RF/IDLE
isrDummy,//SCI PE/FE/NF/OR
isrDummy,//SPI TE
isrDummy,//SPI MOD/OVR/RF
isrDummy,//TIM2 OVR
isrDummy,//TIM2 channel 1
isrDummy,//TIM2 channel 0
isrDummy,//TIM1 OVR
*[中断向量]
ORG $FFF6 ;定时器1通道0输入捕捉中断向量
DW Tim1CH0Int
ORG $FFFE ;复位向量
DW MainInit
*Tim1CH0Int:定时器1通道0输入捕捉中断子程序-------------*
*功能:定时器输入捕捉中断处理,开关拨动时指示灯PTA.1闪烁*
*入口:无*
*出口:无*
*------------------------------------------------------*
Tim1CH0Int:
LDA #%00110000
STAT1SC
;[输入捕捉模式,允许输入捕捉中断,跳变沿捕捉]
LDA #%01001100
STAT1SC0
;[允许定时器1计数寄存器计数]
BCLR 5,T1SC
CLI ;开总中断
;[主循环开始]
MainLoop:
NOP
JMP MainLoop
*[内部直接调用子程序存放处]
*[两个起始地址名]
RAMstartAddr equ $0040 ;RAM的起始地址
FlashStartAddr equ $8000 ;程序开始地址
*[指示灯定义]
Light_P equ PTA ;灯(Light)接在PTA口
Light_D equ DDRA ;相应的方向寄存器
Light_Pin equ 1 ;所在的引脚
PSHH ;保护H
;[至此,可读取计数器的值,可在此处添加用户的程序.本程
;序仅为实验例程,用指示等状态改变,说明发生了中断]
;指示灯状态变换
BRCLR Light_Pin,Light_P,Tim1CH0Int_1
BCLR Light_Pin,Light_P ;若原来灯暗,则变亮
BRA Tim1CH0Int_2
*文件名:Tim1Ch0I.prj *
*硬件接线:1:PTA.1接指示灯*
* 2:PTD.4,即定时器1通道0(21脚),接开关*
*程序描述:以输入捕捉中断方式, *
*开关拨动使捕捉中断取反指示灯PTA1,使其闪动*
*目的:学习HC08系列定时器溢出捕捉功能*
*说明:本例是将定时器1通道0(21脚)设为"跳变沿捕捉" *
实例编号:A05_2路径:\ASM\ A05_2定时器输入捕捉(Ch0main.asm)
*------------------------------------------------------*
*工程名:Tim1Ch0.ASM *
*硬件接线:1:PTA.1接指示灯*
* 2:PTD.4,即定时器1通道0(21脚)接开关*
#define Light_Pin 1 //所在的引脚
#define CH0FBit 7 //定时器1通道标志位
// vectors08.c用于定义中断矢量表
/*isrTim1Ch0I:输入捕捉中断处理函数---------------------*
*功能:当前灯的状态*
*-----------------------------------------------------*/
#define Light_Pin 1 //所在的引脚
#define CH0FBit 7 //定时器1通道标志位
/*函数声明*/
void SetTim1Ch0I(void); //定时器1和定时器1通道0初始化
void main()
{
asm("SEI"); //禁止所有中断
//[I/O初始化]
Light_D|=1<<Light_Pin; //令指示灯引脚为输出
* (即电平发生变化时产生中断),验证方法是将21脚不*
*断接高电平、低电平,此时指示灯PTA1状态跟随改变*
*---------《嵌入式应用技术基础教程》教学实例----------*/
#include "GP32C.h"
#define Light_P PTA //灯(Light)接在PTA口
#define Light_D DDRA //相应的方向寄存器
10.3.3输入捕捉中断编程实例
下面程序验证定时器1通道0(引脚21)输入捕捉中断的产生,当中断发生时取反指示灯PTA1。定时器1通道0的输入捕捉中断向量的地址是$FFF6。
(1)输入捕捉中断编程实例C语言主程序
实例编号:C05_2路径:\C\C05_2定时器输入捕捉(tim1ch0.prj)
/*-----------------------------------------------------*
Light_P|=1<<Light_Pin; //初始时,指示灯"暗"
//[定时器1和定时器1通道0初始化]
SetTim1Ch0I();
asm("CLI"); //开放中断
//[主循环开始,为空操作]
//[等待输入捕捉中断,(开关的拨动)]
while(1);
}
/*SetTim1Ch0I:定时器1和定时器1通道0初始化-------------*
*功能:初始化定时器1和定时器1通道0 *
*参数:无*
*返回:无*
*-----------------------------------------------------*/
void SetTim1Ch0I()
{
T1SC=0b00110000; //不允许溢出中断、不启动计数、分频因子=1
T1SC0=0b01001100;//允许CH0输入捕捉中断,跳变沿捕捉
isrDummy,//TIM1 channel 1
isrTim1Ch0I,//TIM1 channel 0
isrDummy,//CGM
isrDummy,//IRQ
isrDummy//SWI
/*RESET也是中断,定义在crt08.o中*/
};
#pragma end_abs_address
(3)输入捕捉中断编程实例汇编语言程序
T1SC&=~(1<<5);//允许定时器1计数寄存器计数
}
(2)输入捕捉中断编程实例C语言矢量表文件
输入捕捉中断编程C语言程序例矢量表文件(vectors08.c)
#include "GP32C.h"
/*[引脚定义]*/
#define Light_P PTA //灯(Light)接在PTA口
#define Light_D DDRA //相应的方向寄存器
Tim1CH0Int_1:
BSET Light_Pin,Light_P ;若原来灯亮,则转暗
Tim1CH0Int_2:
;清除定时器1通道0输入捕捉中断标志位
LDA T1SC0
BCLR CH0FBit,T1SC0
PULH;恢复H
RTI
*[外部子程序存放处]
$include "GP32Init.ASM"
#pragma interrupt_handler isrTim1Ch0nsigned char temp=Light_P;
temp&=1<<Light_Pin; //取得当前灯的状态
if(temp!=0) //原来指示灯"暗",则变"亮"
Light_P&=1<<Light_Pin;
CH0FBit equ 7 ;定时器1通道标志位
*======================================================*
*[主程序]
org FlashStartAddr ;程序起始地址
MainInit: ;复位后程序从此开始执行
;[系统初始化]
SEI ;关总中断
LDHX #$023F;堆栈初始化
TXS
JSR GP32Init ;调系统初始化子程序GP32Init
;[I/O初始化]
BSET Light_Pin,Light_D ;令指示灯引脚为输出
BSET Light_Pin,Light_P ;初始时,指示灯"暗"
;[定时器1通道0初始化]
;[不允许溢出中断、不启动计数、分频因子=1]
else //原来指示灯"亮",则变"暗"
Light_P|=1<<Light_Pin;
T1SC0&=~(1<<CH0FBit);//清除定时器溢出标志位
}
#pragma interrupt_handler isrDummy
void isrDummy(void)
{ }
//中断矢量表,如果需要定义其它中断函数,
*程序描述:输入捕捉中断方式,使开关拨动时指示灯PTA.1闪烁*
相关文档
最新文档