51单片机之蜂鸣器、中断系统、点阵LED

蜂鸣器

蜂鸣器是一种能够发出声音的电子元器件,常用于报警、提示和音频信号输出等场景。

  1. 有些蜂鸣器元件内部自带震荡驱动电路,这种蜂鸣器叫做有源蜂鸣器(Active Buzzer,自激式蜂鸣器);而有些则不带震荡驱动电路,这种蜂鸣器叫做无源蜂鸣器(Passive Buzzer,它激式蜂鸣器)。

要求:为按键矩阵增加按键提示音,要求按键按下后,蜂鸣器响0.1s。

  1. 无源蜂鸣器:
  2.  从外部输入一定频率的方波,方波的频率就是蜂鸣器发声的频率,这里使用500Hz的方波                                                                                                                                        
  3. 代码实现
// Int_DigitalTube.h 
#ifndef __INT_DIGITALTUBE_H__
#define __INT_DIGITALTUBE_H__
#define SMG_EN P36
#define LED_EN P34

#include "Com_Util.h"

void Int_DigitalTube_Init();
void Int_DigitalTube_DisplayNum(s32 num);
void Int_DigitalTube_Refresh();

#endif /* __INT_DIGITALTUBE_H__ */

// Int_DigitalTube.c
#include "Int_DigitalTube.h"
#include <STC89C5xRC.H>
static u8 s_codes[11] = {
    0x3F, // 0
    0x06, // 1
    0x5B, // 2
    0x4F, // 3
    0x66, // 4
    0x6D, // 5
    0x7D, // 6
    0x07, // 7
    0x7F, // 8
    0x6F, // 9
    0x40  // -
};

// 存放显示的数的缓存
static u8 s_buffer[8];

//  打开数码管的输入使能
void Int_DigitalTube_Init()
{
    SMG_EN = 0;
    LED_EN = 0;
}
static void Int_DigitalTube_DisplaySingle(u8 position, u8 num_code)
{
    // 关闭当前数码管 否则数码管将有重影
    P0 = 0x00;
    // 位选
    // 先将要显示的数左移 3 位
    position <<= 3;
    // 按位与 将P1 的 p13、P14、P15 位置的数变为0
    P1 &= 0xC7;
    // 按位或 |  将 P1 的 p13、P14、P15 位置和 position 相应位置数交换
    P1 |= position;
    // 段选 需要放置的数字
    P0 = num_code;
}

// 将显示的数放在缓存里
void Int_DigitalTube_DisplayNum(s32 num)
{
    u8 i;
    // 将显存清零
    for (i = 0; i < 8; i++) {
        s_buffer[i] = 0x00;
    }

    if (num < 0) { // 这个功能不需要考虑
        num = -num; // 取绝对值
        i   = 7;    // 从最右侧开始显示数字
        // 将每个位上的数放入显存,从右向左填充
        while (num > 0) {
            s_buffer[i] = s_codes[num % 10];
            num /= 10;
            i--;
        }
        // 如果是负数,将负号放在数字之前的一位
        if (i < 7) {
            s_buffer[i] = s_codes[10]; // s_codes[10] 对应负号 '-'
        }
    } else if (num > 0) {
        i = 7; // 正数从最右侧开始显示
        while (num > 0) {
            s_buffer[i] = s_codes[num % 10];
            num /= 10;
            i--;
        }
    } else {
        // 如果 num == 0 ,将0 放在最右边
        s_buffer[7] = s_codes[0];
    }
}

// 循环多次刷新数码管
void Int_DigitalTube_Refresh()
{
    u8 i;
    for (i = 0; i < 8; i++) {
        Int_DigitalTube_DisplaySingle(i, s_buffer[i]);
        Com_Util_Delay1ms(1); // 延时
    }
}


// Int_KeyMatrix.h
#ifndef __INT_KEYMATRIX_H__
#define __INT_KEYMATRIX_H__

#include "Com_Util.h"
#include <STC89C5xRC.H>

u8 Int_KeyMatrix_CheckSW();

#endif /* __INT_KEYMATRIX_H__ */

// Int_KeyMatrix.c
#include "Int_KeyMatrix.h"

u8 Int_KeyMatrix_CheckSW() {
    u8 i, j;
    u8 lines[4] = {0xFE, 0xFD, 0xFB, 0xF7};
    u8 columns[4] = {0x10, 0x20, 0x40, 0x80};
    for (i = 0; i < 4; i++) {
        P2 = lines[i];
        for ( j = 0; j < 4; j++) {
            if ((P2 & columns[j]) == 0x00) {
                Com_Util_Delay1ms(10);
                if ((P2 & columns[j]) == 0x00) {
                    while ((P2 & columns[j]) == 0x00);
                    return 5 + j + 4 * i;
                }
            }
        }
    }
    return 0;
}

// Int_Buzzer.h
#ifndef __INT_BUZZER_H__
#define __INT_BUZZER_H__
#include <STC89C5xRC.H>
#define BUZZ P46

/**
 * @brief 蜂鸣器响0.1s
 *
 */
void Int_Buzzer_Buzz();

#endif /* __INT_BUZZER_H__ */

// Int_Buzzer.c

#include "Int_Buzzer.h"

void Int_Buzzer_Buzz() {
    u8 counter = 100;
    while(counter) {
    BUZZ = ~BUZZ;
    Com_Util_Delay1ms(1);
    counter--;
}

// main.c
#include "Int_DigitalTube.h"
#include "Int_KeyMatrix.h"
#include "Int_Buzzer.h"
void main()
{
    u8 key;
    Int_DigitalTube_Init();
    while(1) {
        key = Int_KeyMatrix_CheckSW();
        if (Key) {
            Int_DigitalTube_DisplayNum(key);
            Int_Buzzer_Buzz();
        }
        Int_DigitalTube_Refresh();
    }
}

中断系统

  1. 中断系统是单片机用于处理外部紧急事件的一种机制。
  2. 当CPU正在处理某项任务时,外部发生了某个紧急事件,此时CPU会暂停当前的工作,转而去处理这个紧急事件,处理完之后,再回到原来被中断的位置,继续处理原来的工作。
  3.   中断系统使单片机能够实时响应外部事件,提高了系统的灵活性和响应能力。                                                           
  4. 中断源:中断源是指能够引发中断的事件。
  5. 中断标志位:中断标志位用于标识某个中断是否发生,每个中断源都有一个与之对应的中断标志位。当某个中断发生时,相应的中断标位就会置为1,当CPU检测到标志位时,就会处理相应的中断。当中断处理完毕后,中断标志位需要复位(置0),以便接收下一次中断,有些中断源的标志位,会在CPU处理完中断后,自动复位,而有些则需要开发者手动复位。
  6. 中断服务程序:中断服务程序指处理中断的逻辑,当某个中断标志位置1时,CPU会自动执行相应的中断服务程序。
  7. 中断优先级:中断优先级是指在多个中断同时发生时,单片机响应中断的先后顺序,并且高优先级的中断可以打断低优先级的中断。
  8. 中断源:STC89C52RC共有8个中断源,8个中断源可分为3类,3个类别分别是外部中断、定时器中断、串口中断,下面简要介绍每种类型。
  9. 外部中断是指由单片机外部的紧急事件触发的中断,通过向单片机的特定引脚发送特定的信号触发。STC89C52RC共提供了4个外部中断引脚,分别是INT0,INT1,INT2,INT3。
  10. 触发方式:51单片机的外部中断支持两种触发方式,分别是低电平触发下降沿触发
  11. 定时器中断:定时器中断是指由单片机内部的定时器触发的中断。
  12. STC89C52RC共有三个定时器,分别是Timer0、Timer1、Timer2,每个定时器都有一个相对应的中断。

  13. 串口中断:串口中断是由单片机串口触发的中断。串口是单片机用于收发数据的重要接口之一,当单片机通过串口接收到数据或者发送完数据后都会触发相应的中断。STC89C52RC的串口引脚为TxD和RxD,其中TxD用于发送数据,RxD用于接收数据。

  14. 中断服务程序:中断服务程序是指用于处理中断的一段代码,当中断发生时,CPU就会暂停当前程序的执行,转而执行对应的中断服务程序,处理完中断后再恢复到原来的程序。                                                                                                                                          

  15. 中断优先级:STC89C52RC共有四个中断优先级,每个中断源都可以单独设置优先级。若多个中断同时发生,优先级高的会被优先处理;若两个中断的优先级相同,则根据其中断号决定处理顺序,中断号越小越优先。

  16. 高优先级的中断还可以打断低优先级的中断,也就是说当CPU正在处理一个中断时,又发生了另外一个优先级比它还高的中断,此时CPU会暂停原来中断的服务程序,转而去处理这个高优先级的中断,处理完之后,再回到原来低优先级的中断服务程序。这个机制叫做中断嵌套,STC89C52RC支持两级中断嵌套。

外部中断

  1.  通过外部中断的方式检测按钮,必须将按钮接入4个外部中断引脚之一,如下图所示,可以看到SW3可用于触发外部中断0。                                                                                       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值