《Keil C51单片机教程》 第4章:Keil C51的高级应用

4.1 中断程序设计

在Keil C51中编写中断服务程序

在Keil C51环境下,中断服务程序是处理中断事件的关键部分。下面以外部中断0为例进行说明:

#include <reg51.h>

// 外部中断0服务程序
void externalInterrupt0(void) interrupt 0 {
   
   
    // 保护现场,保存可能会被修改的寄存器值
    // 例如保存累加器A的值
    push acc; 

    // 中断处理代码
    // 这里以翻转P1.0引脚电平为例
    P1 ^= 0x01; 

    // 恢复现场,将之前保存的寄存器值恢复
    pop acc; 
}

void main() {
   
   
    // 设置外部中断0为下降沿触发
    IT0 = 1; 

    // 使能外部中断0
    EX0 = 1; 

    // 使能总中断
    EA = 1; 

    while (1) {
   
   
        // 主循环可以执行其他任务
    }
}

在上述代码中:

  • void externalInterrupt0(void) interrupt 0:定义了外部中断0的服务程序。void 表示函数没有返回值,externalInterrupt0 是函数名,(void) 表示函数没有参数,interrupt 0 表示该函数是外部中断0的中断服务程序,其中 0 是外部中断0对应的中断号。
  • push acc;:将累加器 A 的值压入堆栈,以保护现场,防止在中断处理过程中累加器 A 的值被修改。
  • P1 ^= 0x01;:将 P1 口的第0位电平翻转,作为中断处理的一个简单示例。
  • pop acc;:将之前压入堆栈的累加器 A 的值弹出,恢复现场,使程序在中断返回后能继续正常执行。
  • IT0 = 1;:设置外部中断0为下降沿触发方式。当 IT01 时,外部中断0引脚上的下降沿信号会触发中断。
  • EX0 = 1;:使能外部中断0,允许外部中断0请求中断。
  • EA = 1;:使能总中断,只有当总中断使能且对应中断源的中断使能时,中断才能被响应。
  • while (1):主循环,程序在此处不断循环,等待中断发生。
中断的嵌套与优先级管理

51单片机的中断系统支持中断嵌套,并且可以通过设置中断优先级来管理中断的响应顺序。下面以外部中断0和定时器0中断为例,展示中断嵌套和优先级管理的代码实现:

#include <reg51.h>

// 定时器0中断服务程序
void timer0Interrupt(void) interrupt 1 {
   
   
    // 保护现场
    push acc; 

    // 中断处理代码
    // 这里以翻转P1.1引脚电平为例
    P1 ^= 0x02; 

    // 恢复现场
    pop acc; 
}

// 外部中断0服务程序
void externalInterrupt0(void) interrupt 0 {
   
   
    // 保护现场
    push acc; 

    // 中断处理代码
    // 这里以翻转P1.0引脚电平为例
    P1 ^= 0x01; 

    // 进入中断嵌套,手动触发定时器0中断
    TF0 = 1; 

    // 恢复现场
    pop acc; 
}

void main() {
   
   
    // 设置定时器0为模式1
    TMOD = 0x01; 

    // 装入定时器0初值
    TH0 = (65536 - 50000) >> 8; 
    TL0 = (65536 - 50000) & 0xFF; 

    // 使能定时器0中断
    ET0 = 1; 

    // 设置外部中断0为下降沿触发
    IT0 = 1; 

    // 使能外部中断0
    EX0 = 1; 

    // 设置定时器0中断为高优先级
    PT0 = 1; 

    // 使能总中断
    EA = 1; 

    // 启动定时器0
    TR0 = 1; 

    while (1) {
   
   
        // 主循环可以执行其他任务
    }
}

在上述代码中:

  • void timer0Interrupt(void) interrupt 1:定义定时器0的中断服务程序,interrupt 1 表示该函数是定时器0的中断服务程序,1 是定时器0对应的中断号。
  • void externalInterrupt0(void) interrupt 0:定义外部中断0的中断服务程序,interrupt 0 表示该函数是外部中断0的中断服务程序,0 是外部中断0对应的中断号。
  • TF0 = 1;:在外部中断0服务程序中手动触发定时器0中断,模拟中断嵌套。当 TF01 时,会产生定时器0中断请求。
  • TMOD = 0x01;:设置定时器0为模式1,即16位定时器/计数器模式。
  • TH0 = (65536 - 50000) >> 8;TL0 = (65536 - 50000) & 0xFF;:计算并装入定时器0的初值,定时50ms(假设晶振为12MHz)。
  • ET0 = 1;:使能定时器0中断。
  • IT0 = 1;:设置外部中断0为下降沿触发方式。
  • EX0 = 1;:使能外部中断0。
  • PT0 = 1;:设置定时器0中断为高优先级。当有多个中断请求同时发生时,高优先级中断会优先被响应。
  • EA = 1;:使能总中断。
  • TR0 = 1;:启动定时器0,开始计数。

4.2 定时器/计数器的应用

利用定时器实现定时功能

下面以定时器0为例,实现一个定时功能,每隔50ms翻转一次 P1.0 引脚电平:

#include <reg51.h>

// 定时器0中断服务程序
void timer0Interrupt(void) interrupt 1 {
   
   
    // 重新装载定时器初值
    TH0 = (65536 - 50000) >> 8; 
    TL0 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请向我看齐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值