嵌入式51单片机05-中断与定时器系列

news2024/11/14 3:43:21

文章目录

    • 中断与定时器
      • 一、中断系统与定时器
        • 1. 中断简单介绍
        • 2. 定时器简单介绍
      • 二、中断系列代码
        • 1. 中断操作(中断控制LED灯亮灭)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 2. 中断操作(外部中断0的中断方式控制P2口流水灯取反闪烁)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 3. 中断操作(低级中断与高级中断)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 4. 中断操作(门铃)
          • (1)源代码
          • (2)结果分析
        • 5. 中断操作(中断与定时器结合使用)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
      • 三、定时器系列代码
        • 1. 定时器操作(三分钟闹钟)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 2. 定时器操作(计数器)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 3. 定时器操作(秒表)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 4. 定时器操作(电子锁)
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果
        • 5. 定时器操作(定时器实现四种波形)
          • (1)源代码
          • (2)结果分析
        • 6. 定时器操作(软件置位)
          • (1)源代码
          • (2)结果分析
        • 7. 定时器操作(实现PWM波)
          • (1)源代码
          • (2)结果分析
        • 8. 定时器操作(模拟救护车警铃声)
          • (1)源代码
          • (2)结果分析
        • 9. 定时器操作(电子钟(闹钟、调时))
          • (1)仿真电路图
          • (2)源代码
          • (3)实验结果

中断与定时器

一、中断系统与定时器

1. 中断简单介绍

  • 目的:中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。

  • 中断过程:当中央处理机CPU正在处理某事件的时候外界发生了紧急事件请求(中断发生),要求CPU暂停当前的工作,转而去处理这个紧急事件(中断响应和中断服务),处理完以后,再回到原来被中断的地方,继续原来的工作(中断返回)。

    中断执行过程图解
    在这里插入图片描述

  • 中断系统:实现中断功能的部件称为中断系统,请求CPU中断的请求源称为中断源。微型机的中断系统一般允许有多个中断源,当几个中断源同时向CPU请求中断,要求它服务的时候,这就存在CPU优先响应哪个中断源请求的问题。因此设置中断优先级,CPU总是先响应优先级别最高的中断请求。

    中断系统图解
    在这里插入图片描述

  • 中断嵌套:当CPU正在处理一个中断源请求的时候(执行对应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的系统被称为多级中断系统。

  • 中断技术的优点

    • 分时操作:CPU可以分时为多个I/O设备服务,提高了计算机的利用率;

    • 实时响应:CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;

    • 可靠性高:CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。

  • STC90C51的八个中断请求源

    • 外部中断0(INT0)
    • 定时器0中断
    • 外部中断1(INT1)
    • 定时器1中断
    • 串口(UART)中断
    • 定时器2中断
    • 外部中断2(INT2)
    • 外部中断3(INT3)

    所有的中断都具有4个中断优先级;

    用户可以用关总中断允许位(EA)或相应中断的允许位来屏蔽所有的中断请求,也可以用打开相应的中断允许位来使 CPU响应相应的中断申请;

    每一个中断源可以用软件独立地控制为开中断或关中断状态;

    每一个中断的优先级别均可用软件设置。

    高优先级的中断请求可以打断低优先级的中断,反之,低优先级的中断请求不可以打断高优先级及同优先级的中断。

    当两个相同优先级的中断同时产生时,将由查询次序来决定系统先响应哪个中断。
    在这里插入图片描述

    如果使用C语言编程,中断查询次序号就是中断号,如:

    //  中断函数的名称              中断号
    void Int0_Routine(void)     interrupt 0;
    void Timer0_Rountine(void)  interrupt 1;
    void Int1_Routine(void)     interrupt 2;
    void Timer1_Rountine(void)  interrupt 3;
    void UART_Routine(void)     interrupt 4;
    void Timer2_Routine(void)   interrupt 5;
    void Int2_Routine(void)     interrupt 6;
    void Int3_Routine(void)     interrupt 7;
    
  • 89C51中断源和中断优先级

    • 中断源说明1
      在这里插入图片描述

      外部中断即可低电平触发,也可以下降沿触发。请求两个外部中断的标志位是位于寄存器TCON中的IE0IE1,当外部中断服务被响应后,中断请求标志位IE0IE1会被清零。TCON寄存器中的IT0IT1决定外部中断0和1是低电平触发方式还是下降沿触发方式。为0时是低电平触发,为1时是下降沿触发。

      定时器0和1的中断请求标志位是TF0TF1。当定时器寄存器THx/TLx(x=0,1)溢出时,溢出标志位TFx(x=0,1)会被置位,定时器中断发生。当单片机转去执行该定时器中断时,定时器的溢出标志位TFx(x=0,1)会被硬件清除。

      当串行口接收中断请求标志位RI和串行口发送中断请求标志位TI中的任何一个被置为1后,串行口中断都会产生。

    • 中断源说明2
      在这里插入图片描述

      • P3.2 可由IT0(TCON.0)选择其为低电平有效还是下降沿有效。当CPU检测到P3.2引脚上出现有效的中断信号时,中断标志IE0(TCON.1)1,向CPU申请中断。

      • P3.3 可由IT1(TCON.2)选择其为低电平有效还是下降沿有效。当CPU检测到P3.3引脚上出现有效的中断信号时,中断标志IE1(TCON.3)1,向CPU申请中断。

      • TF0(TCON.5),片内定时/计数器T0溢出中断请求标志。当定时/计数器T0发生溢出时,置位TF0,并向CPU申请中断。

      • TF1(TCON.7),片内定时/计数器T1溢出中断请求标志。当定时/计数器T1发生溢出时,置位TF1,并向CPU申请中断。

      • RI(SCON.0)TI(SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位RI或当串行口发送完一帧串行数据时置位TI,向CPU申请中断。

    • 中断优先级原则

      • CPU同时接收到几个中断时,首先响应优先级别最高的中断请求;

      • 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断;

      • 正在进行的低优先级中断服务,能被高优先级中断请求所中断。

  • 中断寄存器
    在这里插入图片描述

    上述是列出的是STC90C51系列的所有中断寄存器,我们使用的STC89C51略微不同,请注意。

    • 中断允许寄存器IE
      在这里插入图片描述

    • 具体介绍(=1时允许,=0时禁止)

      • EX0(IE.0),外部中断0允许位;

      • ET0(IE.1),定时/计数器T0中断允许位;

      • EX1(IE.2),外部中断1允许位;

      • ET1(IE.3),定时/计数器T1中断允许位;

      • ES (IE.4),串行口中断允许位;

      • EA (IE.7), CPU中断允许(总允许)位。

    • 定时器/计数器控制寄存器TCON
      在这里插入图片描述

    • 具体介绍

      • IT0(TCON.0),外部中断0触发方式控制位;

        • 当IT0=0时,为低电平触发方式
        • 当IT0=1时,为边沿触发方式(下降沿有效)
      • IE0(TCON.1),外部中断0中断请求标志位;

      • IT1(TCON.2),外部中断1触发方式控制位;

      • IE1(TCON.3),外部中断1中断请求标志位;

      • TR0(TCON.4), 定时器0的运行控制位;

      • TF0(TCON.5),定时/计数器T0溢出中断请求标志位;

      • TR1(TCON.6), 定时器1的运行控制位;

      • TF1(TCON.7),定时/计数器T1溢出中断请求标志位。

  • 中断响应条件:

    • 中断源有中断请求;
    • 此中断源的中断允许位为1;
    • CPU开中断。

2. 定时器简单介绍

  • 定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

  • 51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

  • 有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情,同时可以实现精确定时作用。

  • 定时/计数器的工作原理:定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

  • 定时器结构:

    定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THx和TLx组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
    在这里插入图片描述

    • 工作方式寄存器TMOD:
      在这里插入图片描述

      • GATE:用于控制定时器的启动是否受外部中断源信号的影响

        当GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;

        当GATE=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。

      • C/T:定时/计数模式选择位

        C/T=0为定时模式;

        C/T =1为计数模式。

      • M1M0:工作方式设置位
        在这里插入图片描述

    • 控制寄存器TCON:
      在这里插入图片描述

      • TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
      • TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
      • TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
      • TR0(TCON.4):T0运行控制位,其功能与TR1类同。
  • 定时器工作方式:

    1. 方式0

      方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。
      在这里插入图片描述

    2. 方式1

      方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器。
      在这里插入图片描述

    3. 方式2

      方式2为自动重装初值的8位计数方式。
      在这里插入图片描述

    4. 方式3

      方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。
      在这里插入图片描述

      此处的机器周期是单片机时钟频率的倒数。51单片机内部时钟频率是外部时钟频率的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。

  • 定时器工作初始化

    1. 对TMOD赋值,以确定T0和T1的工作方式;
    2. 计算初值,并将其写入TH0,TL0或TH1,TL1;
    3. 中断方式时,则对EA赋值,开放定时器中断;
    4. 使TR0或TR1置位,启动定时/计数器定时或计数。

    以定时器T0为例:

    //1.对TMOD赋值,以确定T0的工作方式
    TMOD |= 0x01;
    //2.计算初值,并将其写入TH0,TL0
    TH0 = 0xFC;
    TL0 = 0x18;
    //3.中断方式时,则对EA赋值,开放定时器中断
    ET0 = 1;
    EA = 1;
    //4.使TR0置位,启动定时/计数器定时或计数
    TR0 = 1;
    

二、中断系列代码

1. 中断操作(中断控制LED灯亮灭)

(1)仿真电路图

在这里插入图片描述
在这里插入图片描述

(2)源代码

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

main.c

//第一种实现方式
//使用外部中断0
#include <REGX52.H>
#include "Delay.h"


sbit k3=P3^2; 
sbit led=P2^0;	 


//Int0初始化
void Int0Init()
{
	IT0=1;  //下降沿触发
	EX0=1;  //中断允许	
	EA=1;   //打开总中断	
}

void main()
{
	//外部中断0初始化
	Int0Init(); 
	
	while(1);		
}

//外部中断0的中断函数
void Int0()	interrupt 0		
{
	//消抖
	Delay(20);	 
	while(k3 == 0);
	Delay(20);
	
	led = ~led;
}

//************************************************************************

//第二种实现方式
//使用外部中断1
#include <REGX52.H>
#include "Delay.h"


sbit k4=P3^3; 
sbit led=P2^0;	 


//Int0初始化
void Int1Init()
{
	IT1=1;  //下降沿触发
	EX1=1;  //中断允许	
	EA=1;   //打开总中断	
}

void main()
{
	//外部中断0初始化
	Int1Init(); 
	
	while(1);		
}

//外部中断0的中断函数
void Int1()	interrupt 2		
{
	//消抖
	Delay(20);	 
	while(k4 == 0);
	Delay(20);
	
	led = ~led;
}
(3)实验结果

2. 中断操作(外部中断0的中断方式控制P2口流水灯取反闪烁)

(1)仿真电路图

在这里插入图片描述

(2)源代码

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

main.c

#include <REGX52.H>
#include "Delay.h"


unsigned char i, j;


void main()
{
	EA = 1;  	  //开总中断
	EX0 = 1;	  //EX0为外部中断0请求/INT0允许位,EX0=1为开外部中断0
	IT0 = 1;	  //外部中断0触发方式控制位,IT0=1为下降沿触发方式,需要由软件置位
	
	while(1)  
	{
		P2 = 0xff;  	 
		Delay(250);	 
		for(i = 0; i < 8; i++)
		{
			P2 = P2 >> 1;
			Delay(250);
		}
	}
}

//外部中断程序
void int0() interrupt 0		
{
	//消抖
	Delay(20);	 
	while(P3_2 == 0);
	Delay(20);
	
	for (j = 0; j < 6; j++)	 
	{
		P2 = ~P2;
		Delay(250);
	}
}
(3)实验结果

3. 中断操作(低级中断与高级中断)

(1)仿真电路图

在这里插入图片描述

(2)源代码
#include <AT89X51.h>
#include <intrins.h>

//延时程序
void delay ()           
{
     int a = 5000;
     while (--a)
		 _nop_(); 
}

//外部中断0处理程序,设置为高级中断
void int0() interrupt 0    
{  
	int m;
	for (m = 0;m < 20;m++)
	{
		P2_7 = 0;
		P2_6 = 0;
		delay();
		P2_7 = ~P2_7;
		P2_6 = ~P2_6;
		delay();
	}
}

//外部中断1处理程序,设置为低级中断
void int1() interrupt 2    
{  
	int i;
	for (i = 0;i < 20;i++)
	{
		P2_0 = 0;
		delay();
		P2_0 = ~P2_0;
		delay();
	}
}

void main()
{
	//此语句相当于EA=1;EX0=1;EX1=1; 开总中断,开外部中断0和外部中断1	
	IE = 0X85;   
	//相当于PX0=1; 即外部中断0为高优先级
	IP = 1;	 
	//相当于IT1=1,IT0=1; 外部中断脉冲触发方式,下降沿有效	
	TCON = 5;	  
   while(1);	
}
(3)实验结果

4. 中断操作(门铃)

(1)源代码
#include<AT89X51.h>

int a=0;

//定时器0初始化函数
void timer0Init(void)
{
	EA=1;
	ET0=1;
	TMOD=0x01;
	TH0=0xfd;
	TL0=0x44;
}

void main()
{
	timer0Init();
	
	while(1)
	{
		//判断按键按下
	 	if(P3_1 == 0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			
		 	TR0 = 1;
		}
	}
}

void time0() interrupt 1
{
	P1_5=~P1_5;
	a++;
	if (a<400)
	{
		TH0=0xfd;
		TL0=0x44;
	}
	else if (a<800)
	{
		TH0=0xfc;
		TL0=0x18;
	}
	else
	{
		TR0=0;
		a=0;
	}
}
(2)结果分析
  • 主函数首先对定时器0进行相关的初始化操作,然后while循环中判断按键是否按下,如果按键按下,就让定时器开始工作。

  • 中断服务函数中对P1_5(蜂鸣器)引脚进行取反,在不同的时间下,蜂鸣器会发出不同的声音,我们模拟的门铃操作,需要两种不同的声音,所以要对定时器的时间进行操作,前400次一个定时器时间发出一种声音,后400次另一个定时器时间发出另外一种声音,组合在一起就是门铃的声音。

  • 由于没有单片机实物,无法对相关的实验结果进行展示。

5. 中断操作(中断与定时器结合使用)

(1)仿真电路图

在这里插入图片描述

(2)源代码
//用定时器T0的中断实现P2流水灯2s闪烁,外部中断0中断方式控制循环移动
#include<reg51.h>

int a=0;

void delay(int n)	   //延时函数
{
	int i,j;
	for (i=n;i>0;i--)
	for (j=110;j>0;j--);
}

void main()
{
	EA=1;	 //开总中断
	ET0=1;	  //开定时器T0中断
	EX0=1;
	IT0=1;
	TMOD=0x01; //设定定时器的工作方式1
	TH0=0x4b;  //定时器的高8位初始化
	TL0=0xfd;  //定时器的低8位初始化
	TR0=1;  //启动定时器T0
	while(1); //无限的循环等待中断
}

void time0() interrupt 1
{
	a++;			 //用变量来控制定时器定时的长短
	if (a==20)
	{
		a=0;
		P2=~P2;
	}
	TH0=0x4b/0xff;  
	TL0=0xfd%0xff;
}

void int0() interrupt 0		//外部中断程序
{
	int a,b;
	for (a=0;a<10;a++)	 //产生一次中断请求,P2取反一次
	{
		P2=0xff;	   //P2口初始化
		delay(100);	   //延时一段时间
		for (b=0;b<8;b++)
		{
			P2=P2>>2;
			delay(150);
		}
	}
}
(3)实验结果

三、定时器系列代码

1. 定时器操作(三分钟闹钟)

(1)仿真电路图

在这里插入图片描述

(2)源代码

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Nixie.c

#include <REGX52.H>
#include "Delay.h"	


int second; //全局变量用来显示秒数
int mit;	//全局变量用来显示分钟
int hour;   //全局变量用来显示小时

//数码管段码表
unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};


//数码管显示函数
void display(int k)		
{
	P2_2=1;P2_3=1;P2_4=1;
	P0=NixieTable[hour/10];              
	Delay(1);

	P2_2=0;P2_3=1;P2_4=1;
	P0=NixieTable[hour%10];              
	Delay(1);
	
	P2_2=1;P2_3=0;P2_4=1;
	P0=~0xbf;             
	Delay(1);	

	P2_2=0;P2_3=0;P2_4=1;
	P0=NixieTable[mit/10];              
	Delay(1);
	
	P2_2=1;P2_3=1;P2_4=0;
	P0=NixieTable[mit%10];              
	Delay(1);

    P2_2=0;P2_3=1;P2_4=0;
	P0=~0xbf;
	Delay(1);
	
	P2_2=1;P2_3=0;P2_4=0;	
	P0=NixieTable[k/10];			    
	Delay(1);				   

	P2_2=0;P2_3=0;P2_4=0;
	P0=NixieTable[k%10];				
	Delay(1);
}

//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = NixieTable[Number];  //段码输出
	Delay(1);				  //显示一段时间
	P0 = 0x00;				  //段码清0,消影
}

void Nixie2(unsigned char Number)
{
	int i;
	for(i = 0; i < 8; i++)
	{
		switch(i)
		{
			case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
			case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
			case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
			case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
			case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
			case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
			case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
			case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
		}
	}

	P0 = NixieTable[Number];  //段码输出
	Delay(1);				  //显示一段时间
	P0 = 0x00;				  //段码清0,消影
}

Nixie.h

#ifndef __NIXIE_H__
#define __NIXIE_H__


extern int second; //全局变量用来显示秒数
extern int mit;	//全局变量用来显示分钟
extern int hour;   //全局变量用来显示小时

void Nixie(unsigned char Location,Number);
void Nixie2(unsigned char Number);
void display(int k);

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"

																	
int num;  


void int0Init(void)
{
	//1.对TMOD赋值,以确定T0的工作方式
	TMOD |= 0x01;
	//2.计算初值,并将其写入TH0,TL0
	TH0 = 0xFC;
	TL0 = 0x18;
	//3.中断方式时,则对EA赋值,开放定时器中断
	ET0 = 1;
	EA = 1;
	//4.使TR0置位,启动定时/计数器定时或计数
	TR0 = 1;
}

void clockInit(void)
{
	num=0;	  
	second=0;
	mit=0;
	hour=12;
}

void main()
{
	int0Init();
	clockInit();
	
	while(1)	
	{
		//按下k1,停止计时
		if (P3_1 == 0)	
			TR0 = 0;
		
		//按下k2,开始计时
		if (P3_0 == 0)	
			TR0 = 1;
		
		//按下k3,重新计时
		if (P3_2 == 0)	
		{
			hour = 12;
			mit = 0;
			second = 0;
		}
		display(second);  //调用数码管显示函数
		
		if (hour == 12 && mit == 3 && second == 0)
		{
			TR0=0;
			while(1)
			{	
				P1_5 = ~P1_5;
				//通过修改此延时时间达到不同的发声效果	
				Delay(1);
				display(second); 
			}
		}
	}	
}

//定时器T0中断函数
void time0() interrupt 1	 
{
	num++;	   //中断次数自加一
	if(num==1000)	 //如果时间达到一秒时,就让秒数加1
	{
		num=0;
		second++;
		//当秒数变为0时,让秒数重新置位
		if (second == 60)	 
		{
			second=0;
			mit++;
			//当分钟变为0时,让分钟重新置位
			if (mit == 60)		
			{
				mit=0;
				hour++;
				if (hour == 24)
				{
					hour=0;
				}
			}
		}
	}
	
	//定时器的高8位初始化
	TH0 = 0xFC;    
	//定时器的低8位初始化
	TL0 = 0x18;	 
}
(3)实验结果

2. 定时器操作(计数器)

(1)仿真电路图

在这里插入图片描述

(2)源代码
#include <REGX52.H>
#include "Delay.h"


//数码管段选,显示
int a[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
int second = 0;
int num = 0;


void display(int k)		//数码管显示函数
{	
	//P2口控制位选,用138译码器控制数码管的位选
	P2_2 = 1;P2_3 = 0;P2_4 = 0;	
	//P0口控制段选,用来显示十位上的数值
	P0 = a[k/10];	
	//延时10ms	
	Delay(10);				    

	P2_2 = 0;P2_3 = 0;P2_4 = 0;
	P0 = a[k%10];				
	Delay(10);
}

void timer0Init(void)
{
	EA = 1;	  
	ET0 = 1;     
	TMOD = 0x01; 
	TH0 = 0x3c; //定时器的高8位初始化
	TL0 = 0xb0; //定时器的低8位初始化
	TR0 = 1;
}

void main()
{
	timer0Init();
	P0 = 0xff;
	P2 = 0xff;

	while(1)
	{
		display(second);
	}	 
}

//定时器T0中断函数
void time0() interrupt 1	 
{
	num++;	   
	if(num == 20)	 
	{
		num = 0;
		second++;
		if(second == 99)
		second = 0;
	}
	
	TH0 = 0x3c;    
	TL0 = 0xb0;	   	
}
(3)实验结果

3. 定时器操作(秒表)

(1)仿真电路图

(2)源代码
#include<AT89X51.h>
#include "Delay.h"


int a[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	 
int ssecond = 0;  //控制百分之一秒
int second = 0;	  //秒
int mit = 0;	  //分
int t = 0;	      //控制按键


//数码管显示函数
void display(int k)		
{
	P2_2 = 1;P2_3 = 1;P2_4 = 1;
	P0 = a[mit/10];
	Delay(1);
	
	P2_2 = 0;P2_3 = 1;P2_4 = 1;
	P0 = a[mit%10];
	Delay(1);
	
	P2_2=1;P2_3=0;P2_4 = 1;
	P0 = 0x40;
	Delay(1);
	
	P2_2 = 0;P2_3 = 0;P2_4 = 1;
	P0 = a[second/10];
	Delay(1);
	
	P2_2 = 1;P2_3 = 1;P2_4 = 0;
	P0 = a[second%10];
	Delay(1);
	
	P2_2 = 0;P2_3 = 1;P2_4 = 0;
	P0=0x40;
	Delay(1);
	
	P2_2 = 1;P2_3 = 0;P2_4 = 0;
	P0 = a[k/10];
	Delay(1);
	
	P2_2 = 0;P2_3 = 0;P2_4 = 0;
	P0 = a[k%10];
	Delay(1);
	
	P2 = 0;
	P0 = 0;
	Delay(10);
}

void keydown()		//按键函数,判断按键是否按下
{
	if (P3_0 == 0)
	{
		Delay(20);
		while(P3_0 == 0);
		Delay(20);
		
		t++;
		if(t == 1)
		{
			TR1 = 0;	
		}
		else
		{
			t = 0;
			TR1 = 1;
		}
	}
	
	if (P3_1 == 0 && TR1 == 0)
	{
		Delay(20);
		while(P3_1 == 0);
		Delay(20);

		ssecond = 0;
		second = 0;
		mit = 0;
		TR1 = 0;
	}	
}

void timer1Init(void)
{
	TMOD = 0X10;
	TL1 = 0XF0;
	TH1 = 0XD8;
	ET1 = 1;
	EA = 1;
	TR1 = 1;
}

void main()		
{
	timer1Init();

	while(1)
	{
		display(ssecond);
		keydown();
	}
}

//定时器1中断函数
void time1() interrupt 3	   
{
	TL1 = 0XF0;
	TH1 = 0XD8;
	
	ssecond++;
	if(ssecond == 100)
	{
		ssecond = 0;
		second++;
		if (second > 60)
		{
			second = 0;
			mit++;
			if (mit == 3)
			mit = 0;
		}
	}	
}
(3)实验结果

4. 定时器操作(电子锁)

(1)仿真电路图

在这里插入图片描述

(2)源代码

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

MatrixKey.c

#include <REGX52.H>
#include "Delay.h"


/**
  * @brief  矩阵键盘读取按键键码
  * @param  无
  * @retval KeyNumber 按下按键的键码值
			如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
  */
unsigned char MatrixKey()
{
	static unsigned char KeyNumber = 0;
	
	P1 = 0xFF;
	P1_3 = 0;
	if(P1_7 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 1; P2_0 = ~P2_0;}
	if(P1_6 == 0){ Delay(20); while(P1_6 == 0); Delay(20); KeyNumber = 5; P2_0 = ~P2_0;}
	if(P1_5 == 0){ Delay(20); while(P1_5 == 0); Delay(20); KeyNumber = 9; P2_0 = ~P2_0;}
	if(P1_4 == 0){ Delay(20); while(P1_4 == 0); Delay(20); KeyNumber = 13; P2_0 = ~P2_0;}
	 
	P1 = 0xFF;
	P1_2 = 0;
	if(P1_7 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 2; P2_0 = ~P2_0;}
	if(P1_6 == 0){ Delay(20); while(P1_6 == 0); Delay(20); KeyNumber = 6; P2_0 = ~P2_0;}
	if(P1_5 == 0){ Delay(20); while(P1_5 == 0); Delay(20); KeyNumber = 10; P2_0 = ~P2_0;}
	if(P1_4 == 0){ Delay(20); while(P1_4 == 0); Delay(20); KeyNumber = 14; P2_0 = ~P2_0;}
	
	P1 = 0xFF;
	P1_1 = 0;
	if(P1_7 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 3; P2_0 = ~P2_0;}
	if(P1_6 == 0){ Delay(20); while(P1_6 == 0); Delay(20); KeyNumber = 7; P2_0 = ~P2_0;}
	if(P1_5 == 0){ Delay(20); while(P1_5 == 0); Delay(20); KeyNumber = 11; P2_0 = ~P2_0;}
	if(P1_4 == 0){ Delay(20); while(P1_4 == 0); Delay(20); KeyNumber = 15; P2_0 = ~P2_0;}
	
	P1 = 0xFF;
	P1_0 = 0;
	if(P1_7 == 0){ Delay(20); while(P1_7 == 0); Delay(20); KeyNumber = 4; P2_0 = ~P2_0;}
	if(P1_6 == 0){ Delay(20); while(P1_6 == 0); Delay(20); KeyNumber = 8; P2_0 = ~P2_0;}
	if(P1_5 == 0){ Delay(20); while(P1_5 == 0); Delay(20); KeyNumber = 12; P2_0 = ~P2_0;}
	if(P1_4 == 0){ Delay(20); while(P1_4 == 0); Delay(20); KeyNumber = 16; P2_0 = ~P2_0;} 
	
	return KeyNumber;
}

MatrixKey.h

#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "MatrixKey.h"


int a[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
int key;
int key_flag = 0;


void display(int k)		//数码管显示函数
{
	if( k != 0)
	{
		P2_2=1;P2_3=0;P2_4=0;	//P2口控制位选,用138译码器控制数码管的位选
		P0=a[k/10];			    //P0口控制段选,用来显示十位上的数值
		Delay(1);				//延时1ms

		P2_2=0;P2_3=0;P2_4=0;
		P0=a[k%10];				//P0口控制段选,用来显示个位上的数值
		Delay(1);
	}
}


void timer0Init(void)
{
	EA=1;	   //开总中断
	ET0=1;     //开定时器T0中断
	TMOD=0x01; //设置定时器T0于工作方式1
	TH0=0xf0;  //定时器的高8位初始化
	TL0=0x60;  //定时器的低8位初始化
	TR0=1;	   //开启定时器
}

void valueInit(void)
{
	P2 = 0xff;
	P0 = 0xff;
	key=0x00; 	//变量的初始化
}

void main()	   //主函数
{
	int b[7]={9,7,6,2,16};	//保存预先设计的密码

	timer0Init();
	valueInit();
	
	while(key != b[0]);	  //用while循环判断密码是否正确
	while(key != b[1]);
	while(key != b[2]);
	while(key != b[3]);
	while(key != b[4]);		//确认密码输入完成,即设置一个确认键
	
	while(1)
	{
		key_flag = 1;
		
		P1_5=~P1_5;	  //蜂鸣器
		Delay(125);
		
		P1_5=~P1_5;
		Delay(125);	
	}	
}

void time0() interrupt 1	   //定时器T0中断函数
{
	key = MatrixKey();
	if(key_flag != 1)
		display(key);
	
	TH0=0xf0;
	TL0=0x60;
}
(3)实验结果

5. 定时器操作(定时器实现四种波形)

(1)源代码
#include<AT89X51.h>

int num,num1,num2,num3;	

void main()
{
	EA = 1;	
	ET0 = 1;
	TMOD = 0X01;
	TH0 = 0xec;
	TL0 = 0x78;
	TR0 = 1;
	
	num = 0;	
	num1 = 0;
	num2 = 0;
	num3 = 0;
	
	while(1)
	{
		if(num == 5)
		{
			P2_0 = 1;
		}		
		if(num == 10)
		{
			P2_0 = 0;
			num = 0;
		}
		
		if(num1 == 5)
		{
			P2_1 = 1;
		}
		if(num1 == 15)
		{
			P2_1 = 0;
			num1 = 0;
		}
		
		if(num2 == 4)
		{
			P2_2 = 1;
		}
		if(num2 == 16)
		{
			P2_2 = 0;
			num2 = 0;
		}
		
		if(num3 == 6)
		{
			P2_3 = 1;
		}
		if(num3 == 32)
		{
			P2_3 = 0;
			num3 = 0;
		}
	}
}

void time0() interrupt 1
{
	num++;
	num1++;
	num2++;
	num3++;
	
	TH0 = 0xec;
	TL0 = 0x78;
}
(2)结果分析
  • 通过定时器0产生一定的时间,然后在定时器0里面设置四个变量,让变量自加,主函数判断叠加的次数,就可以显示不同时间的高低电平。
  • 由于实验结果需要示波器来显示,故无法做详细的结果分析。

6. 定时器操作(软件置位)

(1)源代码
//定时器T0在工作方式1,控制8位流水灯闪烁(软件置位)
#include<reg51.h>

void main()
{
	TMOD=0x01;	//使用定时器T0的定时模式的方式一
	TH0=(65536-46083)/256;	  //定时器高8位赋初值
	TL0=(65536-46083)%256;	  //定时器低8位赋初值
	TR0=1;		//启动定时器T0. 定时器T0为1时,开始计时,为0时不计数
	P2=0xff;	   //流水灯初始化
    
	while(1)  	//无限循环等待查询
	{
		while(TF0==0);	//检测TF0是否溢出,若TF0溢出,则TF0=1;需用软件置位
		TF0=0;
		P2=~P2;		 //控制流水灯闪烁
		TH0=(65536-46083)/256;	  //定时器高8位赋初值
		TL0=(65536-46083)%256;	  //定时器低8位赋初值
	}
}

//******************************************************************************************

//用定时器T0中断控制8位流水灯闪烁(中断实现方式)
#include<reg51.h>

void main()
{
	EA=1;	 	//EA为全局中断允许位,EA=1意为开所有中断
	ET0=1;		//ET0为定时器T0中断允许位,ET0=1意为开T0中断
    TMOD=0x01;	//TMOD为定时器工作方式寄存器,TMOD=0x01意为使用定时器T0的工作方式1,即N=16
	TH0=(65536-46083)/256;	 //定时器高8位赋初值
	TL0=(65536-46083)%256;	 //定时器低8位赋初值
	TR0=1;					 //启动定时器T0
	while(1);				 //无限循环等待中断
}

void time0() interrupt 1 using 0   //interrupt 声明函数为中断服务函数,其后的1为定时器T0 
{								//的中断编号,0表示使用第0组工作寄存器
	P2=~P2;				   //控制P2口的8位流水灯闪烁
	TH0=(65536-46083)/256;	//定时器T0的高8位重新赋初值
	TL0=(65536-46083)%256;	//定时器T0的低8位重新赋初值
}
(2)结果分析
  • 使用软件置位的方法实现定时器,与中断方式进行对比,进行了详细的注释。

7. 定时器操作(实现PWM波)

(1)源代码

Key.c

#include <REGX52.H>
#include "Delay.h"

/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
	unsigned char KeyNumber = 0;
	
	if(P3_1 == 0){Delay(20); while(P3_1 == 0); Delay(20); KeyNumber = 1;}
	if(P3_0 == 0){Delay(20); while(P3_0 == 0); Delay(20); KeyNumber = 2;}
	if(P3_2 == 0){Delay(20); while(P3_2 == 0); Delay(20); KeyNumber = 3;}
	if(P3_3 == 0){Delay(20); while(P3_3 == 0); Delay(20); KeyNumber = 4;}
	
	return KeyNumber;
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif

main.c

#include<reg51.h>
#include "key.h"


sbit PWM=P1^0;


unsigned char PWMvalue;
unsigned char PWMcount=0;


void timer0Init(void)
{
	TMOD=0x01;
	TL0=0xa3;	//0.1ms
	TH0=0xff;
	ET0=1;
	EA=1;
	TR0=1;
}

void main()
{
	timer0Init();
	
	while(1)
	{
		if(Key() == 1)
		{
			PWMcount=0;
			PWMvalue=9;
		}
		
		if(Key() == 2)
		{
			PWMcount=0;
			PWMvalue=16;	
		}
	}
}

void time0() interrupt 1
{
	TR0 = 0;
	TL0 = 0xa3;	//0.1ms
	TH0 = 0xff;

	PWMcount++;
	if (PWMvalue >= PWMcount)
		PWM = 1;
	else
		PWM = 0;
	if (PWMcount == 200)
		PWMcount = 0;	
		
	TR0 = 1;		
}
(2)结果分析
  • 使用定时器中断实现PWM波,由于需要示波器才能看到结果,故无法进行仿真实验。

8. 定时器操作(模拟救护车警铃声)

(1)源代码
#include <REGX52.H>


unsigned int scount;
unsigned int mscount;
unsigned int flag;

sbit SAP = P1^5;


void timer0Init(void)
{
	TMOD = 0x02;
	TL0 = 256-100;
	TH0 = 256-100;
	ET0 = 1;
	EA = 1;
	TR0 = 1;
}

void main()
{
	timer0Init();

	while(1);
}

void Time0() interrupt 1
{
	mscount++;

	if (flag == 0)
	{
		//根据定时时间的不同发出不同的声音,由于存在标志位,声音持续1s.
		if (mscount > 4)	   
		{
			mscount = 0;
			SAP = ~SAP;
		}
	}
	else
	{
		if (mscount > 9)
		{
			mscount = 0;
			SAP = ~SAP;	
		}
	}

	scount++;
	//通过定时时间来控制一个变量,当时间为1s时进行切换
	if(scount == 10000)	    
	{
		scount = 0;
		if (flag == 0)
			flag = 1;
		else
			flag = 0;	
	}
}
(2)结果分析
  • 中断服务函数中对SAP(蜂鸣器)引脚进行取反,在不同的时间下,蜂鸣器会发出不同的声音,我们模拟的救护车声音操作,需要两种不同的声音,所以要对定时器的时间进行操作,前4次一个定时器时间发出一种声音,后5次另一个定时器时间发出另外一种声音,组合在一起就是救护车的声音。
  • 由于没有单片机实物,无法对相关的实验结果进行展示。

9. 定时器操作(电子钟(闹钟、调时))

(1)仿真电路图

在这里插入图片描述

(2)源代码

Key.c

#include <REGX52.H>
#include "Delay.h"

unsigned char KeyNumber = 0;


/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
	if(P3_1 == 0){Delay(20); while(P3_1 == 0); Delay(20); KeyNumber = 1; P2_0 = ~P2_0;}
	if(P3_0 == 0){Delay(20); while(P3_0 == 0); Delay(20); KeyNumber = 2; P2_0 = ~P2_0;}
	if(P3_2 == 0){Delay(20); while(P3_2 == 0); Delay(20); KeyNumber = 3; P2_0 = ~P2_0;}
	if(P3_3 == 0){Delay(20); while(P3_3 == 0); Delay(20); KeyNumber = 4; P2_0 = ~P2_0;}
	
	return KeyNumber;
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__


extern unsigned char KeyNumber;

unsigned char Key();

#endif

Nixie.c

#include <REGX52.H>
#include "Delay.h"	
#include "clock.h"


//数码管段码表
int a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};


void display(int k)		
{
	P2_2=1;P2_3=1;P2_4=1;
	P0=a[hour/10];
	Delay(1);
	
	P2_2=0;P2_3=1;P2_4=1;
	P0=a[hour%10];
	Delay(1);
	
	P2_2=1;P2_3=0;P2_4=1;
	P0=~0xbf;
	Delay(1);
	
	P2_2=0;P2_3=0;P2_4=1;
	P0=a[minute/10];
	Delay(1);
	
	P2_2=1;P2_3=1;P2_4=0;
	P0=a[minute%10];
	Delay(1);
	
	P2_2=0;P2_3=1;P2_4=0;
	P0=~0xbf;
	Delay(1);
	
	P2_2=1;P2_3=0;P2_4=0;
	P0=a[k/10];
	Delay(1);
	
	P2_2=0;P2_3=0;P2_4=0;
	P0=a[k%10];
	Delay(1);
}

Nixie.h

#ifndef __NIXIE_H__
#define __NIXIE_H__


void display(int k);

#endif

clock.c

#include "clock.h"
#include "Key.h"
#include <REGX52.H>


int num;	
int hour;	
int minute;	
int second;	
int modeFlag=0;	
int stop=0;	


/**
  * @brief  控制时钟暂停与启动
  * @param  无
  * @retval 无
  */
void pause()	
{
	if(Key() == 4)
	{
		KeyNumber = 0;
		
		stop++;
		if (stop == 1)
			TR0=0;
		else
		{
			TR0=1;
			stop=0;
		}
	}
}

/**
  * @brief  模式切换
  * @param  无
  * @retval 无
  */
void modeChange()	
{
	if(Key() == 1)
	{
		KeyNumber = 0;
		
		modeFlag++;
		if (modeFlag==4)
			modeFlag=1;
		if(modeFlag == 1){P1_5 = 1; P1_6 = 0; P1_7 = 0;}
		if(modeFlag == 2){P1_5 = 0; P1_6 = 1; P1_7 = 0;}
		if(modeFlag == 3){P1_5 = 0; P1_6 = 0; P1_7 = 1;}
	}
}

/**
  * @brief  控制时钟增加与减小
  * @param  无
  * @retval 无
  */
void timeControl()	
{
	if (modeFlag != 0 && TR0 == 0)
	{
		//控制时分秒增加
		if(Key() == 2)
		{
			KeyNumber = 0;
			
			switch(modeFlag)
			{
				case 1: second++; if (second==60) second=0; break;
				case 2: minute++;    if (minute==60)    minute=0;    break;
				case 3: hour++;   if(hour==24)    hour=12;  break;
			}
		}
		
		//控制时分秒减小
		if(Key() == 3)
		{
			KeyNumber = 0;
			
			switch(modeFlag)
			{
				case 1: second--; if (second==-1) second=59; break;
				case 2: minute--;    if (minute==-1)    minute=59;    break;
				case 3: hour--;   if(hour==-1)    hour=23;   break;
			}
		}	
	}
}

clock.h

#ifndef __CLOCK_H__
#define __CLOCK_H__

extern int num;	
extern int hour;	
extern int minute;	
extern int second;	
extern int modeFlag;	
extern int stop;	


void pause(void);
void modeChange(void);
void timeControl(void);	


#endif

init.c

#include <REGX52.H>
#include "clock.h"
#include "Delay.h"
#include "Nixie.h"

/**
  * @brief  定时器0初始化
  * @param  无
  * @retval 无
  */
void timer0Init(void)
{
	EA = 1;				
	ET0 = 1;
	TMOD = 0X01;
	TH0 = 0X3C;
	TL0 = 0XB0;
	TR0 = 1;
}

/**
  * @brief  变量初始化
  * @param  无
  * @retval 无
  */
void valueInit(void)
{
	num = 0;		
	hour = 12;
	minute = 0;
	second = 0;
	stop = 0;
}

/**
  * @brief  定时器0中断服务函数
  * @param  无
  * @retval 无
  */
void time0() interrupt 1		
{
	num++;
	if (num == 20)
	{
		num = 0;
		second++;
		if (second == 60)
		{
			second = 0;
			minute++;
			if (minute == 60)
			{
				minute = 0;
				hour++;
				if (hour == 24)
					hour = 12;
			}
		}
	}
	TH0 = 0X3C;
	TL0 = 0XB0;
	
	if (hour == 12 && minute == 30 && second == 0)	
	{
		TR0 = 0;	
		while(1)	
		{	
			P1_5 = ~P1_5;
			Delay(5);	
			display(second); 	
		}
	}	
}

init.h

#ifndef __INIT_H__
#define __INIT_H__


void timer0Init(void);
void valueInit(void);


#endif

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

main.c

#include <REGX52.H>
#include "Nixie.h"
#include "clock.h"
#include "init.h"


void main()		
{
	timer0Init();
	valueInit();
	
	while(1)	
	{
		modeChange();
		pause();
		timeControl();
		display(second);
	}
}
(3)实验结果

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

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

相关文章

c++强制类型转换:

强制类型转换&#xff1a;1. const属性用const_cast。 案例&#xff1a; 说明&#xff1a;该变量可以将变量的const 的属性去掉。如该案例&#xff0c;转换后修改x的值是合法的。2. 基本类型转换用static_cast。 案例&#xff1a; 说明&#xff1a;一般用在(1)基本类型&#xf…

新黑马头条项目经验(黑马)

swagger (1)简介 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(API Documentation & Design Tools for Teams | Swagger)。 它的主要作用是&#xff1a; 使得前后端分离开发更加方便&#xff0c;有利于团队协作 接…

微服务知识

Spring Cloud Netfix&#xff1a;Eureka&#xff0c;Ribbon&#xff0c;Feign&#xff0c;Hystrix&#xff0c;Zuul | Gateway&#xff0c;Config Spring Colud Alibaba&#xff1a;Nacos&#xff0c;Sentinel&#xff0c;Seata Nacos通过Ribbon实现负载均衡&#xff0c;Ribb…

【java笔记】java多线程

目录 一、概念 1.1 什么是进程&#xff1f; 1.2 什么是线程&#xff1f; 1.3 什么事多线程&#xff1f; 1.4 进程和线程的关系 二、线程对象的生命周期 三、实现线程有两种方式 3.1 继承 java.lang.Thread&#xff0c;重写 run方法 3.2 实现 java.lang.Runnable 接口…

材料写作素材:关于“大”排比句40例

1.一轮思想政治“大督查”&#xff0c;一轮政策落实“大检查”&#xff0c;一次非公企业“大走访”&#xff0c;一次问题线索“大起底”&#xff0c;一批典型案例“大曝光”。 2.在重大风险挑战面前豁得出去、顶得上去&#xff0c;在重大困难考验面前迎难而上、敢于胜利&#…

【计网】WebSocket协议

目录 一、背景 二、WebSocket握手过程 三、SpringBoot中使用WebSocket协议 1、服务器 2、客户端 一、背景 一般的web开发以请求响应为主即客户端发送一个请求&#xff0c;服务器返回一个响应&#xff0c;这就使得类似聊天等需求基于HTTP协议进行实现时比较消费资源&#xf…

大数据之Hadoop分布式文件系统HDFS

目录&#xff1a; 一、介绍二、HDFS 设计原理三、原理图形介绍四、HDFS 常用 shell 命令五、HDFS相关JavaAPI 一、介绍 HDFS &#xff08;Hadoop Distributed File System&#xff09;是 Hadoop 下的分布式文件系统&#xff0c;具有高容错、高吞吐量等特性&#xff0c;可以部署…

厨电新十年,不可逆的行业分化与老板电器的数字进化

“人生就像滚雪球&#xff0c;最重要之事是发现湿雪和长长的山坡。”股神巴菲特的这句名言&#xff0c;让坡是否长、雪是否厚成为人们评价一个行业、一家公司的标准之一。 家电行业&#xff0c;厨电曾是最后一块“坡长雪厚”之地&#xff0c;投资者也对相关企业给出了相当的热…

FIR半带滤波器

FIR半带滤波器 半带滤波器原理&#xff1a; CIC滤波器是一种适合于工作在高采样率条件下的滤波器。 半带滤波器是一种非常适合于2倍抽取的FIR滤波器。 半带滤波器可以使2倍抽取的每秒乘法次数比一般线性相位的FIR滤波器减少近1/2。 半带滤波器是一种实现数字下变频的高效数…

暗藏的比特币白皮书已删除 苹果其实与Web3“格格不入”?

据悉&#xff0c;Apple已从其最新的Mac OS Ventura beta中删除了比特币白皮书&#xff0c;虽然该公司从未对白皮书的存在提供任何官方解释&#xff0c;但许多人猜测这是对加密货币日益增长的重要性的认可。 4月上旬&#xff0c;科技专家Andy Baio偶然发现&#xff0c;自己的Mac…

浅述 国产仪器 1652AM任意波形发生器

1652AM任意波形发生器是一款多通道、多功能的任意波形发生器。它在兼顾了输出信号高质量的同时&#xff0c;实现了高通道密度。它可与其它通用或专用模块化测试仪器构成综合测试系统或平台&#xff0c;支持众多解决方案&#xff0c;包括量子计算机调控信号生成、大规模MIMO信号…

活动目录(Active Directory)安全审计

延迟响应变化的影响可能会使原本应该微不足道的颠簸滚雪球变成无法弥补的损害。这在 Windows Active Directory 环境中更为重要&#xff0c;因为这种延迟造成的损害可能会使组织损失数百万美元&#xff01;在这种情况下&#xff0c;需要一个警惕的警报系统&#xff0c;该系统可…

WPF学习

一、了解WPF的框架结构 &#xff08;第一小节随便看下就可以&#xff0c;简单练习就行&#xff09; 1、新建WPF项目 xmlns&#xff1a;XML的命名空间 Margin外边距&#xff1a;左上右下 HorizontalAlignment&#xff1a;水平位置 VerticalAlignment&#xff1a;垂直位置 2…

性能测试开始前的需求调研

之前的博客聊聊性能测试开始前的准备工作&#xff0c;聊了一些关于性能测试开始前要做的准备工作。这篇博客&#xff0c;来谈谈性能测试开始前的需求调研阶段&#xff0c;我们要做什么&#xff0c;关注那些Point。。。 一、基本信息 信息类型说明项目名称项目归属的业务线&am…

低代码应用开发平台,让数据管理更简单!

在数据管理越来越规范化的今天&#xff0c;低代码应用开发平台也获得了进步和发展的机会和空间。想要将企业内部的数据资源做好系统管理&#xff0c;从而为各个时期的经营决策提供强有力的证据和基础&#xff0c;低代码应用开发平台就是其中备受喜爱的工具。本文主要从它的特点…

重磅!阿里云云原生合作伙伴计划全新升级:加码核心权益,与伙伴共赢新未来

在今天的 2023 阿里云合作伙伴大会上&#xff0c;阿里云智能云原生应用平台运营&生态业务负责人王荣刚宣布&#xff1a; “阿里云云原生合作伙伴计划”全新升级。他表示&#xff1a; 云原生致力于帮助企业客户最大限度的减轻运维工作&#xff0c;更好的实现敏捷创新&#x…

MQTT 协议

MQTT 简介 MQTT是一种基于客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范&#xff0c;易于实现。这些特点得它对很多场景来说都是很有的选择&#xff0c;特别是对于受限的环境如机器与机器的通信&#xff08;M2M&#xff09;以及物联网…

RAC集群节点2异常时节点1的database实例无法提供服务问题的分析

在客户的数据库RAC集群环境中&#xff0c;节点2发生了异常&#xff0c;最终通过重启解决。在节点2发生异常的10分钟左右时间内&#xff0c;由于RAC集群节点2异常&#xff0c;此时节点1的database实例无法提供服务问题&#xff0c;程序操作报超时&#xff1b; 对此现象&#xf…

【Linux】-关于Linux的指令(中)

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言一、man指令二、cp指令三、mv指令四、cat指令五、more和less指令六、hea…

【力扣-141】 环形链表 + 【力扣-142】 环形链表 II

&#x1f58a;作者 : Djx_hmbb &#x1f4d8;专栏 : 数据结构 &#x1f606;今日分享 : 霍桑效应(霍索恩效应) : 是指那些意识到自己正在被别人观察的个人具有改变自己行为的倾向。 霍桑效应告诉我们&#xff1a;从旁人的角度&#xff0c;善意的谎言和夸奖真的可以造就一个人&a…