嵌入式软件--51单片机 DAY 4

2024-09-07 03:44

本文主要是介绍嵌入式软件--51单片机 DAY 4,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、蜂鸣器

当电流通过线圈时会产生电磁场,电磁场与永磁体相互作用,从而使金属膜产生震动而发声。为使金属膜持续震动,蜂鸣器需要使用震荡电路进行驱动。有些蜂鸣器元件内部自带震荡驱动电路,这种蜂鸣器叫做有源蜂鸣器(Active Buzzer,自激式蜂鸣器);而有些则不带震荡驱动电路,这种蜂鸣器叫做无源蜂鸣器(Passive Buzzer,它激式蜂鸣器)。

1.原理图

2.软件实现

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"
#include "Util.h"void Int_Buzzer_Buzz()
{unsigned char counter = 100;while (counter) {BUZZ = ~BUZZ;Delay1ms(1);--counter;}
}

main.c 

#include "Int_DigitalTube.h"
#include "Int_MatrixKey.h"
#include "Int_Buzzer.h"
int main()
{u8 key_pressed = 0;Int_DigitalTube_Init();Int_DigitalTube_DisplayNum(key_pressed);while (1) {key_pressed = Int_MatrixKey_CheckKey();if (key_pressed) {Int_DigitalTube_DisplayNum(key_pressed);Int_Buzzer_Buzz(); //按键提示音}Int_DigitalTube_Refresh();}
}

 

二、中断系统

1.概念

中断系统是单片机用于处理外部紧急事件的一种机制。中断系统工作的大致流程如下图所示:当CPU正在处理某项任务时,外部发生了某个紧急事件,此时CPU会暂停当前的工作,转而去处理这个紧急事件,处理完之后,再回到原来被中断的位置,继续处理原来的工作。

中断系统使单片机能够实时响应外部事件,提高了系统的灵活性和响应能力。

中断源

中断源是指能够引发中断的事件。

中断标志位

中断标志位用于标识某个中断是否发生,每个中断源都有一个与之对应的中断标志位。当某个中断发生时,相应的中断标位就会置为1,当CPU检测到标志位时,就会处理相应的中断。当中断处理完毕后,中断标志位需要复位(置0),以便接收下一次中断,有些中断源的标志位,会在CPU处理完中断后,自动复位,而有些则需要开发者手动复位,在使用中断时,需要注意查看手册说明。

中断服务程序

中断服务程序指处理中断的逻辑,当某个中断标志位置1时,CPU会自动执行相应的中断服务程序。

中断优先级

中断优先级是指在多个中断同时发生时,单片机响应中断的先后顺序,并且高优先级的中断可以打断低优先级的中断。

中断源:

STC89C52RC共有8个中断源,8个中断源可分为3类,3个类别分别是外部中断(4个)、定时器中断(3个)、串口中断(1个)。

2.外部中断

外部中断是指由单片机外部的紧急事件触发的中断,通过向单片机的特定引脚发送特定的信号触发。STC89C52RC共提供了4个外部中断引脚,分别是INT0,INT1,INT2,INT3,如下图所示。

51单片机的外部中断支持两种触发方式,分别是低电平触发下降沿触发

3.定时器中断

定时器中断是指由单片机内部的定时器触发的中断。

定时器是大多数单片机都具备的一个功能模块,用于实现定时任务。其用法是,设置一个定时值,然后开始计时,待计时结束后,触发相应的定时器中断,开发者可以在中断服务程序中编写定时任务的逻辑。

STC89C52RC共有三个定时器,分别是Timer0、Timer1、Timer2,每个定时器都有一个相对应的中断。

4.串口中断

串口中断是由单片机串口触发的中断。

串口是单片机用于收发数据的重要接口之一,当单片机通过串口接收到数据或者发送完数据后都会触发相应的中断。

STC89C52RC的串口引脚为TxD和RxD,其中TxD用于发送数据,RxD用于接收数据,如下图所示。


5.中断服务程序

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

STC89C52RC共有8个中断源,分为4个外部中断、3个定时器中断和1个串口中断,开发者可以为每个中断源声明相应的中断服务程序,中断服务程序的声明语法如下。

6.中断优先级

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

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

三、外部中断

需求:使用外部中断的方式,一键控制LED灯的亮灭。

1.硬件设计

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

2.使用说明

(1)启用中断

默认情况,CPU会屏蔽所有中断请求,也就是说CPU不会响应任何中断请求,要使用中断,必须先进行启用。

每个中断源是否被启用,是由单片机内部的两个寄存器控制的,这两个寄存器分别是IE(Interrupt Enable,中断允许)寄存器和XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器。

从上图可以看出,STC89C52系列的中断系统具有两级控制,首先是EA总控制位,其次是每个中断源各自的控制位。因此若需要启用某个中断,需要先将总控制位EA置位1,再将该中断自身的控制位置为1。//EA=1

(2)配置外部中断触发方式

STC89C52系列的外部中断支持两种触发方式,分别是低电平触发和下降沿触发,4个外部中断各需要1个控制位用于设置触发方式,这4个控制位分布于如下两个寄存器中,分别是XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器中、TCON(Timer 0 and 1 Control寄存器,如下图所示。

4个控制位的具体作用可参考下图(STC89C52系列中断系统结构图)。

(3)配置中断优先级

STC89C52系列的中断系统支持四个优先级,所以每个中断源的优先级都需要通过2个控制位进行配置,8个中断源共需要16个控制位,这16个控制位分布在如下3个寄存器中,分别是IPH(Interrupt Priority High,中断优先级高位)寄存器,IP(Interrupt Priority Low,中断优先级低位)寄存器,XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器。

(4)定义中断服务程序

外部中断0到外部中断3的中断号分别是:0、2、6、7,以外部中断0为例,其中断服务程序应定义为

void INT0_Handler() interrupt 0{}

3.软件设计

实现思路:

(1)启用外部中断0

//打开中断总开关
EA=1;
//打开外部中断0开关
EX0=1;

(2)配置外部中断0的触发方式

下降沿触发

IT0=1;

(3)只有一个中断,优先级不考虑

(4)中断服务程序

void INT0_Func() interrupt 0
{LED0=~LED0;
}

完整代码:

#include <STC89C5xRC.H> //包含STC89C52的头文件#define LED0   P00void Init_INT0()
{// 打开中断总开关EA = 1;// 打开外部中断0开关EX0 = 1;// 配置外部中断为下降沿触发IT0 = 1;
}void main()
{Init_INT0();while (1);
}/*** @brief 中断函数中打开LED0,代表当触发中断时,LED0会打开。*        根据我们之前的设置,当按下SW3时,P32为低电平,此时LED0打开。**        interrupt 0表示0号中断触发时执行该函数的逻辑*        如果用C语言编程,中断查询次序就是中断号*/
void INT0_Func() interrupt 0
{// 中断中打开LED0LED0 = ~LED0;
}

四、定时器中断--闪烁LED灯

1.需求:

使用定时器中断的方式实现LED闪烁,具体要求是使用定时器0令LED1每1秒钟闪烁一次。

定时器的基本工作原理,是使用一个n位的脉冲计数器,对时钟信号的脉冲进行计数,每个脉冲加1,当脉冲计数器达到最大值(2n)时,也就是溢出时,触发定时器中断。

2.启用定时器中断

//中断总开关
EA=1;
//定时器0中断开关
ET0=1;

选择定时器工作模式

M1

M0

工作模式

0

0

工作模式0(13位)

0

1

工作模式1(16位)

1

0

工作模式2(8位自动重装载)

1

1

工作模式3(双8位)

计算脉冲初始值

假如现在需要定时1ms,那么1ms需要的脉冲个数应为0.001/(12/11059200),因此定时器的初始值应为65536-0.001/(12/11059200),大约等于64614。

计算完毕后,需要将该值赋予TL0(低8位)和TH0(高8位),如下。

TL0 = 64614;

TH0 = 64614 >> 8;

启动定时器

在做完上述配置后,还需最后一步——启动定时器,启动之后定时器才会开始工作。定时器的启动可由单片机内部的寄存器控制,也可由单片机的外部引脚控制。具体控制逻辑如下图所示。

当GATE=0时,外部引脚(INT0,P3.2)无效,此时只能由内部寄存器TR0控制,当TR0=1时,脉冲计数器开始计数,TR0=0时,停止计数。

当GATE=1时,外部引脚(INT0,P3.2)生效,此时只有当内部寄存器TR0和外部引脚INT0都为1时,脉冲计数器才开始计数,否则停止计数。

3.定义中断服务程序

void Timer0_Hander() interrupt 1

{

    //编写定时任务逻辑

}

4.软件设计

(1)启用定时器中断

EA=1;
ET0=1;

(2)选择定时器0的工作模式

GATE=0 C/T=0 M1=0 M0=1

C/T是TMOD寄存器中定时器0的控制位,选择定时器C/T应为0.

故,TMOD寄存器低四位是0001,高四位保持原值。

TMOD&=0xF0;//高四位不变,低四位归零。

TMOD|=0x01;//高四位不变,最低位变1.

(3)启动定时器

GATE已经设置为0,只要TR0=1,即可启动。

(4)定义中断服务程序

void Timer0_Hander() interrupt 1
{
static unsigned int count = 0;//重新状态脉冲计数器TL0 = 64614;TH0 = 64614 >> 8;//统计中断次数if (count++ >= 500) {LED1  = ~LED1;count = 0;}
}

5.完整代码

Dri_Timer0.c

#include "Dri_Timer0.h"
#include <STC89C5xRC.H>
void Dri_Timer0_Init()
{EA=1;//总开关ET0=1;//定时器0开关//定时器0工作方式TMOD&=0xF0;TMOD|=0x01;//脉冲计数器初始值TL0=64614;TH0=64614>>8;//启动定时器TR0=1;}

Dri_Timer0.h

#ifndef __DRI_TIMER0_H__
#define __DRI_TIMER0_H__void Dri_Timer0_Init();//定时器0开关,启动函数#endif /* __DRI_TIMER0_H__ */

main.c

#include <STC89C5xRC.H>
#include "Dri_Timer0.h"
#include "Com_Util.h"
#define LED1 P00
void main()
{Dri_Timer0_Init();while(1);
}
//定时中断服务程序
void Timer0_Hander() interrupt 0
{LED1=~LED1;Com_Util_Delay1ms(500);
}

6.定时器封装

为使定时器使用起来更加方便和通用,我们可以将定时器代码进一步封装。

(1)思路

初始化定时器-->中断服务程序,轮询调用函数.

这篇关于嵌入式软件--51单片机 DAY 4的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143962

相关文章

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

Linux基础入门 --9 DAY

文本处理工具之神vim         vi和vim简介 一、vi编辑器 vi是Unix及类Unix系统(如Linux)下最基本的文本编辑器,全称为“visual interface”,即视觉界面。尽管其名称中包含“visual”,但vi编辑器实际上工作在字符模式下,并不提供图形界面。vi编辑器以其强大的功能和灵活性著称,是Linux系统中不可或缺的工具之一。 vi编辑器具有三种主要的工作模

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

[Day 73] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

AI在健康管理中的應用實例 1. 引言 隨著健康管理需求的提升,人工智能(AI)在該領域的應用越來越普遍。AI可以幫助醫療機構提升效率、精準診斷疾病、個性化治療方案,以及進行健康數據分析,從而改善病患的健康狀況。這篇文章將探討AI如何應用於健康管理,並通過具體代碼示例說明其技術實現。 2. AI在健康管理中的主要應用場景 個性化健康建議:通過分析用戶的健康數據,如飲食、運動、睡眠等,AI可

Vue day-03

目录 Vue常用特性 一.响应更新 1. 1 v-for更新监测 1.2 v-for就地更新 1.3 什么是虚拟DOM 1.4 diff算法更新虚拟DOM 总结:key值的作用和注意点: 二.过滤器 2.1 vue过滤器-定义使用 2.2 vue过滤器-传参和多过滤器 三. 计算属性(computed) 3.1 计算属性-定义使用 3.2 计算属性-缓存 3.3 计算属

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品