单片机中断任务改进实验

利用C语言知识,在任务六的基础上改进
改进要求

img


任务六代码已写好

img


img

以下内容部分参考ChatGPT模型:


思路:

  1. 首先需要明确改进的要求,即要在任务六的基础上进行改进。从任务六代码中可以看出,该任务实现了外部中断0的功能,即当外部中断0引脚(P3.2)有信号变化时,会执行中断服务函数int0()。

  2. 针对该任务的改进可以有多种方式,以下是其中一种:

    1. 在int0()函数中添加一个计数器,每触发一次中断,计数器加1。
    2. 在主函数中添加一个定时器中断,每隔一段时间检查一下计数器的值,如果计数器的值为偶数,则控制LED1亮,否则灭。
  3. 具体实现过程如下:

    1. 在int0()函数中添加一个计数器count,并在每次中断服务函数执行时将count加1:

      void int0() interrupt 0 {
          count++;
      }
      
    2. 在主函数中初始化定时器,并开启定时器中断。这里以定时器0为例,每1秒钟触发一次中断:

      void init_timer0() {
          TMOD |= 0x01;   // Timer0使用模式1
          TH0 = 0xFC;     // 定时1s
          TL0 = 0x18;
          ET0 = 1;        // 开启定时器0中断
          TR0 = 1;        // 启动定时器0
      }
      
      void timer0() interrupt 1 {
          if (count % 2 == 0) {   // 如果count为偶数,则LED1亮
              LED1 = 1;
          } else {                // 否则LED1灭
              LED1 = 0;
          }
      }
      
      void main() {
          init_timer0();  // 初始化定时器0
          IE = 0x81;      // 开启中断,允许外部中断0和定时器0中断
          while (1);
      }
      
    3. 在主函数中开启中断,并在while循环中等待中断的触发。

  4. 最终的代码如下:

    #include <reg52.h>
    
    sbit LED1 = P0^0;   // LED1的控制引脚
    sbit INT0 = P3^2;   // 外部中断0引脚
    
    unsigned int count = 0;   // 计数器
    
    void init_timer0() {
        TMOD |= 0x01;   // Timer0使用模式1
        TH0 = 0xFC;     // 定时1s
        TL0 = 0x18;
        ET0 = 1;        // 开启定时器0中断
        TR0 = 1;        // 启动定时器0
    }
    
    void timer0() interrupt 1 {
        if (count % 2 == 0) {   // 如果count为偶数,则LED1亮
            LED1 = 1;
        } else {                // 否则LED1灭
            LED1 = 0;
        }
    }
    
    void int0() interrupt 0 {
        count++;
    }
    
    void main() {
        init_timer0();  // 初始化定时器0
        IE = 0x81;      // 开启中断,允许外部中断0和定时器0中断
        while (1);
    }
    

如果我的建议对您有帮助、请点击采纳、祝您生活愉快

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7804871
  • 这篇博客你也可以参考下:单片机C语言实现呼吸灯代码,中断执行
  • 除此之外, 这篇博客: 这是我看过最全面讲解嵌入式C语言回调函数和函数指针的教程中的 函数指针结构体 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 但是很多时候我们一般在结构体中定义函数指针用的比较多一点。下面再举一个简单的例子。

    #include "sys.h"
    #include "led.h"
    #include "delay.h"
    #include "usart.h"
    /****************************************
     * 函数指针结构体 开发者写的结构体
    ***************************************/
    typedef struct
    {
        uint8_t (*p_sum)(uint8_t, uint8_t);
        uint8_t (*p_sub)(uint8_t, uint8_t);
        uint8_t (*p_mul)(uint8_t, uint8_t);
        float   (*p_div)(uint8_t, uint8_t);
    } Operation_T;
    
    /*声明结构体变量g_Operation*/
    Operation_T  g_Operation;
    
    /*使用者写的回调函数*/
    uint8_t cal_sum(uint8_t a, uint8_t b)
    {
        return a + b;
    }
    /*使用者写的回调函数*/
    uint8_t cal_sub(uint8_t a, uint8_t b)
    {
        return a - b;
    
    }
    /*使用者写的回调函数*/
    uint8_t cal_mul( uint8_t a, uint8_t b)
    {
        return a * b;
    
    }
    /*使用者写的回调函数*/
    float cal_div(uint8_t a, uint8_t b)
    {
        return a / b;
    
    }
    /*结构体变量g_Operation初始化*/
    Operation_T g_Operation = {cal_sum, cal_sub, cal_mul, cal_div};
    
    int main(void)
    {
        delay_init();
        uart_init(9600);
    
        printf("www.zhiguoxin.cn\r\n");
        printf("微信公众号:果果小师弟\r\n");
    
        uint8_t a = 10;
        uint8_t b = 8;
        /*使用函数指针调用函数*/
        printf("%d\r\n", g_Operation.p_sum(a, b));
        printf("%d\r\n", g_Operation.p_sub(a, b));
        printf("%d\r\n", g_Operation.p_mul(a, b));
        printf("%f\r\n", g_Operation.p_div(a, b));
    
        while(1)
        {
        }
    }
    

  • 您还可以看一下 Abel小智老师的嵌入式开发系统学习路线 从基础到项目 精品教程 工程师必备课程 物联网课程中的 C语言开发基础介绍小节, 巩固相关知识点