时钟程序基本走时功能加流水灯
- 格式:doc
- 大小:41.50 KB
- 文档页数:9
五种编程方式实现流水灯的单片机C程序流水灯是一种常见的灯光效果,常用于装饰和展示。
实现流水灯的程序可以使用多种不同的编程方式,包括传统的顺序编程、状态机编程、中断编程、调度器编程和面向对象编程。
下面分别介绍这五种方式实现流水灯的程序。
1.顺序编程方式:顺序编程是最常见的编程方式,也是最直接的方式。
下面是使用顺序编程方式实现流水灯的C程序:```c#include <reg52.h>void delay(unsigned int t)while(t--)for(int i=0; i<50; i++);}void mainunsigned char led = 0x80; // 初始灯光状态while(1)P0 = led; // 输出灯光状态delay(500); // 延时一段时间led >>= 1; // 右移一位,实现流水灯效果if(led == 0) // 到达最右边后重新开始led = 0x80;}}```2.状态机编程方式:状态机编程是一种基于状态的编程方式,通过定义不同的状态和状态转换来实现流水灯效果。
下面是使用状态机编程方式实现流水灯的C程序:```c#include <reg52.h>typedef enumState1,State2,State3,State4,State5} State;void delay(unsigned int t)while(t--)for(int i=0; i<50; i++);}void mainState state = State1; // 初始状态为State1 while(1)switch(state)case State1:P0=0x80;delay(500);state = State2;break;case State2:P0=0x40;delay(500);state = State3;break;case State3:P0=0x20;delay(500);state = State4;break;case State4:P0=0x10;delay(500);state = State5;break;case State5:P0=0x08;delay(500);state = State1;break;}}```3.中断编程方式:中断编程方式是一种基于中断事件的编程方式,通过在特定的中断事件触发时改变灯光状态来实现流水灯效果。
流水灯实验原理
流水灯实验是一种常见的电子原型实验,其原理是利用计时器和移位寄存器来控制一组LED灯的亮灭状态,实现灯光顺序
循环变化的效果。
在流水灯实验中,LED灯的亮灭状态是由移位寄存器控制的。
移位寄存器是一个存储二进制数据的器件,它具有将数据从一个位置移动到另一个位置的功能。
通过这种移位操作,可以实现LED灯的顺序变化。
将多个LED灯连接到移位寄存器的输出引脚上,然后将计时
器的时钟信号连接到移位寄存器的时钟输入引脚上。
计时器的时钟信号用于触发移位寄存器的移位操作。
当计时器的时钟信号输入时,移位寄存器会将存储在其中的数据向移位方向移动一位。
移动之后,每个LED灯的状态就发
生了变化,从而实现了灯光顺序的循环变化。
为了控制LED灯的亮灭状态,可以使用二进制计数器作为移
位寄存器的输入。
二进制计数器的输出可以连接到LED灯的
输入引脚上,根据计数器的计数值决定LED灯的亮灭状态。
通过调节计时器的时钟频率和移位寄存器的移位方式,可以实现不同的流水灯效果。
例如,可以设置较快的时钟频率和循环移位的方式,使LED灯的亮灭状态快速顺序变化;或者设置
较慢的时钟频率和单向移位的方式,使LED灯的亮灭状态缓
慢顺序变化。
通过流水灯实验,可以更好地理解计时器、移位寄存器和LED灯的工作原理,同时也能够培养学生的实验操作能力和创新思维。
图1流水灯硬件原理图从原理图中可以看出,假如要让接在PLO 口的LEDI 亮起来,那么只要把 P1.0口的电平变为低电平就可以了;相反,假如要接在PLO 口的LEDl 熄灭,就 要把PLO 口的电平变为高电平洞理,接在P1.1~PL7 口的其他7个LED 的点 亮和熄灭的方法同LED1。
因此,要实现流水灯功能,我们只要将发光二极管 LED1-LED8依次点亮、熄灭,8只LED 灯便会一亮一暗的做流水灯了。
在此 我们还应留意一点,由于人眼的视觉暂留效应以及单片机执行每条指令的时间很 短,我们在掌握二极管亮灭的时候应当延时一段时间,否则我们就看不到“流水” 效果了。
3.软件编程单片机的应用系统由硬件和软件组成,上述硬件原理图搭建完成上电之后, 我们还不能看到流水灯循环点亮的现象,我们还需要告知单片机怎么来进行工PlO POO Pll POl PlJ POi PlJ P03 Pl* PO* P15 PO 5 Pl 3PO 4 P17 λ!SS>C51POT am PJO nττoPnP22 Il pn IO P” P25 I∑∖T> PY P27Xl X :XXD!XD KD ALEP TlPSHT∖n47Kx8VCCLEDl-M —LED)W LED)LED1 W * LEDS人KLEDj WLED7W-44LEDS-M作,即编写程序掌握单片机管脚电平的凹凸变化,来实现发光二极管的一亮一灭。
软件编程是单片机应用系统中的一个重要的组成部分,是单片机学习的重点和难点。
下面我们以最简洁的流水灯掌握功能即实现8个LED灯的循环点亮,来介绍实现流水灯掌握的几种软件编程方法。
3.1位控法这是一种比较笨但又最易理解的方法,采纳挨次程序结构,用位指令掌握Pl 口的每一个位输出凹凸电平,从而来掌握相应LED灯的亮灭。
程序如下:ORG OOOOH ;单片机上电后从0000H地址执行AJMPSTART ;跳转到主程序存放地址处ORG 0030H ;设置主程序开头地址START : MOV SP , #60H ;设置堆栈起始地址为60HCLRPl.0;PLO输出低电平,使LEDl点亮ACALL DELAY ;调用延时子程序SETB P1.0;P1.0输出高电平,使LEDl熄灭CLR Pl.l ;P1.1输出低电平,使LED2点亮ACALL DELAY ;调用延时子程序SETB Pl.l ;P1.1输出高电平,使LED2熄灭CLR P1.2;P1.2输出低电平,使LED3点亮ACALL DELAY ;调用延时子程序SETB P1.2;P1.2输出高电平,使LED3熄灭CLR P1.3 ;P1.3输出低电平,使LED4点亮ACALL DELAY ;调用延时子程序SETB P1.3;P1.3输出高电平,使LED4熄灭CLR Pl.4 ;P1.4输出低电平,使LED5点亮ACALL DELAY ;调用延时子程序SETB P1.4;P1.4输出高电平,使LED5熄灭CLR P1.5;P1.5输出低电平,使LED6点亮ACALL DELAY ;调用延时子程序SETB P1.5;P1.5输出高电平,使LED6熄灭CLR P1.6 ;P1.6输出低电平,使LED7点亮ACALL DELAY ;调用延时子程序CLR P1.7 ;P1.7输出低电平,使LED8点亮ACALL DELAY ;调用延时子程序SETB P1.7pl.7输出高电平,使LED8熄灭ACALL DELAY ;调用延时子程序START ;8个LED流了一遍后返回到标号START处再循环AJMPDELAY :;延时子程序MOV RO , #255 ;延时一段时间Dl : MOV Rl , #255DJNZRl , $DJNZ RO , DlRET ;子程序返回END ;程序结束3.2循环移位法在上个程序中我们是逐个掌握Pl端口的每个位来实现的,因此程序显得有点简单,下面我们采用循环移位指令,采纳循环程序结构进行编程。
流水灯时钟电路工作原理
流水灯时钟电路主要由以下部分组成:时钟电源、电子时钟芯片、驱动电路、LED灯珠。
1. 时钟电源:提供所需的电源电压和电流,通常使用交流电源转换为恒流恒压的直流电源。
2. 电子时钟芯片:控制时钟的运行和显示,一般采用数字时钟芯片。
它可以接收外部的时间信号,将时间信息转化为特定的电信号发送给驱动电路。
3. 驱动电路:接收电子时钟芯片发送的时间信号,根据信号的不同控制LED灯进行点亮和熄灭。
通常采用二进制计数的方式,通过控制特定的输出端口来控制对应的LED灯珠。
4. LED灯珠:通过驱动电路的控制,实现灯珠的点亮和熄灭。
通常使用共阳极的LED灯珠,每个LED灯代表一个数字或符号。
工作原理如下:
电子时钟芯片接收外部的时间信号,将时间信息转化为特定的二进制信号,通过输出端口发送给驱动电路。
驱动电路根据接收到的信号对应控制LED灯珠的点亮和熄灭,从而显示出当
前的时间。
同时,驱动电路还需要保证时间信息的持续更新,以使流水灯时钟能够实现时间的连续显示。
具体来说,驱动电路中,将得到的二进制信号转换为对应的电
平信号,通过开关控制LED灯珠的通断,实现LED的点亮和熄灭。
根据时间的变化,LED灯珠依次点亮和熄灭,形成流水灯效果。
通过适当的控制和驱动,可以实现对年、月、日、小时、分钟等时间信息的显示。
微机原理流水灯流水灯是一种常见的电子产品,它可以通过不同的灯光组合展示出各种图案和文字。
在微机原理中,流水灯也是一个经典的实验项目,通过学习和掌握流水灯的原理和实现方法,可以帮助我们更好地理解微机原理的相关知识。
首先,我们需要了解流水灯的工作原理。
流水灯通常由多个LED灯组成,这些LED灯按照一定的顺序依次亮起,然后熄灭,再依次亮起,如此循环往复。
这种效果可以通过微机原理中的计时器和计数器来实现。
计时器用来控制LED灯的亮起时间,而计数器则用来控制LED灯的顺序。
通过合理地设计计时器和计数器的工作模式,我们就可以实现流水灯的效果。
接下来,我们来介绍一种常见的流水灯实现方法。
首先,我们需要准备一块开发板,例如51单片机开发板。
然后,我们需要连接数个LED灯到开发板的GPIO口上,并且通过电阻限流,以防止LED 灯烧坏。
接着,我们需要编写相应的程序,通过控制计时器和计数器的工作模式,来实现LED灯的流水灯效果。
最后,将程序下载到开发板上,即可看到LED灯按照预定的顺序依次亮起和熄灭,实现流水灯的效果。
除了这种基于单片机的实现方法,我们还可以利用FPGA来实现流水灯。
FPGA是一种可编程逻辑器件,可以根据我们的设计需求来实现各种逻辑功能。
通过使用FPGA,我们可以更加灵活地设计流水灯的工作模式,实现更加丰富多彩的流水灯效果。
当然,相比于基于单片机的实现方法,利用FPGA来实现流水灯可能需要更多的硬件资源和编程知识,但是它可以实现更加复杂和高级的流水灯效果。
总的来说,微机原理中的流水灯实验项目不仅可以帮助我们更好地理解计时器和计数器的工作原理,还可以培养我们的动手能力和创造力。
通过不断地实践和探索,我们可以设计出各种各样的流水灯效果,甚至可以将其应用到实际的电子产品中。
希望大家在学习微机原理的过程中能够加深对流水灯的理解,同时也能够在实践中不断提升自己的能力。
最后,希望大家能够在微机原理的学习中取得更大的进步,为将来的发展打下坚实的基础。
电工创新设计性实验电子数字时钟一、设计任务与要求1. 信号源电路:利用直流电源和555 定时器设计1Hz 的振荡电路。
需要理解555 定时器的结构与原理。
2. 时钟电路:使用计时器、与门、非门实现60进制和24 进制,并设计调时电路和归零电路。
需要深刻理解计时器和逻辑门的功能。
3. 流水灯电路:利用计时器的38 译码器实现流水灯随时间流动。
需要掌握计时器和38 译码器的原理。
、方案设计与论证(一)方案设计方案一、单片机编程时钟电路方案二、纯逻辑时钟电路(二)方案论证选择方案一、单片机编程时钟电路优点:网络资源多,学习成本低,电路设计简单缺点:需要 C 语言基础方案二、纯逻辑时钟电路优点:成就感高,锻炼主动学习能力缺点:网络资源根本没有,学习时间成本高,电路设计复杂最终选择“方案二”三、单元电路设计、参数计算、元器件的选择信号源电路:振荡电路是数字钟的核心部分,它的频率和稳定性直接关系到表的精度。
因此选择555 定时器构成的多谐振荡器,其中电容C1为47 微法,C2为0.01微法,两个电阻R1=R2=10K欧姆。
此时在电路的输出端就得到了一个周期性的矩形波,其振荡频率为:f=1.43/ [(R1+2R2)C]由公式代入R1,R2和C的值得,f=1Hz。
即其输出频率为1Hz 的矩形波信号。
核心元件:555 定时器,电容,电阻时钟电路:信号源电路提供稳定的频率,使第一个计数器 1 秒加一,并通过一个与门和两个非门连接Q1Q3和MR实现累计10 归零,(用两个非门的目的是为了单向传输,避免电位冲突),通过一个与门连接Q0Q3 和下一个计数器相连实现十进制,同样的道理做出了累计6归零,整体实现60 进制,这样秒钟就做好了,相同的方法做出了分钟,由于小时是24进制,所以累计24 归零需要更改复杂,比较费劲。
归零电路要保证每条连接MR 的线路都是要用非门实现单向信号传输,而不能用二极管。
核心元件:计数器(CLK接受高电平后计数,MR接受高电平后重置计数,Q0-3输出 4 位二进制)38译码器(ABC输入3位二进制,Y0-7对应脚输出低电平,其他输出高电平)非门(输出相反电平)流水灯电路:信号源电路提供稳定的频率,使计数器1秒加一,并通过连接Q3和MR实现累计8 归零,Q0-3连接38 译码器使流水灯与秒钟联动。
几种流水灯程序1. 基础流水灯程序:用来控制1个led灯,使其呈现流水灯的效果,代码如下: int led = 13; // 让led连接到电路的13号引脚void setup(){pinMode(led, OUTPUT); // 设置13号引脚的模式为输出}void loop(){digitalWrite(led, HIGH); // 让led灯亮起来delay(1000); // 等待1秒digitalWrite(led, LOW); // 让led灯熄灭int led1 = 13;int led2 = 12;int led3= 11;int led4 = 10;void setup (){pinMode (led1, OUTPUT);pinMode (led2, OUTPUT);pinMode (led3, OUTPUT);pinMode (led4, OUTPUT);}void loop (){digitalWrite (led1, HIGH);delay (500);digitalWrite (led1, LOW);digitalWrite (led2, HIGH);delay (500);digitalWrite (led2, LOW);digitalWrite (led3, HIGH);delay (500);digitalWrite (led3, LOW);digitalWrite (led4, HIGH);delay (500);digitalWrite (led4, LOW);delay (1000);}3.调节速度的流水灯程序:将第一个流水灯程序增加一个模拟变量,使得可以即时调节灯泡亮度以及闪烁速度,以及可以控制单个led灯或多个led灯,其代码如下:4.设置模式的流水灯程序:将流水灯程序改进,使得应用于不同的场景,可以调节闪烁模式,如快速,慢速,长亮等,其代码如下:。
一、实验目的1. 熟悉时序电路的基本原理和设计方法。
2. 掌握FPGA开发软件的使用方法,包括原理图设计、Verilog HDL编程、仿真调试等。
3. 学会使用FPGA实现时序流水灯的功能,并观察其工作效果。
二、实验原理时序流水灯是一种常见的电子电路,通过控制LED灯的亮灭顺序,实现流水灯效果。
本实验采用FPGA实现时序流水灯,主要原理如下:1. 使用FPGA内部寄存器作为计数器,对时钟信号进行计数。
2. 根据计数器的值,通过查找表(LUT)控制LED灯的亮灭顺序。
3. 使用时钟分频器产生定时器时钟,用于更新计数器的值。
三、实验内容1. 使用FPGA开发软件,建立时序流水灯的原理图。
2. 使用Verilog HDL编写时序流水灯的代码。
3. 对代码进行仿真调试,验证其正确性。
4. 将程序烧录到FPGA开发板上,观察时序流水灯的工作效果。
四、实验步骤1. 建立原理图(1)打开FPGA开发软件,创建一个新项目。
(2)添加FPGA芯片,并配置其引脚。
(3)添加时钟信号源,设置时钟频率。
(4)添加计数器模块,设置计数器的位宽和初始值。
(5)添加查找表(LUT)模块,用于控制LED灯的亮灭顺序。
(6)添加时钟分频器模块,产生定时器时钟。
2. 编写Verilog HDL代码(1)创建一个名为`seq_led`的模块,包含以下端口:- `clk`:时钟信号输入- `rst`:复位信号输入- `led`:LED灯输出(2)在模块内部,定义以下信号:- `count`:计数器信号- `led_pattern`:查找表输出信号(3)编写代码实现以下功能:- 初始化计数器和查找表输出信号。
- 在每个时钟周期,对计数器进行加1操作。
- 根据计数器的值,通过查找表输出对应的LED灯亮灭顺序。
3. 仿真调试(1)将编写好的代码添加到原理图中。
(2)设置仿真参数,包括时钟频率、仿真时间等。
(3)启动仿真,观察LED灯的亮灭顺序是否符合预期。
单片机-流水灯的程序流水灯是学习单片机基础知识不可或缺的一个实验,通过流水灯的实现可以掌握单片机 I/O 口的使用、定时器中断的使用以及掌握基本的程序流程控制语句。
本文将介绍流水灯基本概念及实现步骤。
流水灯基本概念流水灯是由多个 LED 灯组成的,每个灯都有一个独立的控制信号,通过按照一定的模式控制信号的输出,就可以实现流水灯的效果。
在单片机中,可以通过将多个 I/O 口作为流水灯中的 LED 控制信号输入口,实现流水灯的效果。
流水灯程序实现步骤在单片机中实现流水灯的程序主要包括以下几个步骤:1.通过 I/O 口控制单片机的 GPIO 端口输出。
2.在控制 GPIO 端口输出时,需要注意端口的方向设置与输出方式的选择。
3.通过控制 GPIO 端口的输出,可以实现 LED 灯的亮灭控制。
4.在亮灭控制中,需要注意定时器中断的使用,以保证流水灯的优美效果。
5.在程序编写的同时,需要考虑到不同型号单片机 I/O 口和定时器的不同特性。
6.需要根据不同的实验要求和要达到的效果,编写相应的程序。
流水灯程序的实现步骤详解下面,将详细介绍流水灯程序的实现步骤:1.首先,需要定义 I/O 口与对应的 LED 灯的对应关系。
一般情况下,LED 灯是连接在单片机的某一 I/O 口上。
我们需要将 I/O 口与 LED 灯的对应关系进行定义,以便在编写程序时可以通过 I/O 口控制 LED 灯的亮灭。
2.接着,需要设置 I/O 口的方向和输出方式。
在单片机的 I/O 口中,默认输入方向,如果要将 I/O 口设置为输出方向,则需要通过软件设置 I/O 口相应的设置寄存器。
同时,需要设置输出方式为推挽输出或是开漏输出,并配置相应的电平。
3.设置定时器。
在流水灯程序中,需通过定时器中断控制 LED 灯的亮灭模式。
需要设置定时器的时钟源、预分频系数、计数值和比较值等参数,以实现不同的滚动速度和亮灭模式。
4.定义中断函数。
中断函数需要根据定时器的计时值进行 LED 灯亮灭的控制操作。
流水灯实验报告引言:流水灯实验是电子学基础课程中的一项重要实践,在学习数字电路与逻辑设计的过程中起着至关重要的作用。
通过实验可以加深对数字电路的理解,以及学会使用固定数量的电子元件来构建复杂的电路。
一、实验目的本次实验的目的是利用数字电路中的逻辑门电路和时序电路来实现一个流水灯。
通过流水灯的演示,学生们将能够理解和掌握多位二进制计数的原理以及基本的逻辑门的用途。
二、实验器材与方法1. 实验器材:- 逻辑门芯片(如与门、或门、非门)- 时钟芯片- 集成电路取线板- LED灯- 电压源2. 实验方法:a. 将逻辑门芯片、时钟芯片和LED灯插入集成电路取线板;b. 使用导线连接逻辑门的输入端和输出端;c. 调整电压源,给电路供电;d. 观察LED灯的亮灭情况,检查流水灯的效果。
三、实验过程与结果在实验过程中,我们选择了两种不同的方法来实现流水灯的效果,分别是基于与门电路和基于时钟芯片控制。
1. 基于与门电路的实现a. 首先,我们准备了四个与门芯片、一个非门芯片和一个LED灯。
b. 将四个与门芯片的输出依次与非门芯片的输入相连。
c. 通过控制与门芯片的输入,使得流水灯的效果能够正确实现。
d. 观察LED灯随着输入变化而灯亮的情况,确保实验成功。
2. 基于时钟芯片控制的实现a. 我们使用了一个时钟芯片、一个非门芯片和四个LED灯。
b. 将时钟芯片的输出连接到非门芯片的输入端。
c. 将非门芯片的输出分别连接到四个LED灯。
d. 通过控制时钟芯片的频率,我们可以实现流水灯效果。
通过以上实验,我们成功实现了基于与门电路和基于时钟芯片控制的流水灯效果。
通过这些实验我们可以得出以下结论:结论:1. 利用逻辑门芯片可以实现多位二进制计数,从而实现流水灯的效果;2. 时钟芯片的输入信号能够控制流水灯的亮灭情况,实现了流水灯的自动化效果;3. 实验过程中LED灯的亮灭情况与输入信号的变化是一一对应的,验证了实验的正确性。
第一章单片机的基础学习第一个实验 LED发光二极管的左移右移(D1到D8依次)点亮二极管点亮的原理图如下。
实际上是接在P1口。
原理图说明:发光二极管阴极接单片机,让电流流入单片机,因为单片机输出电流小,点不亮发光二极管。
发光二极管点亮电流为5 mA至20mA。
编程说明:(1)做一个LED的左移右移,有硬件电路可知,输出“0”才能使LED亮。
开始时P1.0亮,——P1.1亮——P1.2亮….——P1.7亮——P1.0亮,重复循环点亮LED。
(2)延时时间的设计:石英晶体为12MHz,1个机器周期为1微秒,采用单片机每走一步指令需要的时间来延时。
✧延时时间子程序(10.002毫秒)Delay: MOV R4,#20 ;2个机器周期,2微秒D1: MOV R5,#248 ;2个机器周期,2微秒DJNZ R5,$ ;2个机器周期,2*248微秒DJNZ R4,D1 ;2个机器周期,2*20微秒RET这个延时子程序:20*(498+2)+2=10002个机器周期=10.002毫秒。
✧延时时间子程序(200毫秒)Delay: MOV R3,#20 ; 200微秒D1:MOV R4,#20 ;10微秒D2: MOV R5,#248DJNZ R5,$DJNZ R4,D2DJNZ R3,D1RET(3)汇编程序源代码注意:向电脑上编辑程序时注意标点符号要在英文的格式下输入。
ORG 00HMAIN: MOV A,#0FFHCLR CMOV R2,#08H;左移点亮发光二极管LOOP: RLC A ;带进位左移一位MOV P1,A;点亮LED发光二极管CALL DELAY;调用延时子程序DJNZ R2,LOOP;左移、轮流点亮发;光二极管;左移点亮发光二极管后,再右移点亮发光二极管MOV R2,#07HLOOP1: RRC A ;带进位右移一位MOV P1,A;点亮LED发光二极管CALL DELAY;调用延时子程序DJNZ R2,LOOP1JMP MAIN; 返回到初始位置;设置延时时间DELAY: MOV R3,#20D1: MOV R4,#20D2: MOV R5,#248DJNZ R5,$DJNZ R4,D2DJNZ R3,D1RETEND(4)C程序源代码#include <reg51.h>void Delay()//延时子程序{ int i,j;for(i=0;i<=255;i++)for(j=0;j<=255;j++);}void main(){unsigned int i;unsigned int temp;P1=0xff;while(1){temp=0x01;for(i=0;i<8;i++){P1=~temp;逐位取反Delay();temp=temp<<1;}}}(4)实验结果图(注意学习板上的JJ_P1连接器连上)第二个实验采用定时器来设置延时时间(方式0)说明:(1)开始时p1.0亮,延时0.2秒后左移至p1.1亮,如此左移7次后至,再延时0.2秒右移至p1.6亮,如此右移7次后至p1.0亮;(2)延时时间0.2秒,使用定时器0在方式0下工作;采用查询的方式(3)程序源代码ORG 00HMOV TMOD,#00H /***设置定时器的工作方式***/START: CLR CMOV A,#0FFHMOV R2,#08 /***设置循环次数***/LOOP: RLC A /***带进位左循环累加器,点亮发光二极管***/ MOV P1,A /***设置定时器定时时间***/MOV R3,#100CALL DELAYDJNZ R2,LOOP /***点亮了八个发光二极管吗,没有继续***/MOV R2,#07LOOP1: RRC AMOV P2,AMOV R3,#100CALL DELAYDJNZ R2,LOOP1JMP START/***通过单片机内部的定时器设置定时时间***/DELAY: SETB TR0 /***启动定时器***/AGAIN: MOV TL0,#(8192-2000) MOD 32MOV TH0,#(8192-2000) / 32LOOP2: JBC TF0,LOOP3 ;通过查询的方式来判断时间定时器的计时JMP LOOP2LOOP3: DJNZ R3,AGAINCLR TR0RET;非中断END(4)实验结果图第三个实验采用定时器来设置延时时间(方式1)(1)开始时p1.0亮,延时0.2秒后左移至p2.1亮,如此左移7次后至,再延时0.2秒右移至p1.7亮,如此右移7次后至p1.0亮;(2)延时时间0.2秒,使用定时器0在方式1下工作;采用查询的方式(3)源程序代码ORG 00HMOV TMOD,#01HSTART: CLR CMOV A,#0FFHMOV R2,#08LOOP: RLC AMOV P1,AMOV R3,#20CALL DELAYDJNZ R2,LOOPMOV R2,#07LOOP1: RRC AMOV P1,AMOV R3,#20CALL DELAYDJNZ R2,LOOP1JMP STARTDELAY: SETB TR0AGAIN: MOV TL0,#0F0HMOV TH0,#0D8HLOOP2: JBC TF0,LOOP3JMP LOOP2LOOP3: DJNZ R3,AGAINCLR TR0RETEND附录资料:红外发射器的原理图AT89S52下载器的原理图。
在实时钟及流水灯的设计一、实验目的:通过实验,让我们进一步了解、熟悉和掌握CPLD开发软件的使用方法;通过原理图输入设计方法和VHDL编程法加深对其知识的掌握与巩固;并学习简单时序电路的设计。
二、实验要求:1.画出实验设计原理框图;2.分模块对实验原理进行简要说明;3.进行软件验证,并保存波形仿真结果;4.写出实验心得体会。
三、实验原理框图:从原理图中可以看出一共有5个模块,1个con4m模块、2个led模块、1个sc 模块、一个led12模块。
2个输入端:CLR、CLK;43个输出端:SLA……SLG,SHA……SHG,MLA……MLG,MHA……MHG,Q1……Q8,HA……HG。
四、单元模块设计:1.con4m模块:功能:为模4M计数器/分频器。
它有2个输入端口:CLR、CLK。
2个输出端口:CSP、CSN。
CSP为正极性输出,CSN为负极性输出,且CSP超前CSN一个时钟周期。
VHDL语言程序如下:SUBDESIGN Con4m(CLR,CLK : INPUT ;CSP,CSN : OUTPUT;)VARIABLECOUNT[21..0]: DFF;BEGINcount[].clk=CLK;COUNT[].CLRN=CLR;CSP=(count[]==0);CSN=!(count[]==1);IF count[]<3999999 THENcount[]=count[]+1;ELSEcount[]=0;END IF;END;2.Led60模块:功能:为模60LED显示计数器。
它有 1个con60、2个7seg模块构成。
它有三个输入端口(PE、CLR、CLK),15个输出端口(LA…LG,HA…HG,CO)。
Led60模块软件仿真结果如下图所示:功能:六进制计数器软件仿真结果如下所示7seg模块:VHDL语言程序如下:SUBDESIGN 7seg(dat[3..0] : INPUT ;a,b,c,d,e,f,g : OUTPUT;)BEGINTABLEdat[3..0] => a,b,c,d,e,f,g;0 => 0,0,0,0,0,0,1;1 => 1,0,0,1,1,1,1;2 => 0,0,1,0,0,1,0;3 => 0,0,0,0,1,1,0;4 => 1,0,0,1,1,0,0;5 => 0,1,0,0,1,0,0;6 => 0,1,0,0,0,0,0;7 => 0,0,0,1,1,1,1;8 => 0,0,0,0,0,0,0;9 => 0,0,0,0,1,0,0;10 => 0,0,0,1,0,0,0;11 => 1,1,0,0,0,0,0;12 => 0,1,1,0,0,0,1;13 => 1,0,0,0,0,1,0;14 => 0,1,1,0,0,0,0;15 => 0,1,1,1,0,0,0;END TABLE;END;3.Sc模块:功能:流水灯控制电路。
#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit jiak=P2^3;sbit youyik=P2^2;sbit zuoyik=P2^1;sbit jiank=P2^0;sbit int1k=P3^3;sbit FMQ=P1^1;sbit CLK=P3^5;//1302时钟信号线sbit IO=P3^6;//1302的I/O数据线sbit RST=P3^7;//1302的RST复位线void InputByte(uchar);//输入1Byteuchar OutputByte(uchar);//输出1Bytevoid W1302(uchar,uchar);uchar R1302(uchar);uchar tab[6];void key();void display();void init();uchar a,c,i,b;//c表示中断次数a表示数码管移位次数uint temp;uchar miao,fen,shi;uchar tab1[7]={0x40,0x59,0x11,0x11,0x02,0x06,0x06};uchar code tab2[10]={0x88,0Xbe,0Xc4,0X94,0Xb2,0X91,0X81,0Xbc,0X80,0X90}; sbit zy=P2^1;sbit yy=P2^2;bit flagg;uchar zz,time;uchar code tabp0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff}; uchar code tabp2[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef};//延时1msvoid delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//往1302写入1Byte d为写入的数据入口参数void InputByte(uchar date){uchar i;ACC=date;for(i=8;i>0;i--){IO=ACC0;//相当于汇编中的RRCCLK=1;CLK=0;ACC=ACC>>1;}}//从1302读取1Byte数据返回值ACCuchar OutputByte(void){uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}//往1302写入数据先写地址后写数据ucADD ucDA是入口参数void W1302(uchar addr,uchar date){RST=0;CLK=0;RST=1;InputByte(addr);//写地址InputByte(date);//写1Byte数据CLK=1;RST=0;}//读取1302某地址的数据先写地址后读数据ucAddr入口地址ucDa是返回值uchar R1302(uchar addr){uchar date;RST=0;CLK=0;RST=1;InputByte(addr);//写地址date=OutputByte();//读1Byte数据CLK=1;RST=0;return(date);}//初始化设置初始值void init(){uchar i1;uchar addr=0x80;W1302(0x8e,0x00);//控制命令字节WP=0 写操作for(i1=0;i1<7;i1++){W1302(addr,tab1[i1]);//秒分时日月星期年addr+=2;}W1302(0x90,0xa6);W1302(0x8e,0x80);//控制命令字节WP=1写保?}void display(){uchar Curtime[7];uchar i,i2;uchar addr=0x81;for(i2=0;i2<7;i2++){Curtime[i2]=R1302(addr);//格式秒分时日月星期年addr+=2;}miao=Curtime[0];if(time!=miao){ time=miao;flagg=1;}fen=Curtime[1];shi=Curtime[2];tab[5]=miao%16;tab[4]=miao/16;tab[3]=fen%16;tab[2]=fen/16;tab[1]=shi%16;tab[0]=shi/16;for(i=0;i<6;i++){SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(20);if(flagg==1){flagg=0;P0=tabp0[zz];P2=tabp2[zz];zz++;if(zz==12)zz=0;FMQ=0;delay(20);FMQ=1;}}//主函数void main(){display();if(shi==0x00&&fen==0x00&&miao==0x80)init();EA=1;EX1=1;IT1=1;while(1){if(c!=1)display();if(fen==0x00&&miao<=5)FMQ=0;}}//外部中断1void int1() interrupt 2{while(1){if(int1k==0) //扫描p3{delay(20);if(int1k==0){while(!int1k);W1302(0x8e,0x00);a=1;c++;if(c==2)c=0;}}if(c==1){if(youyik==0) //扫描键盘{delay(20);if(youyik==0){while(!youyik);a+=2;if( a==7) a=1;}}if(zuoyik==0){delay(20);if(zuoyik==0){while(!zuoyik);if( a==1)a=7;a-=2;}}for(i=0;i<6;i++) //这个循环是个关键{if( a==i){b=a;SBUF=0xff;}else SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(100);if(b==a){if(jiak==0){delay(20);if(jiak==0){while(!jiak);switch(b){case 1: tab[1]++;if(tab[1]==10){ tab[1]=0;tab[0]++;}if(tab[0]==2&&tab[1]==4){tab[0]=0;tab[1]=0;}shi=tab[0]*10+tab[1];W1302(0x84,(shi/10)*16+shi%10);break;case 3: tab[3]++;if(tab[3]==10){ tab[3]=0;tab[2]++;}if(tab[2]==6&&tab[3]==0){tab[2]=0;tab[3]=0;}fen=tab[2]*10+tab[3];W1302(0x82,(fen/10)*16+fen%10);break;case 5: tab[5]++;if(tab[5]==10){ tab[5]=0;tab[4]++;}if(tab[4]==6&&tab[5]==0){tab[4]=0;tab[5]=0;}miao=tab[4]*10+tab[5];W1302(0x80,(miao/10)*16+miao%10);break;}}}if(jiank==0){delay(20);if(jiank==0){while(!jiank);switch(b){case 1: if(tab[0]==0&&tab[1]==0){ tab[0]=2;tab[1]=4;}if(tab[1]==0){ tab[1]=10;tab[0]--;}tab[1]--;shi=tab[0]*10+tab[1];W1302(0x84,(shi/10)*16+shi%10);break;case 3: if(tab[2]==0&&tab[3]==0){ tab[2]=6;tab[3]=0;}if(tab[3]==0){ tab[3]=10;tab[2]--;}tab[3]--;fen=tab[2]*10+tab[3];W1302(0x82,(fen/10)*16+fen%10);break;case 5: if(tab[4]==0&&tab[5]==0){ tab[4]=6;tab[5]=0;}if(tab[5]==0){ tab[5]=10;tab[4]--;}tab[5]--;miao=tab[4]*10+tab[5];W1302(0x80,(miao/10)*16+miao%10);break;}}}}for(i=0;i<6;i++){SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(100);}if(c==0)break;}}#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit jiak=P2^3;sbit youyik=P2^2;sbit zuoyik=P2^1;sbit jiank=P2^0;sbit int1k=P3^3;sbit FMQ=P1^1;sbit CLK=P3^5;//1302时钟信号线sbit IO=P3^6;//1302的I/O数据线sbit RST=P3^7;//1302的RST复位线void InputByte(uchar);//输入1Byteuchar OutputByte(uchar);//输出1Bytevoid W1302(uchar,uchar);uchar R1302(uchar);uchar tab[6];void key();void display();void init();uchar a,c,i,b;//c表示中断次数a表示数码管移位次数uint temp;uchar miao,fen,shi;uchar tab1[7]={0x40,0x59,0x11,0x11,0x02,0x06,0x06};uchar code tab2[10]={0x88,0Xbe,0Xc4,0X94,0Xb2,0X91,0X81,0Xbc,0X80,0X90}; sbit zy=P2^1;sbit yy=P2^2;bit flagg;uchar zz,time;uchar code tabp0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff}; uchar code tabp2[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef};//延时1msvoid delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//往1302写入1Byte d为写入的数据入口参数void InputByte(uchar date){uchar i;ACC=date;for(i=8;i>0;i--){IO=ACC0;//相当于汇编中的RRCCLK=1;CLK=0;ACC=ACC>>1;}}//从1302读取1Byte数据返回值ACCuchar OutputByte(void){uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}//往1302写入数据先写地址后写数据ucADD ucDA是入口参数void W1302(uchar addr,uchar date){RST=0;CLK=0;RST=1;InputByte(addr);//写地址InputByte(date);//写1Byte数据CLK=1;RST=0;}//读取1302某地址的数据先写地址后读数据ucAddr入口地址ucDa是返回值uchar R1302(uchar addr){uchar date;RST=0;CLK=0;RST=1;InputByte(addr);//写地址date=OutputByte();//读1Byte数据CLK=1;RST=0;return(date);}//初始化设置初始值void init(){uchar i1;uchar addr=0x80;W1302(0x8e,0x00);//控制命令字节WP=0 写操作for(i1=0;i1<7;i1++){W1302(addr,tab1[i1]);//秒分时日月星期年addr+=2;}W1302(0x90,0xa6);W1302(0x8e,0x80);//控制命令字节WP=1写保?}void display(){uchar Curtime[7];uchar i,i2;uchar addr=0x81;for(i2=0;i2<7;i2++){Curtime[i2]=R1302(addr);//格式秒分时日月星期年addr+=2;}miao=Curtime[0];if(time!=miao){ time=miao;flagg=1;}fen=Curtime[1];shi=Curtime[2];tab[5]=miao%16;tab[4]=miao/16;tab[3]=fen%16;tab[2]=fen/16;tab[1]=shi%16;tab[0]=shi/16;for(i=0;i<6;i++){SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(20);if(flagg==1){flagg=0;P0=tabp0[zz];P2=tabp2[zz];zz++;if(zz==12)zz=0;FMQ=0;delay(20);FMQ=1;}}//主函数void main(){display();if(shi==0x00&&fen==0x00&&miao==0x80)init();EA=1;EX1=1;IT1=1;while(1){if(c!=1)display();if(fen==0x00&&miao<=5)FMQ=0;}}//外部中断1void int1() interrupt 2{while(1){if(int1k==0) //扫描p3{delay(20);if(int1k==0){while(!int1k);W1302(0x8e,0x00);a=1;c++;if(c==2)c=0;}}if(c==1){if(youyik==0) //扫描键盘{delay(20);if(youyik==0){while(!youyik);a+=2;if( a==7) a=1;}}if(zuoyik==0){delay(20);if(zuoyik==0){while(!zuoyik);if( a==1)a=7;a-=2;}}for(i=0;i<6;i++) //这个循环是个关键{if( a==i){b=a;SBUF=0xff;}else SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(100);if(b==a){if(jiak==0){delay(20);if(jiak==0){while(!jiak);switch(b){case 1: tab[1]++;if(tab[1]==10){ tab[1]=0;tab[0]++;}if(tab[0]==2&&tab[1]==4){tab[0]=0;tab[1]=0;}shi=tab[0]*10+tab[1];W1302(0x84,(shi/10)*16+shi%10);break;case 3: tab[3]++;if(tab[3]==10){ tab[3]=0;tab[2]++;}if(tab[2]==6&&tab[3]==0){tab[2]=0;tab[3]=0;}fen=tab[2]*10+tab[3];W1302(0x82,(fen/10)*16+fen%10);break;case 5: tab[5]++;if(tab[5]==10){ tab[5]=0;tab[4]++;}if(tab[4]==6&&tab[5]==0){tab[4]=0;tab[5]=0;}miao=tab[4]*10+tab[5];W1302(0x80,(miao/10)*16+miao%10);break;}}}if(jiank==0){delay(20);if(jiank==0){while(!jiank);switch(b){case 1: if(tab[0]==0&&tab[1]==0){ tab[0]=2;tab[1]=4;}if(tab[1]==0){ tab[1]=10;tab[0]--;}tab[1]--;shi=tab[0]*10+tab[1];W1302(0x84,(shi/10)*16+shi%10);break;case 3: if(tab[2]==0&&tab[3]==0){ tab[2]=6;tab[3]=0;}if(tab[3]==0){ tab[3]=10;tab[2]--;}tab[3]--;fen=tab[2]*10+tab[3];W1302(0x82,(fen/10)*16+fen%10);break;case 5: if(tab[4]==0&&tab[5]==0){ tab[4]=6;tab[5]=0;}if(tab[5]==0){ tab[5]=10;tab[4]--;}tab[5]--;miao=tab[4]*10+tab[5];W1302(0x80,(miao/10)*16+miao%10);break;}}}}for(i=0;i<6;i++){SBUF=tab2[tab[i]];while(!TI);TI=0;}delay(100);}if(c==0)break;}}}。
蓝桥杯嵌⼊式——SysTick定时器与流⽔灯流⽔灯如何实现?思路不妨和熟悉的数字逻辑电路做⽐较,⽐如需要从右往左依次点亮,那么将clk(晶振50MHz)分频,使⽤计数器,不断计数到预定时间(⽐如1s),然后将output⽤Led_Disp输出。
⽽MCU中也是⼀样的逻辑,并且它已经设置好了⼀个定时器(24bit)(或者说计数器),⾃动地从0开始计数,到预定值清零,我们所需的只是调⽤它,⽽不需要重新写⼀个计数器。
实现⽅法:1.将SysTick的频率改为指定的1s,但是要知道,SysTick是给MCU很多资源使⽤的时钟,⼀般使⽤72MHz或者80MHz,如果为了点灯把它设置为1Hz,会极⼤降低Mcu⼯作速度,得不偿失。
2.将SysTick的频率设置到⼀定值(很⾼的频率,但是同时是⼀些整数倍的关系),这样为⼈为写⼀个变量,每次都递增,(也就是⼀个计数器),到预定值之后执⾏操作,也能实现功能。
SysTick 简介SysTick—系统定时器是属于 CM3 内核中的⼀个外设,内嵌在 NVIC 中。
系统定时器是⼀个 24bit的向下递减的计数器,计数器每计数⼀次的时间为 1/SYSCLK,⼀般我们设置系统时钟 SYSCLK等于 72M。
当重装载数值寄存器的值递减到 0 的时候,系统定时器就产⽣⼀次中断,以此循环往复。
因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单⽚机都具有这个系统定时器,使得软件在 CM3 单⽚机中可以很容易的移植。
系统定时器⼀般⽤于操作系统,⽤于产⽣时基,维持操作系统的⼼跳。
(这是依照CM3内核介绍的systick,m4内核还没了解)寄存器相关操作⽅法:具体的sys_configure可以直接使⽤cubemx⽣成,有空的话之后再读⼀下库函数。
之后在startup.stm32g4xx.s中找到中断函数命名,再找到定义位置,然后将原有中断函数注释,⾃⼰编写中断服务函数。
#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar a;uchar XPOS,YPOS;sbit RS = P2^5; //Pin4sbit RW = P2^6; //Pin5sbit E = P2^7; //Pin6sbit CLK=P3^6; //txdsbit DA TA=P3^5; //RXDsbit SH_LD=P3^7; //sbit buz=P3^4;#define Data P0 //数据端口uchartime,shi,fen,miao,shi11,shi12,fen11,fen12,miao11,miao12,miao1,fen1,shi1,y ue1,r1,nian11,nian12,nian13,nian14,yue,yue11,yue12,r,r11,r12;uchar Time1[]={'0','1','2','3','4','5','6','7','8','9'};uint nian,nian1;/************************************************************* *****//* 函数声明*//************************************************************* *****//******************************************************* ********/void DelayUs(unsigned char us)//delay us{unsigned char uscnt;uscnt=us>>1;/* Crystal frequency in 12MHz*/while(--uscnt);}/******************************************************************/void DelayMs(unsigned char ms)//delay Ms{while(--ms){DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);}}void WriteCommand(unsigned char c){DelayMs(5);//short delay before operationE=0;RS=0;RW=0;_nop_();E=1;Data=c;E=0;}/************************************************************* ***/void WriteData(unsigned char c){DelayMs(5); //short delay before operationE=0;RS=1;RW=0;_nop_();E=1;Data=c;E=0;RS=0;}/************************************************************* ********/void ShowChar(unsigned char pos,unsigned char c){unsigned char p;//p=pos+0x80; //是第二行则命令代码高4位为0x8 p=pos;WriteCommand (p);//write commandWriteData (c); //write data}void Writer_zfc(uchar cspos,uchar*s){WriteCommand (cspos);while(*s!='\0'){WriteData (*s);s++;}}void InitLcd(){DelayMs(15);WriteCommand(0x38); //display mode WriteCommand(0x38); //display mode WriteCommand(0x0f); //display mode WriteCommand(0x06); //显示光标移动位置WriteCommand(0x0c); //显示开及光标设置WriteCommand(0x01); //显示清屏}void Wenzi_yiwei(int z){int i;for(i=0;i<z;i++){DelayMs(1000);WriteCommand(0x18);}}void Liushui_d(){P1=_crol_(P1,1);DelayMs(1000);}void initiatejs0(void){time=0;//全局变量随计数器而加一TMOD=0X01;//js0工作于方式一下16位的,外部中断不起作用TH0=0x4b;TL0=0xff;ET0=1;//ET0源允许EA=1;//EA总允许TR0=1;//启动js0}void sufas(uchar shi0)//得到时分秒,各位{shi11=shi0/10;shi12=shi0%10;}void sufaf(uchar fen0){fen11=fen0/10;fen12=fen0%10;}void sufam(uchar miao0){miao11=miao0/10;miao12=miao0%10;}void sufan(uint nian0){nian11=nian0/1000;nian12=(nian0%1000)/100;nian13=((nian0%1000)%100)/10;nian14=((nian0%1000)%100)%10;}void sufay(uchar yue0){yue11=yue0/10;yue12=yue0%10;}void sufar(uchar r0){r11=r0/10;r12=r0%10;}void SJ_intial(){nian=2013;sufan(nian);yue=1;sufay(yue);r=7;sufar(r);shi=23;sufas(shi);fen=59;sufaf(fen);miao=40;sufam(miao);Writer_zfc(0x80,"TIME : : ");Writer_zfc(0xC0,"DA TE >-__-< ");ShowChar(0xc5,Time1[nian11]);ShowChar(0xc6,Time1[nian12]);ShowChar(0xc7,Time1[nian13]);ShowChar(0xc8,Time1[nian14]);ShowChar(0xca,Time1[yue11]);ShowChar(0xcb,Time1[yue12]);ShowChar(0xcd,Time1[r11]);ShowChar(0xce,Time1[r12]);ShowChar(0x86,Time1[shi11]);ShowChar(0x87,Time1[shi12]);ShowChar(0x89,Time1[fen11]);ShowChar(0x8a,Time1[fen12]);ShowChar(0x8c,Time1[miao11]);ShowChar(0x8d,Time1[miao12]);}void SJ_xianshi(uchar shi,uchar fen,uchar miao) {if(miao!=miao1){sufam(miao);ShowChar(0x8c,Time1[miao11]);ShowChar(0x8d,Time1[miao12]);miao1=miao;}if(fen!=fen1){sufaf(fen);ShowChar(0x89,Time1[fen11]);ShowChar(0x8a,Time1[fen12]);fen1=fen;}if(shi!=shi1){sufas(shi);ShowChar(0x86,Time1[shi11]);ShowChar(0x87,Time1[shi12]);shi1=shi;}if(r!=r1){sufar(r);ShowChar(0xcd,Time1[r11]);ShowChar(0xce,Time1[r12]);r1=r;}if(yue!=yue1){sufay(yue);ShowChar(0xca,Time1[yue11]);ShowChar(0xcb,Time1[yue12]);yue1=yue;}if(nian!=nian1){sufan(nian);ShowChar(0xc5,Time1[nian11]);ShowChar(0xc6,Time1[nian12]);ShowChar(0xc7,Time1[nian13]);ShowChar(0xc8,Time1[nian14]);nian1=nian;}}void SJ_xz(){if(miao==60){fen++;miao=0;if(fen==60){shi++;fen=0;if(shi==24){r++;shi=0;if((yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)&&r> 31){r=1;yue++;if(yue>12){nian++;yue=1;}}else{if((yue==4||yue==6||yue==9||yue==11)&&r>30){r=1;yue++;}else{if((yue==2||nian%100==0)&&r>29&&nian%400==0){yue++;r=1;}else{if((yue==2||nian%100==0)&&(nian%400!=0)&&(r>28)){yue++;r=1;}else{if((yue==2||nian%100!=0)&&(nian%4==0)&&r>29){yue++;r=1;}}}}}}}}}void FM_baoshi(){if(fen==0&&(miao==1||miao==2||miao==3||miao==4||miao==5)){buz=~buz;DelayMs(500);}buz=1;}void main(){InitLcd();WriteCommand(0x01);SJ_intial();initiatejs0();P1=0XEE;while(1){FM_baoshi();SJ_xz();SJ_xianshi(shi,fen,miao);//Wenzi_yiwei(1);Liushui_d();}}void js0(void) interrupt 1{TH0=0x4b;//一次中断50毫秒TL0=0xff;time++;if(time==20){//P1=0Xfe;time=0;miao++;}}。