单片机原理及技术(三)—— AT89S51单片机(二)(C51编程)
一、AT89S51单片机的并行I/O端口
1.1 P0口
AT89S51的P0口是一个通用的I/O口,可以用于输入和输出。每个引脚都可以通过软件控制为输入或输出模式。
1.1.1 P0口的工作原理
P0口的工作原理是通过对P0寄存器的读写操作来控制P0口的引脚。
-
输出模式:当P0口配置为输出模式时,可以通过对P0寄存器进行写操作来控制引脚的电平状态。写入“0”将相应引脚置为低电平(0V),写入“1”将相应引脚置为高电平(Vcc,即供电电压),实现对外部设备的控制。
-
输入模式:当P0口配置为输入模式时,可以通过对P0寄存器进行读操作来获取外部设备输入的电平状态。读取P0寄存器的值,可以得知相应引脚的电平,如果读取值为“0”,表示引脚为低电平,如果读取值为“1”,表示引脚为高电平。
1.2 P1口
AT89S51的P1口是一个具有8个引脚的I/O口,可以用于输入和输出操作,可以配置为输入或输出模式,可以使用上拉电阻和推挽电路配置。
1.2.1 P1口的工作原理
P1口也是一种数字输入/输出(I/O)端口,其工作原理与P0口类似,但具有一些特定的功能和特性。
P1口通常可用于各种用途,如外部中断,定时器/计数器的输入/输出。以下是P1口的一般工作原理:
-
输入模式:在输入模式下,P1口可以接收外部电路传输的电平信号。当外部电路输出低电平(0V)时,P1口会读取到一个逻辑低电平(0);当外部电路输出高电平(3.3V或5V)时,P1口会读取到一个逻辑高电平(1)。这样,通过读取P1口的电平状态,可以判断外部设备的状态或传送外部设备的数据。
-
输出模式:在输出模式下,P1口可以向外部电路发送电平信号。通过将P1口设置为输出模式,并向其写入逻辑低电平(0)或逻辑高电平(1),可以控制外部电路的工作状态或发送数据。
1.3 P2口
AT89S51的P2口是一个8位的双向I/O口,可以用于输入和输出。P2口的特殊功能是通过该端口的位定义来选择。默认情况下,P2口的所有引脚都是作为GPIO引脚使用。
1.3.1 P2口的工作原理
P2口的默认状态是输入模式。要将P2某一位设置为输出模式,只需将相应的P2寄存器位设置为1即可。
- 当P2口设置为输出模式时,可以通过对P2寄存器位的设置来控制相应的引脚输出高电平(1)或低电平(0)。
- 当P2口设置为输入模式时,可以通过对P2寄存器位的读取来获取相应引脚的输入状态。例如,读取P2寄存器的P2.0位,可以获取P2.0引脚的输入状态(高电平或低电平)。
注意:
- 在将P2口的某一位设置为输出模式时,要确保相应引脚上的外部设备可以接受输出信号,并且要注意电流和电压等规格的限制。
1.4 P3口
P3口的引脚分别为P3.0~P3.7,可以通过程序配置为输入或输出。对于输出模式,可以通过设置对应的P3寄存器来输出高电平或低电平电压。对于输入模式,可以通过读取P3寄存器的状态来获取引脚的电平状态。
注意:
- P3口同时也作为一些特殊功能的引脚,如外部中断、定时器/计数器输入等。
1.4.1 P3口的工作原理
P3口是AT89S51单片机的一个8位双向口。它可以通过配置为输入或输出模式来进行相应的操作。
- 在输出模式下,可以通过设置P3口的相应位来输出高电平或低电平电压。对于P3.0至P3.7,可以使用软件指令来设置或清除相应的位。设置位将引脚拉高为高电平,而清除位将引脚拉低为低电平。
- 在输入模式下,P3口可以用来读取外部设备或传感器的状态。通过读取P3口的相应位,程序可以获取到对应引脚的电平状态(高电平或低电平)。
- 除了一般的输入/输出功能,P3口还有一些特殊功能。其中,P3.2和P3.3可以用作外部中断引脚,用于接收外部中断信号。P3.4和P3.5可以作为定时器/计数器的输入引脚。这些功能需要在使用之前进行相应的配置,以使P3口能够正确地工作。
二、时钟电路与时序
下面是AT89S51的时钟电路和时序相关的特点:
时钟电路: AT89S51的时钟电路由晶体振荡器和相关外部元件组成。它支持使用外部晶体振荡器或外部时钟源作为时钟信号。晶体振荡器接口可以接入一个8MHz的陶瓷晶体,或外部时钟信号。
时序特点: AT89S51的时序特点包括以下几个方面:
- 时钟频率:AT89S51的工作时钟频率为最高为33MHz。时钟频率由供电电压和晶体振荡器的频率决定。
- 存取时间:AT89S51的存取时间(即指令执行时间)为1个机器周期。机器周期是时钟周期与机器指令执行时间之和。以8MHz的晶振为例,机器周期时间为1/8MHz=125ns。
- 中断响应时间:AT89S51的中断响应时间为2机器周期。即在发生中断请求后,芯片最多需要2个机器周期才能进入中断服务程序。
- 复位时间:AT89S51的复位时间为2机器周期。即在复位引脚(RST)变为高电平后,芯片最多需要2个机器周期才能执行正常的程序。
2.1 时钟电路设计
2.1.1 内部时钟方式
AT89S51单片机的内部时钟方式包括两种:晶振模式和RC振荡模式。
-
晶振模式:在晶振模式下,单片机使用外部晶体振荡器作为主时钟源。晶体振荡器通过外部晶体与XTAL1和XTAL2引脚连接,提供稳定的时钟信号。晶振模式具有更高的精度和稳定性,适用于对时钟要求较高的应用。
-
RC振荡模式:在RC振荡模式下,单片机使用内部RC振荡电路作为主时钟源。RC振荡电路包括一个电容和一个电阻,通过内部电阻和电容的组合来产生时钟信号。RC振荡模式成本低廉,但时钟信号精度和稳定性较差,适用于对时钟要求不那么严格的应用。
2.1.2 外部时钟方式
AT89S51单片机支持两种外部时钟方式:晶体振荡器模式和外部时钟源模式。
-
晶体振荡器模式: 在晶体振荡器模式下,需要使用一个晶体振荡器将外部时钟信号输入到单片机的XTAL1和XTAL2引脚。晶体的频率可以根据实际需求选择,常见的频率为11.0592MHz或12MHz。单片机通过内部的时钟电路将晶体振荡器输出的时钟信号分频,生成系统时钟,供CPU和其他模块使用。
-
外部时钟源模式: 在外部时钟源模式下,可以直接将外部时钟源信号输入到单片机的XTAL1引脚,而XTAL2引脚保持悬空或接地。外部时钟源的频率可以根据实际需求选择,一般情况下,输入频率应小于单片机支持的最大外部时钟频率。
在程序中,需要通过设置单片机的相关寄存器来选择使用哪种外部时钟方式。对于晶体振荡器模式,可以通过设置相应的位来选择晶体振荡器的频率;对于外部时钟源模式,需要设置相应的位来使能外部时钟源,并设置外部时钟的频率。
以下是一个使用晶体振荡器模式的示例程序:
#include <REG51.h>void main()
{// 设置晶体振荡器的频率为11.0592MHzOSCXCN = 0x67; // 配置晶体振荡器模式和频率while (!(OSCXCN & 0x80)); // 等待晶体振荡器稳定// 设置系统时钟为晶体振荡器模式AUXR &= 0xF7; // 清除定时器2的时钟源选项位// 其他代码...while (1){// 主循环}
}
2.1.3 时钟信号的输出
AT89S51单片机的时钟信号输出主要有两个方式:XTAL2引脚输出和P3.4引脚输出。
-
XTAL2引脚输出: 在晶体振荡器模式下,XTAL2引脚可以用作时钟信号的输出。单片机内部的时钟电路通过分频晶体振荡器的时钟信号生成系统时钟,系统时钟经过处理后就会驱动XTAL2引脚输出相应的时钟信号。XTAL2引脚的输出频率通常是输入时钟频率的一半。
-
P3.4引脚输出: P3.4是AT89S51单片机的一个通用I/O口,可以通过编程将其配置为时钟信号的输出。需要设置P3.4为输出模式,并将相应的寄存器设置为输出高电平或低电平,来控制P3.4引脚输出时钟信号。需要注意的是,P3.4引脚是具有上拉电阻的,因此在将其配置为输出低电平时,需要将其外接到地,以确保输出为低电平。
以下是使用P3.4引脚作为时钟信号输出的示例程序:
#include <REG51.h>void main()
{// 将P3.4引脚配置为输出模式P3 &= 0xEF; // 将P3.4引脚置为0,即输出低电平P3 |= 0x10; // 将P3.4引脚置为1,即输出高电平// 其他代码...while (1){// 主循环}
}
2.2 机器周期、指令周期与指令时序
AT89S51单片机的机器周期、指令周期和指令时序如下:
-
机器周期: AT89S51单片机使用外部时钟源进行时钟信号的驱动。机器周期取决于所选择的外部时钟源频率(晶振频率)。一般情况下,AT89S51的机器周期为12个时钟周期。例如,如果使用12MHz的晶振,那么每个机器周期的时钟周期就是1微秒(1/12MHz)。
-
指令周期: AT89S51的指令周期通常为12个机器周期。因此,在使用12MHz晶振的情况下,每个指令周期的时钟周期为12微秒。每条指令按照这个指令周期来执行。
-
指令时序: AT89S51的指令时序是由内部控制单元生成的。它定义了每个指令在执行时的各个阶段,并且需要按照时钟信号进行同步。在每个指令周期内,有不同的阶段,如取指令、译码、执行、存储结果等。每个阶段需要满足一定的时间要求,以确保指令的正确执行。
三、复位操作和复位电路
3.1 复位操作
在AT89S51单片机中,复位操作可以通过以下方法进行:
-
外部电源复位:将单片机的Vcc电压降至低电平(通常为0V)并持续一段时间,然后恢复到正常电压(通常为5V),即可触发复位操作。
-
内部复位:通过设置单片机内部的复位标志位来触发复位操作。可以通过编写程序来实现内部复位,具体代码如下:
#include <8051.h>void main()
{EA = 0; // 关闭总中断RSTFR = RSTFR | 0x01; // 设置复位标志位EA = 1; // 打开总中断while(1){// 程序运行主体}
}
在以上代码中,通过设置RSTFR(复位标志寄存器)的最低位为1,即可触发复位操作。设置复位标志位之前需要先关闭总中断(EA=0),设置完成后再打开总中断(EA=1)。
下面是在AT89S51单片机复位时,部分片内寄存器的状态表格:
寄存器名称 | 复位后状态 |
---|---|
P0 | 0xFF |
P1 | 0xFF |
P2 | 0xFF |
P3 | 0xFF |
PSW | 0x00 |
ACC | 0x00 |
B | 0x00 |
SP | 0x07 |
DPL | 0x00 |
DPH | 0x00 |
IP | 0x00 |
IE | 0x00 |
TMOD | 0x00 |
TCON | 0x00 |
TH0 | 0x00 |
TL0 | 0x00 |
TH1 | 0x00 |
TL1 | 0x00 |
SCON | 0x00 |
SBUF | 0x00 |
IE | 0x00 |
IP | 0x00 |
EA | 0x00 |
RSTFR | 0x00 |
T2CON | 0x00 |
RCAP2L | 0x00 |
RCAP2H | 0x00 |
TL2 | 0x00 |
TH2 | 0x00 |
上表列出了复位后的部分寄存器状态,其中:
- 端口寄存器(P0, P1, P2, P3)的状态为0xFF,表示所有引脚为高电平输入状态;
- 程序状态字寄存器(PSW)的状态为0x00,表示所有标志位都被清零;
- 累加器(ACC)和B寄存器的状态为0x00,表示内容被清零;
- 堆栈指针(SP)的状态为0x07,指向上一次使用的栈顶位置;
- 定时器、串口等相关寄存器的状态为0x00,表示所有配置被清零。
3.2 复位电路设计
AT89S51单片机的复位电路一般由三部分组成:复位电路、晶振电路和电源电路。
-
复位电路:复位电路主要是用来实现单片机的复位功能,确保在单片机上电或外部复位信号发生时,单片机能正常地进行初始化操作。它通常由一个复位电路芯片(如MAX809)和相关的电阻和电容组成。复位电路芯片有两个功能引脚,一个是复位输入引脚(RST),用于接收复位信号;另一个是复位输出引脚(RESET),用于输出复位信号给单片机。
-
晶振电路:晶振电路主要是用于提供稳定的时钟信号给单片机。AT89S51单片机通常需要外接一个晶振(如12MHz),晶振电路由晶振、两个电容和两个相关电阻组成。其中,晶振接在单片机的两个时钟输入引脚(XTAL1和XTAL2),两个电容和两个电阻分别连接在晶振和地之间,用于稳定晶振的工作。
-
电源电路:电源电路主要是用于为单片机提供稳定的电源。一般来说,AT89S51单片机可以工作在5V的电源电压下。电源电路通常由一个稳压芯片(如7805)和相关的电容和二极管组成。稳压芯片负责将输入的电源电压(如9V)稳压为5V输出给单片机,相关的电容和二极管则用于滤波和保护。
相关文章:

单片机原理及技术(三)—— AT89S51单片机(二)(C51编程)
一、AT89S51单片机的并行I/O端口 1.1 P0口 AT89S51的P0口是一个通用的I/O口,可以用于输入和输出。每个引脚都可以通过软件控制为输入或输出模式。 1.1.1 P0口的工作原理 P0口的工作原理是通过对P0寄存器的读写操作来控制P0口的引脚。 输出模式:当P0口…...

摄影店展示服务预约小程序的作用是什么
摄影店包含婚照、毕业照、写真、儿童照、工作照等多个服务项目,虽然如今人们手机打开便可随时拍照摄影,但在专业程度和场景应用方面,却是需要前往专业门店服务获取。 除了进店,也有外部预约及活动、同行合作等场景,重…...

【数据分析基础】实验一 Python运算符、内置函数、序列基本用法
一、实验目的 熟练运用Python运算符。熟练运用Python内置函数。掌握Python的基本输入输出方法。了解lambda表达式作为函数参数的用法。掌握列表、元组、字典、集合的概念和基本用法。了解Python函数式编程模式。 二、实验内容: 1. 在命令模式测试如下命令&#x…...

【Redis】构建强韧的远程Redis连接与端口保障机制完美指南
【Redis】构建强韧的远程Redis连接与端口保障机制完美指南 大家好 我是寸铁👊 总结了【Redis】构建强韧的远程Redis连接与端口保障机制完美指南✨ 喜欢的小伙伴可以点点关注 💝 前言 在当今的软件开发领域中,远程访问和操作数据存储是极为常见…...

Flowable项目启动报错#java.time.LocalDateTime cannot be cast to java.lang.String
Flowable 项目启动后报错 flow项目第一次启动创建表成功,但是第二次启动时报错信息如下: 1、Error creating bean with name ‘appRepositoryServiceBean’ defined in class 2、Error creating bean with name ‘flowableAppEngine’: FactoryBean t…...

《数字电路》
问答题4*5 在数字电路中,三极管经常工作在哪两种开关状态? 在数字电路中,三极管经常工作在饱和导通状态和截止状态。 时序电路根据输出信号分为哪两类? 时序电路根据输出信号分为莫尔型和米里型两类。 写出三种以上常用的二-十…...
STM32F103 点亮LED闪烁与仿真
STM32F103 点亮LED闪烁与仿真 今天给大家分享一下STM32 流水灯简单的仿真吧,我感觉这个提供有用的,但是自己也是第一次使用,主要是感觉曲线很高级。在PWM中查看脉宽很有用。 code: led.c #include "led.h" #include "delay…...

阿里云服务器发送邮件失败 Could not connect to SMTP host: smtp.xxx.com, port: 465;
最近做了一个发送邮件的功能, 在本地调试完成后,部署到阿里云服务器就一直报错, Could not connect to SMTP host: smtp.qiye.aliyun.com, port: 465; 网上也搜索了很多的资料,最后花了好几个小时才解决, 报错日志如下…...

Socket编程权威指南(二)完美掌握TCP流式协议及Socket编程的recv()和send()
在上一篇文章中,我们学习了Socket编程的基础知识,包括创建Socket、绑定地址、监听连接、接收连接等操作。然而,真正的套接字编程远不止于此。本文将重点介绍TCP 流式协议,什么是粘包问题?如何解决粘包问题 ?…...

当C++的static遇上了继承
比如我们想要统计下当前类被实例化了多少次,我们通常会这么写 class A { public:A() { Count_; }~A() { Count_--; }int GetCount() { return Count_; }private:static int Count_; };class B { public:B() { Count_; }~B() { Count_--; }int GetCount() { return …...

Three.js中的Raycasting技术:实现3D场景交互事件的Raycaster详解
前言 在Web开发中,Three.js是一个极为强大的库,它让开发者能够轻松地在浏览器中创建和展示3D图形。随着3D技术在网页设计、游戏开发、数据可视化等领域的广泛应用,用户与3D场景的交互变得日益重要。而要实现这种交互,一个核心的技…...

5 分钟内构建一个简单的基于 Python 的 GAN
文章目录 一、说明二、代码三、训练四、后记 一、说明 生成对抗网络(GAN)因其能力而在学术界引起轩然大波。机器能够创作出新颖、富有灵感的作品,这让每个人都感到敬畏和恐惧。因此,人们开始好奇,如何构建一个这样的网…...
智能硬件产品中常用的参数存储和管理方案
一、有哪些参数需要管理? 在智能硬件产品中,一般有三类数据需要存储并管理: 1. 系统设置数据 系统设置数据是指产品自身正常工作所依赖的一些参数。 这类数据的特点:只能在生产过程中修改,出厂后用户无权限修改。 比如:产品SN、产品密钥/token/license、传感器校准值…...

SwiftUI中Mask修饰符的理解与使用
Mask是一种用于控制图形元素可见性的图形技术,使用给定视图的alpha通道掩码该视图。在SwiftUI中,它类似于创建一个只显示视图的特定部分的模板。 Mask修饰符的定义: func mask<Mask>(alignment: Alignment .center,ViewBuilder _ ma…...

全光网络与传统网络架构的对比分析
随着信息技术的飞速发展,网络已经成为我们日常生活中不可或缺的一部分。在这个信息爆炸的时代,全光网络和传统网络架构作为两种主流的网络技术,各有其特点和适用范围。本文将对这两种网络架构进行详细的对比分析,帮助读者更好地了…...

stack overflow复现
当你在内存的栈中,存放了太多元素,就有可能在造成 stack overflow这个问题。 今天看看如何复现这个问题。 下图,是我写的程序,不断的创造1KB的栈,来看看执行了多少次,无限循环。 最后结果是7929kB时, 发…...
mybatis使用笔记
文章目录 打印sql日志mybatis-config.xml方式application.yml里面配置配置类配置方式 其他扫描方式官网文档 mybatis用了那么久,实际一直不明白,做个笔记吧。 打印sql日志 实测,mybatis-config.xml方式好用(记得注掉yml里的相关配置) mybat…...

学习笔记——路由网络基础——路由概述
一、路由概述 1、路由定义与作用 路由(routing)是指导报文转发路径信息,通过路由可以确认转发IP报文的路径。 路由:是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程。 路由(routing)的定义是指分…...
在量子计算时代,大数据技术将面临哪些挑战和机遇?
在量子计算时代,大数据技术将面临以下挑战和机遇: 挑战: 处理速度:量子计算机具有极高的计算速度,大数据技术需要适应和充分利用这种速度。现有的大数据算法和架构可能需要重新设计和优化,以充分发挥量子计…...

怎么换自己手机的ip地址
在互联网时代,IP地址已经成为了我们数字身份的一部分。无论是浏览网页、下载文件还是进行在线交流,我们的IP地址都在默默发挥着作用。然而,有时出于安全或隐私保护的考虑,我们可能需要更换手机的IP地址。那么,如何轻松…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...