单片机寄存器相关知识及应用(51单片机)

news2024/12/30 2:28:08

在前面的STM32中我并没有直接对寄存器进行操作,而是通过固件库直接引用进行各个外设的配置和应用,现在,我开始进行寄存器的学习(51单片机)。

我们先简单看一下80C51/52的微控制头文件  <REG52.h>

一、字节寄存器定义

  • 定义了一系列的特殊功能寄存器,如 P0、P1、P2、P3、PSW、ACC、B、SP、DPL、DPH、PCON、TCON、TMOD、TL0、TL1、TH0、TH1、IE、IP、SCON、SBUF。
  • 对于 8052 扩展部分,定义了 T2CON、RCAP2L、RCAP2H、TL2、TH2。

二、位寄存器定义

  1. PSW 相关位
    • 定义了 PSW 寄存器中的各个位,如 CY(进位标志位)、AC(辅助进位标志位)、F0(用户标志位)、RS1 和 RS0(寄存器组选择位)、OV(溢出标志位)、P(8052 特有的奇偶校验位)。
  2. TCON 相关位
    • 定义了 TCON 寄存器中的各个位,如 TF1(定时器 1 溢出标志位)、TR1(定时器 1 运行控制位)、TF0、TR0、IE1、IT1、IE0、IT0。
  3. IE 相关位
    • 定义了 IE 寄存器中的各个位,如 EA(总中断允许位)、ET2(8052 特有的定时器 2 中断允许位)、ES、ET1、EX1、ET0、EX0。
  4. IP 相关位
    • 定义了 IP 寄存器中的各个位,如 PT2、PS、PT1、PX1、PT0、PX0。
  5. P3 相关位
    • 定义了 P3 端口的各个位,如 RD(外部数据存储器读选通位)、WR、T1、T0、INT1、INT0、TXD、RXD。
  6. SCON 相关位
    • 定义了 SCON 寄存器中的各个位,如 SM0、SM1、SM2、REN、TB8、RB8、TI、RI。
  7. P1 相关位(8052 特有的)
    • 定义了 P1 端口的两个位 T2EX 和 T2。
  8. T2CON 相关位
    • 定义了 T2CON 寄存器中的各个位,如 TF2、EXF2、RCLK、TCLK、EXEN2、TR2、C_T2、CP_RL2。

这个微控制器有四个端口,分别是:

  1. P0:8 位并行输入 / 输出端口。
  2. P1:8 位并行输入 / 输出端口。
  3. P2:8 位并行输入 / 输出端口。
  4. P3:8 位并行输入 / 输出端口,同时部分引脚具有第二功能。

比如我们要操作一个蜂鸣器或者一个LED灯的亮暗,我们就可以查看想要在那个引脚处进行驱动,执行高低电平,这里是控制一个低电平触发的蜂鸣器。

sbit等价于set bit,也就是设置引脚的作用,在这个程序中我们设置了P1端口的第1位,并设置为低电平态。

重温继电器:

  • 继电器内部主要由线圈和触点组成。当线圈两端加上合适的电压时,会产生磁场,使触点状态发生改变。在低电平触发的情况下,线圈通过低电平信号驱动电流,从而产生磁场使继电器动作。
  • 继电器的触点可以用于控制外部电路的通断,例如连接高电压、大电流的负载。

使用继电器实现对LED灯的控制

我们如果想写一个延迟的函数可以借助STC—ISP下载器,在这里可以直接生成相对应的代码。

利用震动传感器实现震动感应灯

注:震动传感器为低电平触发

中断知识:

在 51 单片机中,中断是一种重要的机制,它允许单片机在执行主程序的过程中,暂停当前任务,转而去处理更紧急的事件,处理完后再返回原来被中断的地方继续执行主程序

一、中断的作用

  1. 提高系统的实时性:当有紧急事件发生时,能够及时响应,而不必等待主程序循环执行到相应的位置。比如,外部设备发送数据需要立即处理,通过中断可以快速响应,避免数据丢失。
  2. 实现多任务处理:在单一处理器上模拟多任务的效果。不同的中断源可以代表不同的任务,单片机可以根据中断的优先级依次处理这些任务。

二、中断源

51 单片机通常有多个中断源,主要包括:

  1. 外部中断:由外部信号触发,可以设置为低电平触发或下降沿触发。例如,按键按下时产生的外部中断信号。
  2. 定时器中断:当定时器计数溢出时产生中断。可以用于定时控制、产生周期性的信号等。
  3. 串口中断:当串口接收到数据或发送完数据时产生中断,方便进行数据的接收和发送处理。

三、中断优先级

51 单片机具有两级中断优先级,可以设置高优先级和低优先级中断。当多个中断同时发生时,高优先级的中断会先被响应。如果同一优先级的中断同时发生,则按照硬件查询顺序响应。

四、中断的过程

  1. 中断请求:当中断源产生中断信号时,向单片机的中断系统发出中断请求。
  2. 中断响应:如果中断允许标志位(IE 寄存器中的相应位)被置位,并且没有更高优先级的中断正在被处理,单片机就会响应中断。响应中断时,单片机首先完成当前指令的执行,然后将程序计数器(PC)的值压入堆栈保存,接着将相应的中断入口地址装入 PC,开始执行中断服务程序。
  3. 中断服务:在中断服务程序中,处理中断源对应的事件。这是中断处理的核心部分,根据具体的需求编写相应的代码。
  4. 中断返回:中断服务程序执行完毕后,通过执行中断返回指令(RETI),将堆栈中保存的程序计数器的值弹出,恢复到中断前的程序执行位置,继续执行主程序。

中断系统:

8051 单片机的中断控制系统工作程序主要包括以下几个步骤:

一、中断源及相关寄存器设置

8051 单片机有 5 个中断源,分别是外部中断 0(INT0)、外部中断 1(INT1)、定时器 / 计数器 0 溢出中断(T0)、定时器 / 计数器 1 溢出中断(T1)和串行口中断。每个中断源都有相应的控制寄存器来设置其触发方式、使能状态等。

  1. 中断允许寄存器 IE(Interrupt Enable):

    • EA:总中断允许位,EA = 1 时,开放所有中断;EA = 0 时,关闭所有中断。
    • EX0 和 EX1:分别为外部中断 0 和外部中断 1 的允许位。
    • ET0 和 ET1:分别为定时器 / 计数器 0 和定时器 / 计数器 1 溢出中断允许位。
    • ES:串行口中断允许位。
  2. 中断优先级寄存器 IP(Interrupt Priority):

    • PX0 和 PX1:分别为外部中断 0 和外部中断 1 的优先级控制位。
    • PT0 和 PT1:分别为定时器 / 计数器 0 和定时器 / 计数器 1 溢出中断的优先级控制位。
    • PS:串行口中断的优先级控制位。

二、中断触发方式设置

  1. 外部中断触发方式:

    • 通过定时器控制寄存器 TCON 中的 IT0 和 IT1 位来设置外部中断 0 和外部中断 1 的触发方式。
    • IT0 = 0 时,外部中断 0 为低电平触发;IT0 = 1 时,外部中断 0 为下降沿触发。
    • IT1 同理。
  2. 定时器 / 计数器溢出中断:由定时器 / 计数器的计数溢出自动产生中断请求。

三、中断响应过程

  1. 中断请求:当某个中断源满足触发条件时,就会向 CPU 发出中断请求。例如,外部中断源在触发条件满足时,将相应的中断请求标志位置位。

  2. 中断查询:CPU 在每个机器周期的最后一个状态(S6),查询所有中断源的中断请求标志位。如果有中断请求且相应的中断允许位为 1,则进入下一步。

  3. 中断响应:

    • CPU 响应中断后,首先自动执行一条硬件指令 “LCALL” 或 “LJMP”,将程序计数器 PC 的内容压入堆栈保护,然后将相应的中断入口地址装入 PC,转去执行中断服务程序。
    • 8051 单片机的 5 个中断源分别对应 5 个固定的中断入口地址:外部中断 0 为 0003H,外部中断 1 为 0013H,定时器 / 计数器 0 溢出中断为 000BH,定时器 / 计数器 1 溢出中断为 001BH,串行口中断为 0023H。
  4. 中断服务程序执行:在中断服务程序中,根据具体的中断源进行相应的处理操作。例如,对于外部中断,可以读取外部信号状态进行相应的处理;对于定时器中断,可以进行定时操作或计数操作等。

  5. 中断返回:中断服务程序执行完毕后,执行中断返回指令 “RETI”。该指令将堆栈中保存的程序计数器 PC 的值弹出,使程序返回到被中断的地方继续执行。

四、中断优先级处理

当多个中断源同时发出中断请求时,CPU 按照中断优先级进行响应。8051 单片机的中断优先级分为两级,高优先级中断可以中断低优先级中断的服务程序。如果同一优先级的多个中断源同时请求中断,CPU 将按照自然优先级顺序进行响应,其顺序为外部中断 0、定时器 / 计数器 0 溢出中断、外部中断 1、定时器 / 计数器 1 溢出中断、串行口中断。

芯片图:

使用中断:

利用中断实现震动感应灯

注:利用中断可节约CPU资源

#include <REG52.h>
#include <INTRINS.H>

sbit LED = P1^1;	
sbit SHARK = P1^0;
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void init()
{
	EA = 1;//¿ªÆô×ÜÖжÏ
	EX0 =1;//¿ªÆôEX0µÄÍⲿÖжÏ
	IT0=1;//µÍµçƽ´¥·¢·½Ê½
	
	
}

int main()
{
	init();
	
	while(1)
	{
		
	}
	
	return 0;
}


void int0() interrupt 0
{
	  LED = 0;
		Delay500ms();
		LED=1;
		Delay500ms();	

}

定时器相关知识:

一、定时器的作用

  1. 定时功能:可以实现精确的时间延迟,用于控制程序中的时间间隔,例如周期性地执行某些任务、产生定时中断等。
  2. 计数功能:对外部脉冲进行计数,可以用于测量外部事件的频率、脉冲宽度等。

二、定时器的结构

8051 单片机通常有两个定时器 / 计数器:T0 和 T1。每个定时器都由以下部分组成:

  1. 计数器:16 位的计数器,可以对内部机器周期进行计数(定时模式)或对外部脉冲进行计数(计数模式)。
  2. 工作方式寄存器:用于设置定时器的工作方式,如定时 / 计数模式选择、计数位数等。
  3. 控制寄存器:控制定时器的启动、停止、中断等操作。

三、工作方式

  1. 方式 0:13 位定时器 / 计数器。由 THx 的高 8 位和 TLx 的低 5 位组成 13 位计数器。
  2. 方式 1:16 位定时器 / 计数器。THx 和 TLx 组成 16 位计数器。
  3. 方式 2:8 位自动重装定时器 / 计数器。TLx 作为计数器,当计数溢出时,自动将 THx 的内容重装到 TLx 中。
  4. 方式 3:T0 分为两个独立的 8 位定时器 / 计数器,T1 停止计数。

四、定时时间的计算

定时时间取决于计数脉冲的频率和计数器的初值。

  1. 定时模式下,计数脉冲的频率是单片机的时钟频率经过 12 分频得到的。若单片机时钟频率为 fosc,则计数脉冲频率为 fosc/12。
  2. 定时时间 T = (2^n - 计数初值)× 机器周期。其中,n 为计数器的位数(方式 0 时 n = 13,方式 1 时 n = 16,方式 2 时 n = 8),机器周期 = 12 /fosc。

五、定时器的编程步骤

  1. 设置定时器的工作方式:通过对 TMOD 寄存器进行赋值来选择定时器的工作方式、定时 / 计数模式等。
  2. 计算计数初值:根据所需的定时时间,计算出计数器的初值,并分别写入 THx 和 TLx 寄存器。
  3. 启动定时器:将 TRx 位置 1,启动定时器开始计数。
  4. 处理定时器中断(如果需要):当定时器计数溢出时,会产生中断请求。可以在中断服务程序中处理定时任务。

六、应用场景

  1. 实现精确的时间延迟,如控制 LED 的闪烁频率、电机的转速等。
  2. 作为实时时钟的时间基准,实现时钟功能。
  3. 测量外部信号的频率、脉冲宽度等。
  4. 在多任务系统中,作为时间片轮转调度的时钟源。

定时器相关知识:

定时器用于计数系统,可实现软件计时,使程序每隔一段时间完成一项操作

大部分用于替代在程序中长时间delay(函数),从而提高CPU的运行效率和处理速度

STC89C52有3个定时器(T0,T1,T2),这比传统的51单片机多一个T2

该定时器 / 计数器 0 处于模式 1,即 16 位定时器 / 计数器模式。在这种模式下,它可以实现较为精确的定时功能或者对外部事件进行计数。

SYSclk表示系统时钟,定时器和计数器都来自系统时钟,选择不同的时钟模式可以调整计数速度,12T和6T。

12T表示一个机器周期由12个时钟周期组成,6T表示一个机器周期由6个时钟周期组成,所以6T计数速度更快,频率更高,精度更高,但会消耗更多的功率。

“TRO C/T=0 control (8 Bits)”、“TLO (8 bits)” 和 “THO” 分别对应定时器 / 计数器的低 8 位控制寄存器、低 8 位计数器和高 8 位计数器。通过对这些寄存器的设置,可以控制定时器 / 计数器的工作方式,如启动、停止、复位等。

“TFO Interrupt” 表示定时器 / 计数器溢出时可以产生中断。当定时器 / 计数器从初始值计数到最大值后,会产生溢出标志,并可以触发中断请求,以便 CPU 进行相应的处理。

“GATE” 和 “INTO” 可能与外部控制信号和中断输入有关。例如,GATE 可以用于控制定时器 / 计数器的启动和停止是否受外部信号的影响,INTO 可能是外部中断输入引脚。

一、模式 0:13 位定时器 / 计数器

在模式 0 下,定时器 / 计数器被配置为 13 位的计数器。其中,低 5 位由 TLO(定时器 / 计数器低 5 位寄存器)组成,高 8 位由 THO(定时器 / 计数器高 8 位寄存器)的低 5 位组成。

这种模式的计数范围相对较小,但在一些对定时精度要求不高且需要较小计数范围的应用中可能会有用。例如,简单的定时闪烁小灯,或者作为一个简单的时间间隔测量工具。

二、模式 1:16 位定时器 / 计数器(常用)

这是一种较为常用的模式。16 位的定时器 / 计数器由 TLO(低 8 位)和 THO(高 8 位)组成。

它具有较大的计数范围,可以满足大多数一般应用的定时和计数需求。比如,可以用于产生一定时间间隔的中断,以实现周期性的任务执行;或者用于对外部脉冲进行计数,以测量外部事件的发生频率等。

三、模式 2:8 位自动重装载模式

在模式 2 下,定时器 / 计数器被配置为 8 位的计数器。当计数器计满溢出时,自动将一个预先设置好的值重新装载到计数器中,开始下一轮计数。

这种模式的优点是可以在不需要软件干预的情况下实现精确的定时。例如,在需要周期性地产生一个固定时间间隔的中断时,可以使用模式 2。设置好自动重装载的值后,定时器 / 计数器会自动重复计数,无需在每次溢出后通过软件重新设置计数值。

四、模式 3:两个 8 位计数器

在模式 3 下,定时器 / 计数器 0 被分成两个独立的 8 位计数器。其中,TL0 作为一个 8 位计数器使用,而 TH0 则被固定为一个 8 位定时器,只能用于定时功能,不能作为计数器使用。定时器 / 计数器 1 在模式 3 下停止计数。

这种模式在一些特殊的应用场景中可能会有用。例如,当需要同时进行两个不同时间间隔的定时任务,且其中一个任务对定时精度要求较高时,可以使用模式 3 中的 TH0 作为高精度定时器,而 TL0 则用于另一个定时任务。

1.寄存器是连接软硬件的媒介
2.在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式。
3.寄存器相当于一个复杂机器的”操作按钮”

利用定时器控制灯

#include <REG52.h>
#include <INTRINS.H>

sbit LED = P1^1;
sbit SHARK = P1^0;

// 定义一个全局变量 T0count,用于记录定时器 0 的中断次数
unsigned int T0count;

// 定时器初始化函数
void timer_init()
{
    // 设置定时器 0 的工作模式为模式 1(16 位定时器)
    TMOD = 0X01;
    // 清除定时器 0 的溢出标志位
    TF0 = 0;
    // 启动定时器 0
    TR0 = 1;
    // 给定时器 0 的高 8 位赋初值,64535/256
    TH0 = 64535/256;
    // 给定时器 0 的低 8 位赋初值,64535%256
    TL0 = 64535%256;
    // 使能定时器 0 中断
    ET0 = 1;
    // 使能总中断
    EA = 1;
    // 设置定时器 0 中断为高优先级
    PT0 = 1;
}

// 软件延时函数,延时约 500 毫秒(在 11.0592MHz 晶振下)
void Delay500ms()		//@11.0592MHz
{
    unsigned char i, j, k;
    // 空操作指令,用于稍微延迟一点时间(可能是为了确保稳定或其他未知目的)
    _nop_();
    _nop_();
    // 初始化变量 i、j、k
    i = 22;
    j = 3;
    k = 227;
    // 三层嵌套循环实现延时
    do
    {
        do
        {
            // k 递减直到为 0
            while (--k);
        } while (--j);
    } while (--i);
}

// 主函数
void main()
{
    // 调用定时器初始化函数
    timer_init();
    while(1)
    {
        // 主循环中目前没有任何操作,只是空循环等待中断发生
    }
}

// 定时器 0 中断服务函数
void timer0_routine() interrupt 1
{
    // 重新给定时器 0 的高 8 位赋初值,64535/256
    TH0 = 64535/256;
    // 重新给定时器 0 的低 8 位赋初值,64535%256
    TL0 = 64535%256;
    // 定时器 0 的中断次数加一
    T0count++;
    // 当定时器 0 的中断次数达到 1000 时
    if(T0count>=1000)
    {
        // 将 LED 引脚置为低电平,点亮 LED
        LED = 0;
        // 调用软件延时函数,延时约 500 毫秒
        Delay500ms();
        // 将 LED 引脚置为高电平,熄灭 LED
        LED = 1;
        // 再次调用软件延时函数,延时约 500 毫秒
        Delay500ms();
        // 将中断次数重置为 0
        T0count = 0;
    }
}

对于定时器初始化函数timer_init();

  1. TMOD = 0X01;

    • TMOD是定时器 / 计数器的工作方式寄存器。
    • 设置TMOD0X01,表示将定时器 0 设置为工作模式 1,即 16 位定时器模式。在这种模式下,定时器由高 8 位和低 8 位两个寄存器组成,计数范围为 0 到 65535。
  2. TF0=0;

    • TF0是定时器 0 的溢出标志位。
    • 将其初始化为 0,表示当前定时器 0 没有发生溢出。
  3. TR0=1;

    • TR0是定时器 0 的运行控制位。
    • 设置为 1 表示启动定时器 0,开始计数。
  4. TH0=64535/256; 和 TL0=64535%256;

    • TH0是定时器 0 的高 8 位计数器初始值,TL0是低 8 位计数器初始值。
    • 这里将初始值设置为 64535,即当定时器从这个值开始计数,经过一定时间后会产生溢出中断。具体的计数时间取决于晶振频率和定时器的工作模式。
    • 这两个值其实是由2^16-1=64535,TH0=64535/256(2^8)可取得高八位,同理可取得低8位。
  5. ET0=1;

    • ET0是定时器 0 的中断允许位。
    • 设置为 1 表示允许定时器 0 产生中断。
  6. EA=1;

    • EA是总中断允许位。
    • 设置为 1 表示允许所有中断,包括定时器 0 的中断。
  7. PT0=1;

    • PT0是定时器 0 的中断优先级控制位。
    • 设置为 1 表示将定时器 0 的中断设置为高优先级。

综上所述,这个定时器初始化函数的作用是配置定时器 0 为 16 位定时器模式,设置初始计数值,允许中断并启动定时器,同时将定时器 0 的中断设置为高优先级。这样,定时器 0 就可以按照设定的方式进行计数,并在满足条件时产生中断,触发相应的中断服务程序。

串口相关:
这里我只叙述一下前面32单片机没有讲到的知识点。

一、SBUF(串行口缓冲寄存器)

SBUF 在发送和接收过程中起到关键作用。在发送时,写 SBUF 意味着将数据写入发送缓冲寄存器(通常与 TH1、TL1 及发送控制器等相关联),然后数据通过发送控制器和控制门,从 TXD(发送数据引脚)发送出去。在接收时,数据从 RXD(接收数据引脚)进入,经过接收控制器存入 SBUF,此时读 SBUF 可以获取接收到的数据。

二、发送过程

  1. 当向 SBUF 写入数据后,数据会进入发送控制器,同时可能与 TH1 和 TL1(通常与定时器 1 相关)以及 T1 溢出率有关。T1 溢出率可能会影响发送的速率等特性。
  2. 发送控制器根据控制信号和相关设置,将数据通过控制门从 TXD 引脚发送出去。当发送完成后,会触发 TI(发送中断标志位),可以去中断逻辑进行相应处理。

三、接收过程

  1. 数据从 RXD 引脚接收进来,经过接收控制器存入 SBUF。接收控制器可能会根据一些控制信号如 SMOD(电源控制寄存器的双倍波特率位)等进行相应的操作。
  2. 当读取 SBUF 时,可以获取接收到的数据。

四、控制门及其他设置

  1. 控制门在发送和接收过程中起到数据通路的控制作用,确保数据在正确的时间和方向上传输。

一、中断系统概述

中断系统是单片机中非常重要的部分,它允许单片机在执行主程序的过程中,暂停当前任务去响应紧急事件或外部请求,处理完中断事件后再返回主程序继续执行。

二、各个部分的作用

  1. 控制门 TX 和收控利(接收控制):控制数据的发送和接收,确保数据在正确的时间和方向上传输。
  2. 位寄存:可能用于存储特定的状态位或数据位,以便在中断处理过程中进行判断和操作。
  3. TCON(定时器 / 计数器控制寄存器)和 SCON(串行口控制寄存器)
    • TCON 主要用于控制定时器 / 计数器的启动、停止,以及设置中断标志等。例如,IE(中断允许寄存器)和 IP(中断优先级寄存器)可以设置各个中断源的允许和优先级。
    • SCON 主要用于控制串行口的工作方式、接收和发送状态等。
  4. 硬件查询:可以通过查询特定的寄存器状态来判断是否有中断请求发生。
  5. 中断优先级:由 ITO(外部中断 0 触发方式控制位)、EXO(外部中断 0 允许位)、PX(外部中断 0 优先级控制位)等控制外部中断 0 的优先级;同理, INTO(外部中断 1 触发方式控制位)、IEO(外部中断 1 允许位)等控制外部中断 1 的优先级。高级中断源具有更高的优先级,在多个中断同时发生时,优先级高的先被响应。
  6. 中断入口:当中断发生时,程序会跳转到相应的中断入口地址去执行中断服务程序。例如,TO(定时器 / 计数器 T0 溢出中断请求标志位)、T1(定时器 / 计数器 T1 溢出中断请求标志位)、TI(串行口发送中断请求标志位)、TF(串行口接收中断请求标志位)等中断标志位被置位时,会触发相应的中断入口。
  7. 中断激发:外部事件或内部定时器 / 计数器溢出等情况可以激发中断请求。..

配置串口:

#include <REG52.h>
#include <INTRINS.H>
//#include "timer.h"

// 定义连接 LED 的引脚为 P1.1
sbit LED = P1^1;	
// 定义连接 SHARK(假设是某个外部设备)的引脚为 P1.0
sbit SHARK = P1^0;

// 延时 500 毫秒的函数,在 11.0592MHz 晶振频率下
void Delay500ms()		//@11.0592MHz
{
    unsigned char i, j, k;
    _nop_();
    _nop_();
    // 设置三层循环进行延时
    i = 22;
    j = 3;
    k = 227;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

// 串口初始化函数
void uartinit()
{
    // 设置串口控制寄存器 SCON 为只允许发送模式
    SCON=0x40;
    // 设置电源控制寄存器 PCON 的最高位,即 SMOD 位,用于波特率加倍等特殊用途
    PCON |= 0x80;	
    
    // 清除 TMOD 的高四位,保留低四位
    TMOD &= 0X0F;
    // 设置 TMOD 的高四位为 0010,即定时器 1 工作在模式 2(8 位自动重装模式)
    TMOD |=0X20;
    // 启动定时器 1
    TR1=1;
    // 设置定时器 1 的低 8 位初值为 0xF4
    TL1 = 0xF4;		
    // 设置定时器 1 的高 8 位初值也为 0xF4,用于产生特定的波特率
    TH1 = 0xF4;		
    // 禁止定时器 1 中断
    ET1=0;
}

// 串口发送一个字节数据的函数
void UART_sendbit(unsigned char Byte)
{
    // 将待发送的字节放入发送缓冲寄存器 SBUF
    SBUF=Byte;
    // 等待发送完成标志位 TI 置位
    while(TI==0);
    // 手动将 TI 标志位清零,以便下一次发送
    TI=0;
}

// 主函数
void main()
{
    // 初始化串口
    uartinit();
    // 发送十六进制数据 0x66
    UART_sendbit(0x66);
    while(1)
    {
        // 无限循环,程序在此处停止,等待外部事件
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2130429.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android 提高第一次开机速度(取消系统默认手机加密)

Android刷机后第一次开机&#xff0c;系统默认是要手机加密的&#xff0c;有些机器加密就几秒钟&#xff0c;有些机器加密要30多秒甚至更长&#xff0c;严重影响了开机速度。 修改路径&#xff1a; device/qcom/xxxx/fstab_AB_variant.qcom 有一些是这个文件&#xff1a; devic…

补:在Spring Boot 当中使用 Thymeleaf 视图解析器

补&#xff1a;在Spring Boot 当中使用 Thymeleaf 视图解析器 想要在 Spring Boot 当中使用 Thymeleaf 视图&#xff0c;就需要导入相关的 jar 依赖。在 pom.xml 文件中配置 。 <!-- 引入 thymeleaf-start ,项目会自动完成配置&#xff0c;--><dependency>…

MPU6050移植DMP读出三轴角度

先决条件 MPU6050移植完成&#xff0c;能够正确读出加速度和陀螺仪原始数据 DMP移植 官方包代码复制 解压demo&#xff0c;打开motion_driver_6.12\arm\STM32F4_MD6\Projects\eMD6\core\driver&#xff0c;复制路径下的eMPL到自己工程 代码移植 需要修改的有三个文件&am…

GD32/STM32启动过程

GD32/STM32启动过程 文章目录 GD32/STM32启动过程前言一、系统架构二、自举配置三、启动文件四、启动流程总结 前言 本文以STM32F407为例简单介绍其启动过程。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、系统架构 STM32F407的系统架构如图所…

libyuv之linux编译

文章目录 一、下载源码二、编译源码三、注意事项1、银河麒麟系统&#xff08;aarch64&#xff09;&#xff08;1&#xff09;解决 armv8-adotprodi8mm 指令集支持问题&#xff08;2&#xff09;解决 armv9-asve2 指令集支持问题 一、下载源码 到GitHub网站下载https://github.…

【JAVA】Undertow的使用及性能优化,以及Undertow与Tomcat的对比

文章目录 Undertow优势Undertow使用Undertow性能优化线程池配置缓冲区和内存使用连接和请求超时禁用无关的设置编程式配置启用HTTP/2 Undertow与Tomcat的对比 更多相关内容可查看 当你进行Tomcat调优发现在怎么调都无法满足需求的时候&#xff0c;Undertow容器在性能和内存上都…

盘点2024年大家都在用的短视频剪辑工具

你现在休息的时间是不是都靠短视频来消遣&#xff1f;看着看着你就会发现短视频制作好像我也可以了吧&#xff1f;这次我就介绍一些简单好操作的短视频剪辑工具。 1.FOXIT视频剪辑 连接直达>>https://www.pdf365.cn/foxitclip/ 短视频剪辑其实也不难&#xff0c;只需…

MySql-表的内外连接

文章目录 前言一、内连接二、外连接1.左外连接2.右外连接 前言 表的内外连接跟我们上节课讲的笛卡尔积很相似。 一、内连接 格式&#xff1a;select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件&#xff1b; 例如&#xff1a;显示SMITH的名字和部门名称 二、外…

RB-SQL:利用检索LLM框架处理大型数据库和复杂多表查询的NL2SQL

NL2SQL的任务是将自然语言问题转换为SQL查询&#xff0c;以便从数据库中获取答案。现有LLM来指导SQL生成的方法在处理大型数据库和复杂多表查询时存在挑战&#xff0c;尤其是在处理冗余信息和提高提示工程效率方面。 (a) 利用大型语言模型&#xff08;LLM&#xff09;解决文本…

ctfshow-web入门-sql注入(web249-web253)nosql 注入

目录 1、web249 2、web250 3、web251 4、wen252 5、web253 1、web249 开始nosql,flag在flag中 $user $memcache->get($id); 使用 Memcache 类的 get 方法从缓存中获取数据&#xff0c;$id 是传入的键&#xff0c;用于从缓存中获取与该键对应的值&#xff0c;结果存储…

明基相机sd卡格式化还能恢复数据吗?可以这样操作

随着数字摄影的普及&#xff0c;相机SD卡已成为我们记录生活点滴的重要载体。然而&#xff0c;不小心将SD卡格式化&#xff0c;导致珍贵照片和视频瞬间消失&#xff0c;无疑是摄影爱好者的一大噩梦。面对这样的突发情况&#xff0c;许多朋友可能会感到无助与绝望。但实际上&…

【计算机组成原理】概述+数制与编码

目录 计算机组成原理概述计算机基本组成计算机系统的层次结构计算机性能指标 数制与编码进位计数制及其相互转换数据的编码与表示校验码 计算机组成原理概述 计算机基本组成 运算器、控制器、存储器、输入输出设备 运算器&#xff1a;完成数据的暂存、变换、算术运算和逻辑…

OpenCV结构分析与形状描述符(23)确定一个点是否位于多边形内的函数pointPolygonTest()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 进行点在轮廓内的测试。 该函数确定点是在轮廓内、轮廓外&#xff0c;还是位于一条边上&#xff08;或与顶点重合&#xff09;。它返回正值&…

【可变参模板】基类参数包的展开

一、基类参数包的展开 1.1基类参数包的展开 C C C是一个支持多继承的语言&#xff0c;因此继承的类也可以是一个基类的参数包 注意继承的语法是 p u b l i c : c l a s s . . . public: class ... public:class...&#xff0c;需要补充 . . . ... ...作为基类参数包的标志。…

Linux 驱动编写框架 并编译导入开发板

向内核新加文件&#xff1a;例如 demo1.c 1. 创建并编辑新的文件 #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/module.h> #include <linux/kdev_t.h> #include …

Qt控制开发板的LED

Qt控制开发板的LED 使用开发板的IO接口进行控制是嵌入式中非常重要的一点&#xff0c;就像冯诺依曼原理说的一样&#xff0c;一个计算机最起码要有输入输出吧&#xff0c;我们有了信息的接收和处理&#xff0c;那我们就要有输出。 我们在开发板上一般都是使用开发板的GPIO接口…

vue3使用provide和inject传递异步请求数据子组件接收不到

前言 一般接口返回的格式是数组或对象&#xff0c;使用reactive定义共享变量 父组件传递 const data reactive([])// 使用settimout模拟接口返回 setTimeout(() > {// 将接口返回的数据赋值给变量Object.assign(data, [{ id: 10000 }]) }, 3000);provide(shareData, dat…

02请求响应(简单参数)

一、操作目的 前端通过post/get请求&#xff0c;传递给后端简单的数据&#xff0c;后端接收后在控制台打印出来&#xff0c;并将结果返回给前端页面展示出来。&#xff08;这里我们用postman来模拟前端页面&#xff0c;而非真实的通过编写前端代码&#xff0c;通过浏览器来展示…

Docker数据挂载本地目录

docker内的数据映射可以不通过数据卷&#xff0c;直接映射到本地的目录。下面将以mysql容器示例&#xff0c;完成容器的数据映射。 注意&#xff1a;每一个不同的镜像&#xff0c;将来创建容器后内部有哪些目录可以挂载&#xff0c;可以参考DockerHubDocker Hub Container Ima…

求树上任意两个点的距离lca

前言&#xff1a;一开始看到这个题目的时候&#xff0c;感觉就和lca有关&#xff0c;但是没有想到具体的公式 d d e p [ x ] d e p [ y ] − 2 ∗ d e p [ l c a ( x , y ) ] d dep[x] dep[y] - 2*dep[lca(x,y)] ddep[x]dep[y]−2∗dep[lca(x,y)] 并且我们这个题目还是一个…