单片机的C语言中如何实现汇编中的中断程序,写哪里?还有org这个伪指令可以在C中实现吗?

单片机的C语言中如何实现汇编中的中断程序,写哪里?还有org这个伪指令可以在C中实现吗?,第1张

如果是用C去写的话,像汇编一样,开中断就行了。位置一般就在MAIN 之前的。

//晶振频率22.1184MHz

#include<at89x52.h>

#define TIMER0H 0x4c

#define TIMER0L 0x00

#define TIMER0_RUN TR0=1

#define SECOND_OVERFLOW 40

#define SEG_PORTP0

#define DISPLAY_DIG1P1&=0xf0P1|=0x01

unsigned char g_CurrentDigit=0 //当前显示的数字

void timer() interrupt 1

{

static unsigned char s_Count = 0

TH0 = TIMER0H //重置定时器初值

TL0 = TIMER0L

//每次进入中断服务程序,TH0和 TL0 的值都

TIMER0_RUN //定时器运行,开始下一

if(s_Count != SECOND_OVERFLOW)

{//未到整秒,把 sCount 值加1

s_Count++

}

else

{//到整秒,s_Count归 0,更新把当前显示

s_Count = 0

if(g_CurrentDigit != 9)

{

g_CurrentDigit++

}

else

{

g_CurrentDigit = 0

}

}

return

}

void Initial(void)//初始化

{

IE = 0x82 //仅允许Timer0 中断

TMOD = 0x01 //Timer0 使用工作方式 1(16位) ,定时器

TH0 = TIMER0H//设置定时器初值

TL0 = TIMER0L

TIMER0_RUN //定时器开始运行

DISPLAY_DIG1

}

void main()

{

unsigned char code SEG_CODE[]

= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

Initial()

while(1)

{

SEG_PORT = SEG_CODE[g_CurrentDigit]//显示当前的数字

//当timer0溢出时,单片机响应 timer0 中断,调用 timer 函数

//每40 次调用当前显示的数字加 1

}

}

程序分析:

程序中主程序做的事只是在死循环中反复显示当前的数字,每产生一次中断,程序就跳

转到中断服务函数 timer()中进行相应的更新。

这里中断服务函数 timer()有别于普通 C函数的地方是在声明中多了“interrupt 1” ,说明

这个函数是中断号为 1的中断服务函数。各个中断对应的中断号如表 3.8所示。

这个程序需要初始化的东西比较多, 我们把这些初始化语句都放在了初始化函数 Initial()

中,这也是程序初始化很常见的做法。我们还第一次用到了静态变量和全局变量。全局变量

是中断处理函数与外界程序进行参数传递的唯一途径,因此在单片机程序中全局变量的使

用频率要比普通的 C 语言程序高。尽管如此,由于全局变量的使用会影响程序的结构化,

所以在可以不使用全局变量的地方,还是要避免使用全局变量。在程序中,为了把全局变

量与静态变量跟普通变量区别开来,我们在变量前分别加了小写 g_和小写 s_以示区别。

IE 寄存器中的使能位和C中的中断号 中断源

0 外部中断0

1 定时器0溢出

2 外部中断1

3 定时器1溢出

4 串行口中断

5

定时器2溢出(仅在S52、

C52中有此中断源)

好了,以上是我找的一个实例,希望对你有帮助!

嗯,我猜你问的是PC的,不是单片机

一、汇编语言的中断分以下几种:

1.BIOS中断,这是固化到BIOS程序中的,每次开机BIOS会自动加载到指定内存

2.186下的DOS中断,在DOS系统被加载后,系统会延用BIOS的中断向量,并向里面添加一些新的向量,这些功能便是DOS系统自带的中断服务程序

3.286及以上的系统中断,PC会进入保护模式,在OS被加载后,中断由IDT控制,这一机制类似于中断向量表,只不过中断向量换成了选择子。这样的中断机制对不同型号的CPU有略微的差别,这里不细说了,我自己也没全弄明白。

二、中断实现的方式(8086下的普通中断)

听说过“优先级编码器”没?——如果同时有两个信号被接收,会指定某一个信号的优先级高,先执行它。中断就是类似的处理方法。

当CPU获取到某一高 *** 作优先级的信号时(比如时钟,每固定时间就会触发一次;比如键盘响应,用户希望通过Ctrl+C来退出任何正在执行的DOS程序),CPU会将当前正在执行的程序挂起来,转而去处理该信号(类似于Call,但略有不同,你看的书应该会讲到)。

处理中断时,系统会将其解释为一个标号,比如int 9h、int 21h等等。这个标号是一个序号,在内存某处存放着连续的一个表格,这个标号便是表格中的“行号”,只不过,每一行是两列,包括了该中断的处理程序的段基址和偏移量。中断向量表是从0000:0000开始的,每4字节为一个表项。中断标号x4就是对应的中断向量表项所存的地址,高地址是基地址,低地址是偏移。

这么说不知道你懂不懂。。。

反正总结一下你的问题吧,中断服务程序是加载到内存中的,它在加载前可能是存在BIOS芯片上,也可能是存在硬盘里的;中断向量表里只能写上中断处理程序的入口地址,要知道每个表项只有4字节;具体的中断服务程序,我不信你学汇编的书上不讲,我大概讲一下:CPU的INTR引脚获得了中断信号,得到了标号,比方说是5号,中断向量表项为0000:000A,读取这个内存,得到中断程序入口地址比方说是AAAA:BBBB,那么它会将当前的CS/IP、Flags寄存器入栈,然后转到AAAA:BBBB处去执行一直到iret指令返回原任务(或许该中断结束了这个任务,就不会返回了)。

至于保护模式的中断,相信你暂时还没遇到。到后面还有 *** 控8259A芯片来实现高级中断的,这个就不是一般需要学的了。

SBUF中的数据发送完毕,TI传送结束标志置1,如果设置了ES=1(串口中断是允许的),就进入串口中断服务程序。解决方法如下:

1、首先打开Cube工程,在Pinout页使能需要使用的串口。

2、切换到“Configuration”页,找到并点击需要使用的串口,比如之前选择的USART2。

3、在d出的“xxx Configuration”对话框中选择“NVIC Settings”,勾选“xxx global interrupt”的Enabled,其中xxx为目标串口名称。

4、回到“Configuration”页,在“NVIC Configuration”对话框点击“Code generation”,勾选“xxx global interrupt”的Generate IRQ handler和“Select for init sequence ord...”。

5、点击“Project ->Generate Code”生成代码。

6、重写HAL_UART_RxCpltCallback回调函数,这里的代码通过判断huart ->Instance是否为USART2,然后将接收的data使用阻塞方式发送出去,接着再启动接收就可以了。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7788121.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存