Arduino驱动MAX7219四位数码管显示时间
Arduino驱动MAX7219四位数码管显示时间
Arduino驱动MAX7219四位数码管显示时间Arduino驱动MAX7219四位数码管显示时间默认使用Pin 2为MOSI(数据发送)引脚,Pin 3为CS(片选)引脚,Pin 4为SCLK(时钟)引脚,如有需要请修改代码前三行的define。
#define MO 2#define CS 3#define CLK 4static int time_h = 21, time_m =25, time_s = 30; //此刻时间:时,分,秒int alarm_clock_h = 8, alarm_clock_m = 00; //闹钟时间unsigned long time = 0;unsigned char buffer_led[5] = { 0x00,};//缓存void SPI_init(void) //初始化SPI引脚{pinMode(CLK, OUTPUT);pinMode(MO, OUTPUT);pinMode(CS, OUTPUT);digitalWrite(CS, HIGH);digitalWrite(CLK, LOW);digitalWrite(MO, HIGH);}void SPI_send(unsigned char reg, unsigned char data) //spi 单向16位数据发送{int x;/*Serial.print("reg = ");Serial.print(reg, HEX);Serial.print(" data = ");Serial.println(data, HEX);*/digitalWrite(CS, LOW);for (x = 0; x < 8; x++){digitalWrite(MO, 0x80 & (reg << x)); //高位在前digitalWrite(CLK, HIGH);digitalWrite(CLK, LOW);}for (x = 0; x < 8; x++){digitalWrite(MO, 0x80 & (data << x)); //高位在前digitalWrite(CLK, HIGH);digitalWrite(CLK, LOW);}digitalWrite(CS, HIGH);}void lcd_init(void)//初始化Max7219配置{SPI_send(0x0b, 0x07); //scan-limitSPI_send(0x09, 0xff); //decode mode allSPI_send(0x0c, 0x01); //shutdown offSPI_send(0x0f, 0x00); //off display testSPI_send(0x0a, 0x04); //intensitydelay(100);}void clear(void)//清除显示{for (int i = 1; i <= 8; i++){SPI_send(i, 0x0F);}}void led_display(void)//显示时间{char cache = 0x00;if ((time_h / 10) == 0)buffer_led[0] = 0x00;else buffer_led[0] = time_h / 10;buffer_led[1] = time_h % 10 | 0x01;buffer_led[2] = time_m / 10;buffer_led[3] = time_m % 10;SPI_send(8, buffer_led[0]);SPI_send(7, buffer_led[1]);SPI_send(6, 0x0a);SPI_send(5, buffer_led[2]);SPI_send(4, buffer_led[3]);SPI_send(3, 0x0a);SPI_send(2, time_s / 10);SPI_send(1, time_s % 10);}void get_time()//获取时间并更新显示{static char ss = 1;static unsigned long time_cc = 0;if ((millis() - time_cc) > 1000 | millis() < 150)//秒{if (millis() <= 200) //若系统计时器溢出时时间,time_cc重计{time_cc = millis();time_s ++;delay(150);}else if (millis() > 200)//秒{time_s += (millis() - time_cc) / 1000;// time_cc = millis()-990; //时间快进time_cc = millis();buffer_led[4] = (0x01 & ss) << 5;ss = ~ss;}if (time_s > 59) //分{if (time_s - 60 > 1)//如果有延时间隔导致秒钟大于60秒,进行分钟缺失补偿 {time_m += time_s / 60;if (time_s % 60 == 0)time_m--;time_s = time_s - (time_s / 60) * 60;}else time_s = 0;time_m++;buffer_led[4] = 0x80;if (time_m > 59)//时{time_h++;time_m = (time_m - 60);buffer_led[4] = 0xf0;}if (time_h > 23){time_h = 0;time_s += 5; //时间误差补偿}}// Serial.print("millis="); // Serial.print(time_cc);// Serial.print(" time="); // Serial.print(time_h);// Serial.print(":");// Serial.print(time_m);// Serial.print(":");// Serial.println(time_s); led_display();//刷新数码管显示}}void setup(){Serial.begin(9600);SPI_init();lcd_init();clear();}void loop(){get_time();}。
串行LED显示驱动器MAX7219及其应用
串行L ED显示驱动器M AX7219及其应用胡奕明(空军工程大学工程学院研究生大队 西安 710038)摘 要 阐述了新型显示驱动芯片M A X7219的基本工作原理和软件设计方法。
该芯片功能强大、编程简单、控显可靠,可广泛用于工业控制器等方面的数码显示驱动。
关键词 显示驱动器 串行发送 M A X72191 概 述M A X7219是美国M A X I M公司生产的串行输入 输出共阴极显示驱动器。
该芯片可直接驱动最多8位7段数字L ED显示器,或64个L ED和条形图显示器。
它与微处理器的接口非常简单,仅用3个引脚与微处理器相应端连接即可实现最高10M H z 串行接口。
M A X7219的位选方式独具特色,它允许用户选择多种译码方式译码选位,而且,每个显示位都能个别寻址和刷新,而不需要重写其他的显示位,这使得软件编程十分简单且灵活。
另外,它具有数字和模拟亮度控制以及与M O TOROLA SP I, Q SP I及M A T I ONAL M I CROW I R E串行口相兼容等特点。
2 引脚说明该芯片采用24脚D IP和SO封装,工作电压410~515V,最大功耗111W。
引脚说明见表1。
3 基本工作原理及使用方法M A X7219与8031单片机连接采用三线串行接口,典型应用电路如图1。
对于M A X7219,串行数据是以16位数据包的形式从D in脚串行输入,在CL K的每一个上升沿一位一位地送入芯片内部16位移位寄存器,而不管L out脚的状态如何。
L oad脚必须在第16个CL K上升沿出现的同时或之后,但在下一个CL K上升沿之前变为高电平,否则移入的数据将丢失。
表1 引脚说明引脚号名称功能说明1D in串行数据输入端。
在CL K的上升沿数据被锁入芯片内部16位移位寄存器2,3,5~8,10,11D IG0~D IG78位L ED位选线,从共阴极L ED中吸入电流4,9GND地线(两个GND必须接在一起)12L oad锁入输入的数据。
4位数码管循环
4位数码管循环4位数码管可以显示0-9的数字,因此可以通过循环实现数字的循环显示。
一种简单的方式是使用四个数码管分别显示个位、十位、百位和千位的数字。
通过循环不断更新这四个数码管的显示内容,就可以实现数字的循环显示。
以下是一个示例代码:```c#include <avr/io.h>#include <avr/delay.h>void displayDigit(uint8_t digit){// 根据数字设置对应的数码管段亮起switch (digit) {case 0:PORTA = 0b00111111;break;case 1:PORTA = 0b00000110;break;case 2:PORTA = 0b01011011;break;case 3:PORTA = 0b01001111;break;case 4:PORTA = 0b01100110;break;case 5:PORTA = 0b01101101;break;case 6:PORTA = 0b01111101;break;case 7:PORTA = 0b00000111;break;case 8:PORTA = 0b01111111;break;case 9:PORTA = 0b01101111;break;default:// 如果传入的数字不在0-9之间,将所有数码管熄灭 PORTA = 0b00000000;break;}}int main(void){// 设置端口A为输出端口DDRA = 0xFF;while (1) {for (int i = 0; i < 10000; i++) {int thousands = i / 1000;int hundreds = (i % 1000) / 100;int tens = (i % 100) / 10;int ones = i % 10;// 分别显示千位、百位、十位和个位的数字displayDigit(thousands);_delay_ms(10);displayDigit(hundreds);_delay_ms(10);displayDigit(tens);_delay_ms(10);displayDigit(ones);_delay_ms(10);}}return 0;}```此代码使用的是ATmega系列的单片机,使用了端口A的8个引脚来控制四个数码管的段的亮灭。
原创数码管动态显示时间(0-999秒倒计时)
数码管动态显示时间(0-999秒倒计时)原理图:
控制部分
数码管时间显示,微动按键时间调整,工作手具转换,启动和复位程序。
1.待机:时间显示010秒.D6灯亮,此时ZHH,GZ无输出。
2.转换键:待机D5和D6状态可相互转换,开机常态体腔指示灯亮ZHH,GZ无输出。
按一下转换到D5状态,D5
指示灯亮ZHH输出,再按一下转换到D6状态,体腔指示灯亮ZHH无输出。
3.“加”“减”键:可调时间000-999秒,可快加和快减时间,每秒10个数变化。
慢加和慢减时间,每按一下变化1
个数。
4.复位键:工作和报警中可用,复位到设定状态。
5.手柄启动键:设定到D6状态时,按下启动键时间以设定时间倒计时工作,此时ZHH无输出GZ输出,治疗指
示灯D4亮时间减到000后,GZ断开报警5秒治疗指示灯闪烁,返回到设定状态。
设定到D5状态时,按下启动键时间以设定时间倒计时工作,此时ZHH,GZ输出,治疗指示灯亮时间减到000后,GZ断开报警5秒治疗指示灯闪烁。
工作中除复位键外其他键不能动作。
报警中可重复启动(设定状态)。
单片机时钟设计MAX7219驱动数码管
单片机时钟设计MAX7219驱动数码管#include#define uchar unsigned char#define uint unsigned intsbit DIN=P0^1; //"显示串行数据输入端"sbit LOAD=P0^2; //"显示数据锁存端"sbit CLK=P0^3; //"显示时钟输入端"#define DecodeMode 0x09 //"译码模式"#define Intensity 0x0a //"亮度"#define ScanLimit 0x0b //"扫描界限"#define ShutDown 0x0c //"掉电模式"#define DisplayTest 0x0f //"显示测试"uchar code seg_data[]={0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70,0x7F,0x7B}; //"0,1,2,3,4,5,6,7,8,9" uchar disp_buf[5];uchar code bit_tab[]={0x01,0x02,0x03,0x04};uchar hour=12,min=0,sec=0,count=0;bit flag;void delay (uint a) //" 毫秒延时函数"{uint i;while( --a != 0){for(i = 0; i < 110; i++);}}void write_max7219_byte(uchar temp){uchar i;for(i=0;i<8;i++){CLK=0;DIN=(bit)(temp&0x80);temp<<=1;CLK=1;}}void write_max7219(uchar address,uint dat){LOAD=0;write_max7219_byte(address);write_max7219_byte(dat);LOAD=1;}void Init_max7219 (void){write_max7219(ScanLimit,0x07); //*"设置扫描界限"*/write_max7219(DecodeMode,0xff); //*"设置译码模式"*/ write_max7219(Intensity,0x04); //*"设置亮度"*/write_max7219(ShutDown,0x01); //*"设置电源工作模式"*/ write_max7219(DisplayTest,0x01);delay(5);write_max7219(DisplayTest,0x00);}void conv(uchar in1,in2){disp_buf[0]=in1/10;disp_buf[1]=in1%10;disp_buf[2]=in2/10;if(flag==0)disp_buf[3]=(in2%10)|0x80;elsedisp_buf[3]=in2%10;}void display( ){write_max7219(bit_tab[0],disp_buf[0]); write_max7219(bit_tab[1],disp_buf[1]); write_max7219(bit_tab[2],disp_buf[2]); write_max7219(bit_tab[3],disp_buf[3]); }void init(){TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count==20){count=0;flag=~flag;sec++;if(sec==60) {sec=0;min++;if(min==60) {min=0;hour++;if(hour==24) {hour=0;min=0;sec=0;}}}}}void main() {init();Init_max7219 ( ); while(1){conv(hour,min); display( );}}。
max7219使用详解介绍
D15~12 以 X 表示,代表可为 0,也可为 1。 Digit0~7 对应到 8 个数码管的地址。 Decode Mode:解码模式寄存器,其地址用 16 迚制表示为 0x09; Intensity:亮度调节寄存器,其地址用 16 迚制表示为 0x0A; Scan Limit:扫描范围寄存器,其地址用 16 迚制表示为 0x0B; Shutdown:省电模式,其地址用 16 迚制表示为 0x0C; Display Test:测试寄存器,其地址用 16 迚制表示为 0x0F;
这个图由三部分组成:
第一部分:是要显示的数据 第二部分:是要发送的数据 D7~D0 第三部分:是数码管的八个段,分别用 DP*,A,B,C,D,E,F,G(DP*表示小数点)
D7 来控制小数点的显示 在弄清这个图之前,我们有必要了解数码管的构造。 下面是数码管的构造图:
数码管有八个段(DP,A,B,C,D,E,F,G)每个段都有一个电路来驱动它, 当你要显示"0",就让 A,B,C,D,E,F 亮,让 G 灭。 当你要显示"1",就让 B,C 亮,让 A,D,E,F,G 灭。 其他的就丌用多说了。 我们再回过头去看 Code B Font 图, 当我们想让数码管显示"0",就向数据位 D3~D0 赋值"0000",那么 MAX7219 就会让 A,B,C,D,E NhomakorabeaF 亮,
MAX7219数码管驱动芯片问题及解决方案
MAX7219数码管驱动芯片问题及解决方案
MAX7219在华强赛格买到的大多是国内抄片的,抗干扰能力很差(原装的我没用过,应该抗干扰能力也好不到哪里去)。
常见的问题是开机上电时,LED数码所有段位全部点亮,芯片处于锁死的状态,无论怎么重新载入数据都无法恢复。
使用绕线变压器作为电源的时候,这种开机锁死的情况较少,概率1%~10%,使用小功率开关电源时,开机锁死的情况较多,30%~60%,使用大功率开关电源时,开机锁死的情况在80%以上分析其中的原因是开机瞬间,电路中出现较多的紊乱信号,而MAX7219的引脚输入阻抗比较大,容易收到这些信号的影响,而且MAX7219内部电路在输入过载的情况下会出现类似运放阻塞的问题。
解决方法是在MAX7219的Load引脚处接一个10K的电阻到地线,这样开机时的紊乱信号就不能在Load引脚处产生足够大的电压。
在我的实际使用中,这种方法能够100%解决绕线变压器电源和小功率开关电源的影响。
但是当整机中有使用100W的大功率开关电源,则在Load引脚处接电阻,即使接1K电阻,也不能保证100%安全。
这时,我采用的方法是单独为Max7219电路做一个软启动电源电路,只需要用一个Mosfet管,一个10K电阻和100uF电容就可以让Max7219在整机上电约100ms后才上电,实际测试,这种方案也是100%成功的。
给Max7219芯片加旁路电容或者在load引脚处加电容,都被证明是无用的。
四位数码管显示时间的原理
四位数码管显示时间的原理
四位数码管是一种常见的显示器件,用于显示数字。
它由四个七段数码管组成,每个数码管有七个段(a-g)用于显示数字0-9。
通过控制这些段的亮灭,可以显示不同的数字。
数码管显示时间的原理如下:
1. 时钟信号:时钟信号是一个周期性的信号,用于控制数码管的刷新频率。
通常,数码管的刷新频率为几十赫兹,即每秒刷新几十次。
2. 数字转换:将当前的时间转换为需要显示的数字。
例如,将小时、分钟和秒分别转换为四个数字。
3. 数字显示:将转换后的数字依次显示在四位数码管上。
通过控制数码管的七段,可以让特定的段亮起,显示对应的数字。
4. 刷新:由于刷新频率较高,每个数码管只能持续亮起很短的时间,然后迅速切换到下一个数码管。
通过快速刷新,人眼会感觉到所有数码管都同时亮起。
这样,通过不断地刷新和更新显示的数字,就可以实现数码管显示时间的功能。
需要注意的是,数码管只能显示数字,不能直接显示字母和其他符号。
如果需要显示字母、符号或者更复杂的信息,可能需要使用其他类型的显示器件。
max7219使用详解
Max7219驱动程序一般的MCU因IO脚驱动能力不够,再加之MCU IO口资源有限,产品开发中通常是通过专门的驱动IC来驱动数码管。
7.1 学会看DatasheetMAX7219就是一款可以同时驱动8个数码管的IC。
下图是其引脚图及典型应用电路:我们的CPU只须三根线就可以控制MAX7219,这三根线是:DIN(第一脚),CS(第12脚),CLK(第13脚)。
DIN是数据输入脚,我们要显示的数据就是通过这根线发送到MAX7219的;CS是片选脚,MCU通过把该脚电平拉低来选中MAX7219,或者说MAX7219通过判断该引脚是否为低电平来使能该芯片。
CLK是时钟引脚,该时钟频率是MCU给到MAX7219的,MCU与7219之间的通信频率就根据该信号做基准。
7.2 MAX7219数据格式我们要让8个数码管显示"12345678",这个过程是怎么实现的呢?首先,要搞清楚MAX7219的数据格式,看图:MAX7219是以16位数据接收和发送的,也就是MCU传给MAX7219的数据必须是16位。
下面分析这16位数据格式:D15~D12为X:表示可以为任意值,因为这四位MAX7219目前还用不到。
D11~D8为ADDRESS:表示MAX7219的地址。
D7~D0为DATA,并且位7为高位(最先发送),位0位低位(最后发送)。
也就是当MCU向MAX7219发送一个16位数据时,其中的D11~D8表示选择MAX7219哪个地址,即数据D7~D0是送到该地址的。
7.3 地址译码MAX7219可以挂8个数码管,MCU是怎么把数据显示到指定的数码管的呢?这就要理解MAX7219的地址译码原理。
下图为MAX7219的地址映射图:D15~12以X表示,代表可为0,也可为1。
Digit0~7对应到8个数码管的地址。
Decode Mode:解码模式寄存器,其地址用16进制表示为0x09;Intensity:亮度调节寄存器,其地址用16进制表示为0x0A;Scan Limit:扫描范围寄存器,其地址用16进制表示为0x0B;Shutdown:省电模式,其地址用16进制表示为0x0C;Display Test:测试寄存器,其地址用16进制表示为0x0F;如果,我们要让第一个数码管显示,那么我们这里送到MAX7219的16位数据中的D11~8应该为0001。
MAX7219驱动数码管应用
MAX7219驱动数码管应用MAX7219的PROTEUS仿真MAX7219是美国MAXIM(美信)公司生产的串行输入/输出共阴极显示驱动器。
它采用了3线串行接口,传送速率达10M数据,能驱动8位七段数字型LED或条形显示器或64只独立的LED。
MAX7219内置BCD码译码器、多路扫描电路、段和数字驱动器和存储每一位的8*8静态RAM。
能方便的用模拟或数字方法控制段电流的大小,改变显示器的数量;能进入低功耗的关断模式(仅消耗150uA电流,数据保留);能方便地进行级联。
可广泛用于条形图显示、七段显示、工业控制、仪器仪表面板等领域。
而且其最重要的一点是,每个显示位都能个别寻址和刷新,而不需要重写其他的显示位,这使得软件编程十分简单且灵活。
MAX719后缀表示其封装方式和工作温度,如表所示:后缀封装工作温度 CNG 窄24脚 0----70? CWG SO24脚 0----70? ENG 窄24脚 -40---85? EWG SO24脚 -40---85? 一. MAX7219的结构和功能1(引脚说明MAX7219的引脚排列如图所示,各引脚功能叙述如下:(1)脚:DIN,串行数据输入。
在CLK的上升沿到来时,数据被移入到内部的16位移位寄存器中。
(2)、(3)、(5)~(8)、(10)、(11)脚:DIG0—DIG7,输入。
8位数字位位选线,从共阴极显示器吸收电流。
(4)、(9)脚:GND,地。
两个引脚必须连接在一起。
(12)脚:LOAD,数据装载输入端。
在LOAD上升沿,移位寄存器接受的数据被锁存。
(13)脚:CLK,时钟输入端,最高时钟频率10MHz。
在CLK的上升沿,数据被移入到内部的16位移位寄存器中。
在CLK的下降沿,数据从DOUT脚输出。
(14)~(15)、(20)~(23)脚:输出。
七段驱动器和小数点驱动器。
它供给显示器电流。
(18)脚:ISET,电流调节端。
通过一个电阻和VCC相连,来调节最大段电流。
max7219秒表程序(一键控制三个状态)
#include <reg51.h>#include "type.h"#include "max7219.h"/********************************************************************控制按键定义***********************************************************************/ sbit Key = P3^0;/********************************************************************变量定义***********************************************************************/uint16 Ms = 0;uint16 Sec = 0;uint8 k;uint8 Count = 0;/************************************************************************函数声明*************************************************************************/void Start_Stop();void Init_Timer0();void Delay();void Display();void Key_In();void Reset();/************************************************************************main()主函数*************************************************************************/void main(){Init_Max7219();Init_Timer0();while(1){Key_In();switch(k){case 0 : Reset();break;case 1 : Display();break;case 2 : TR0 = 0;break;}}}/************************************************************************定时器0中断函数*************************************************************************/void Interrupt_Timer0() interrupt 1{TH0 = 0xee;TL0 = 0x00;Count++;if(Count >= 2){Count = 0;Ms++;if(Ms >= 99) //100次为1s{Ms = 0; //秒数最大显示为99,之后从头开始计时Sec++;}if(Sec >= 99)Sec = 0; //秒加到99,重新计数}}/************************************************************************Reset()清零函数*************************************************************************/void Reset(){Init_Max7219();Init_Timer0();Ms = 0;Sec = 0;}/************************************************************************Display()函数*************************************************************************/void Display(){Write_Max7219(DIG_8,Ms%10);Write_Max7219(DIG_7,Ms/10);Write_Max7219(DIG_6,(Sec%10 | 0x80));Write_Max7219(DIG_5,Sec/10);}/***********************************************************************延时函数(约7毫秒)************************************************************************/void Delay(uint16 x){char i;while(x--){for(i=0;i<125;i++);}}/************************************************************************定时器0初始化*************************************************************************/void Init_Timer0(){TMOD |= 0x11; //初始化两个定时器TH0 = 0x33; //只用到定时器0,赋初值,中断一次5msTL0 = 0x00;TR0 = 1; //启用定时器0ET0 = 1; //允许定时器中断EA = 1; //将总中断打开}/************************************************************************按键控制*************************************************************************/ void Key_In(){if(!Key){Delay(19);if(!Key){k++;if(k>2){k = 0;}while(!Key);}}}max7219.h#ifndef _MAX7219_H_#define _MAX7219_H_/*********************************************************引脚位定义**********************************************************/sbit LOAD=P1^2; //MAX7219 Load-Data Input: rising edge pin 12 sbit DIN=P1^1; //MAX7219 Serial-Data Input: rising edge pin 1 sbit CLK=P1^0; //MAX7219/****************************************************MAX7219 宏定义*****************************************************/#define REG_NO_OP 0x00 // 定义空操作#define DIG_1 0x01 // 定义数码管1#define DIG_2 0x02 // 定义数码管2#define DIG_3 0x03 // 定义数码管3#define DIG_4 0x04 // 定义数码管4#define DIG_5 0x05 // 定义数码管5#define DIG_6 0x06 // 定义数码管6#define DIG_7 0x07 // 定义数码管7#define DIG_8 0x08 // 定义数码管8#define DECODE_MODE 0x09#define INTENSITY 0x0A#define SCAN_LIMIT 0x0B#define SHUT_DOWN 0x0C#define DISPLAY_TEST 0x0F/***********************************************************MAX7210函数声明************************************************************/void Write_Max7219_byte(uint8 temp);//write max7219 a bytevoid Write_Max7219(uint8 address,uint8 dat);//write max7219 command and data void Init_Max7219(void);//Initize max7219/************************************************************MAX7219地址、数据写入函数子程序*************************************************************/void Write_Max7219_byte(uint8 temp){uint8 i;for (i=0;i<8;i++){CLK = 0;DIN = (bit)(temp&0x80);temp <<= 1;CLK = 1;}}/*************************************************************MAX7219地址、数据写入**************************************************************/void Write_Max7219(uint8 address,uint8 dat){LOAD = 0;Write_Max7219_byte(address);Write_Max7219_byte(dat);LOAD = 1;}/**************************************************************MAX7219初始化***************************************************************/void Init_Max7219(void){Write_Max7219(SHUT_DOWN, 0x01);Write_Max7219(DISPLAY_TEST, 0x00);Write_Max7219(DECODE_MODE, 0xff);Write_Max7219(SCAN_LIMIT, 0x07); //SCAN LIMIT 0~7 0xX0~0xX7 Write_Max7219(INTENSITY, 0x04);Write_Max7219(DIG_7,0x00);Write_Max7219(DIG_5,0x00);Write_Max7219(DIG_6,0x80);Write_Max7219(DIG_8,0x00);}#endiftype.h#ifndef _TYPE_H_#define _TYPE_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;typedef char int8;typedef int int16;typedef long int32;#endif。
max7219使用详解
Max7219驱动程序一般的MCU因IO脚驱动能力不够,再加之MCU IO口资源有限,产品开发中通常是通过专门的驱动IC来驱动数码管。
7.1 学会看DatasheetMAX7219就是一款可以同时驱动8个数码管的IC。
下图是其引脚图及典型应用电路:我们的CPU只须三根线就可以控制MAX7219,这三根线是:DIN(第一脚),CS(第12脚),CLK(第13脚)。
DIN是数据输入脚,我们要显示的数据就是通过这根线发送到MAX7219的;CS是片选脚,MCU通过把该脚电平拉低来选中MAX7219,或者说MAX7219通过判断该引脚是否为低电平来使能该芯片。
CLK是时钟引脚,该时钟频率是MCU给到MAX7219的,MCU与7219之间的通信频率就根据该信号做基准。
7.2 MAX7219数据格式我们要让8个数码管显示"12345678",这个过程是怎么实现的呢?首先,要搞清楚MAX7219的数据格式,看图:MAX7219是以16位数据接收和发送的,也就是MCU传给MAX7219的数据必须是16位。
下面分析这16位数据格式:D15~D12为X:表示可以为任意值,因为这四位MAX7219目前还用不到。
D11~D8为ADDRESS:表示MAX7219的地址。
D7~D0为DATA,并且位7为高位(最先发送),位0位低位(最后发送)。
也就是当MCU向MAX7219发送一个16位数据时,其中的D11~D8表示选择MAX7219哪个地址,即数据D7~D0是送到该地址的。
7.3 地址译码MAX7219可以挂8个数码管,MCU是怎么把数据显示到指定的数码管的呢?这就要理解MAX7219的地址译码原理。
下图为MAX7219的地址映射图:D15~12以X表示,代表可为0,也可为1。
Digit0~7对应到8个数码管的地址。
Decode Mode:解码模式寄存器,其地址用16进制表示为0x09;Intensity:亮度调节寄存器,其地址用16进制表示为0x0A;Scan Limit:扫描范围寄存器,其地址用16进制表示为0x0B;Shutdown:省电模式,其地址用16进制表示为0x0C;Display Test:测试寄存器,其地址用16进制表示为0x0F;如果,我们要让第一个数码管显示,那么我们这里送到MAX7219的16位数据中的D11~8应该为0001。
4位共阳数码管遥控时钟
uchar ds,dss,dsg;//继电器小时 小时十位和个位
uchar df,dfs,dfg;//继电器分钟 分钟十位和个位
//设置标志部分
uchar mode=0;//菜单
uchar yiwei=1;
dfs=df/10;//分十位
dfg=df%10;//分个位
dss=ds/10;//时十位
dsg=ds%10;//时个位
P0=table0[dfs];//分十位
P2=table2[3];
delay(10);
naofen=30;
ds=00;
df=30;
while(1)
{ if(!p30) //判断串口是不是有数据
{
iap=0x60; //执行自动下载的命令
}
jishi();//自动走时
TL0=(65535-50000)%256;
int_num++;
}
//定时器初始化函数
void inter_init()
{
EA=1; ///开总中断
ET0=1; //打开定时器T0
TMOD=0x01; //工作方式1
void de(z)//自己用的延迟
{
g n,m;
for(n=z;n>0;n--)
for(m=110;m>0;m--);
}
//初始化T0函数
void time0(void) interrupt 1 // 定时器T0服务子程序
{
TH0=(65535-50000)/256;
MAX7219共阴极LED驱动器程序
MAX7219共阴极 LED数码管显示驱动(一)、 MAX7219MAX7219是一种串入、并出的共阴极LED数码管显示驱动器,每片可驱动8 位 LED数码管显示,与单片机的接口只要 3 根线,内带BCD译码器,及显示测试、移位、锁存器等,输出电流达40mA,外头只要一只亮度调整电阻。
MAX7219引脚图1、引脚功能说明DIN:串行数据输入端,CLK的上涨沿时数据被载入内部16 位移位存放器中CLK:串行时钟输入端,最高工作频次可达10MHzLOAD:片选端,低电平接收DIN 端的数据,高电平常数据被所存DIG0~7: LED的位控制端A~DP:LED的端控制端DOUT:串行数据输出端,用于芯片的级联ISET:硬件亮度调整端,在该引脚与VCC之间跨接一个电阻,LED的亮度即可经过该电阻来调理,流过LED的段驱动均匀电流为流过此电阻电流的100 倍, 此电阻值范围为:10~80K 之间。
2、内部存放器说明A、译码方式选择存放器地点:09H赋值: FFH表示使用MAX7219内部的BCD译码器00H表示不使用MAX7219内部的 BCD译码器B、亮度调理存放器地点:0AH赋值:00H~0FH 可改变MAX7219所驱动的LED的亮度,其变化范围在1/32~31/32之间C、扫描位数设定存放器地点:0BH赋值: 00H所有位不显示01H~07H挨次对应于1~8 位及前方位所有显示(即需显示的位应为“1”)D、待机模式开关存放器地点:0CH赋值: 00H LED全灭01H LED正常显示E、显示器测试存放器地点: 0FH赋值: 00H LED为正常显示状态01H LED测试状态,即LED全亮F、8 位LED显示数据存放器地点: 01H~08H对这些存放器赋值(即需显示的内容),就会在对应的1~8 位LED数码管上显示出来3、使用注意事项因为电源中杂波或邻近的电磁等扰乱信号,使MAX7219在上电后不显示或乱显示;为了除去这类现象应在 MAX7219的 VCC端与地之间接一只104pf 的瓷片电容,在LOAD端于地之间接一只10K 的电阻。
max7219秒表程序(一键控制三个状态)
#include <reg51.h>#include "type.h"#include "max7219.h"/********************************************************************控制按键定义***********************************************************************/ sbit Key = P3^0;/********************************************************************变量定义***********************************************************************/uint16 Ms = 0;uint16 Sec = 0;uint8 k;uint8 Count = 0;/************************************************************************函数声明*************************************************************************/void Start_Stop();void Init_Timer0();void Delay();void Display();void Key_In();void Reset();/************************************************************************main()主函数*************************************************************************/void main(){Init_Max7219();Init_Timer0();while(1){Key_In();switch(k){case 0 : Reset();break;case 1 : Display();break;case 2 : TR0 = 0;break;}}}/************************************************************************定时器0中断函数*************************************************************************/void Interrupt_Timer0() interrupt 1{TH0 = 0xee;TL0 = 0x00;Count++;if(Count >= 2){Count = 0;Ms++;if(Ms >= 99) //100次为1s{Ms = 0; //秒数最大显示为99,之后从头开始计时Sec++;}if(Sec >= 99)Sec = 0; //秒加到99,重新计数}}/************************************************************************Reset()清零函数*************************************************************************/void Reset(){Init_Max7219();Init_Timer0();Ms = 0;Sec = 0;}/************************************************************************Display()函数*************************************************************************/void Display(){Write_Max7219(DIG_8,Ms%10);Write_Max7219(DIG_7,Ms/10);Write_Max7219(DIG_6,(Sec%10 | 0x80));Write_Max7219(DIG_5,Sec/10);}/***********************************************************************延时函数(约7毫秒)************************************************************************/void Delay(uint16 x){char i;while(x--){for(i=0;i<125;i++);}}/************************************************************************定时器0初始化*************************************************************************/void Init_Timer0(){TMOD |= 0x11; //初始化两个定时器TH0 = 0x33; //只用到定时器0,赋初值,中断一次5msTL0 = 0x00;TR0 = 1; //启用定时器0ET0 = 1; //允许定时器中断EA = 1; //将总中断打开}/************************************************************************按键控制*************************************************************************/ void Key_In(){if(!Key){Delay(19);if(!Key){k++;if(k>2){k = 0;}while(!Key);}}}max7219.h#ifndef _MAX7219_H_#define _MAX7219_H_/*********************************************************引脚位定义**********************************************************/sbit LOAD=P1^2; //MAX7219 Load-Data Input: rising edge pin 12 sbit DIN=P1^1; //MAX7219 Serial-Data Input: rising edge pin 1 sbit CLK=P1^0; //MAX7219/****************************************************MAX7219 宏定义*****************************************************/#define REG_NO_OP 0x00 // 定义空操作#define DIG_1 0x01 // 定义数码管1#define DIG_2 0x02 // 定义数码管2#define DIG_3 0x03 // 定义数码管3#define DIG_4 0x04 // 定义数码管4#define DIG_5 0x05 // 定义数码管5#define DIG_6 0x06 // 定义数码管6#define DIG_7 0x07 // 定义数码管7#define DIG_8 0x08 // 定义数码管8#define DECODE_MODE 0x09#define INTENSITY 0x0A#define SCAN_LIMIT 0x0B#define SHUT_DOWN 0x0C#define DISPLAY_TEST 0x0F/***********************************************************MAX7210函数声明************************************************************/void Write_Max7219_byte(uint8 temp);//write max7219 a bytevoid Write_Max7219(uint8 address,uint8 dat);//write max7219 command and data void Init_Max7219(void);//Initize max7219/************************************************************MAX7219地址、数据写入函数子程序*************************************************************/void Write_Max7219_byte(uint8 temp){uint8 i;for (i=0;i<8;i++){CLK = 0;DIN = (bit)(temp&0x80);temp <<= 1;CLK = 1;}}/*************************************************************MAX7219地址、数据写入**************************************************************/void Write_Max7219(uint8 address,uint8 dat){LOAD = 0;Write_Max7219_byte(address);Write_Max7219_byte(dat);LOAD = 1;}/**************************************************************MAX7219初始化***************************************************************/void Init_Max7219(void){Write_Max7219(SHUT_DOWN, 0x01);Write_Max7219(DISPLAY_TEST, 0x00);Write_Max7219(DECODE_MODE, 0xff);Write_Max7219(SCAN_LIMIT, 0x07); //SCAN LIMIT 0~7 0xX0~0xX7 Write_Max7219(INTENSITY, 0x04);Write_Max7219(DIG_7,0x00);Write_Max7219(DIG_5,0x00);Write_Max7219(DIG_6,0x80);Write_Max7219(DIG_8,0x00);}#endiftype.h#ifndef _TYPE_H_#define _TYPE_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;typedef char int8;typedef int int16;typedef long int32;#endif。
max7221动态显示课程设计实验报告
单片机课程设计实验报告课程设计名称:MAX7221动态显示课程设计姓名:设计目标:1、利用Proteus 软件设计一个以AT89C52单片机为主控元件由MAX7221驱动的8位7段数码管动态显示电路。
2、利用protel99绘制原理图。
3、利用microfost Visio绘制硬件总设计框图和程序流程图。
4、根据流程图利用Keil uVision对单片机软件进行编译,与Proteus联调后使系统控制能够完成显示:“01234567”,保持。
图 1 总设计框图二、硬件电路设计本设计中,单片机采用Atmel公司的AT89C52;MAX7221串行输入/输出共阴极显示驱动器;LED数码显示器采用8位7段共阴极数码管显示器。
(硬件总原理图见附件1)P3.0口用来串行数据的接收;P3.1口用来串行数据的发送;P3.2口为外部中断0,此处电平触发(IT0=1)每次执行完中断里面的程序(只要不关闭中断)就又跳进中断里去了,不断的循环执行。
XTAL1和XTAL2外接12MHz的晶振和2个22pF的电容构成时钟电路。
EA/VPP,当EA=1时允许使用片内ROM,当EA=0时只使用片外ROM。
EA/VPP端和RESET 复位端连接一个10μF的有极性电容,在EA端再接+5V,在RESET端接一个8.2k的电阻并接地构成复位电路。
AT89C52与时钟电路和复位电路构成单片机最小系统。
MAX7221采用串行接口方式,可以很方便地和单片机相连,仅占用单片机的P3.0口,P3.1口和P3.2口。
DIN脚为串行数据输入端,数据存入内部16位移位寄存器,它与P3.0口相连。
CS 脚是片选输入端,当 CS=0 时,串行数据存入移位寄存器,当 CS 为上升沿时锁存最后 16 位数据,与P3.1口相连。
CLK 脚是串行时钟输入端,最高频率 10MHz,在时钟上升沿数据移位存入内部移位寄存器,当时钟下降沿时,数据由 DOUT输出,CLK 输入仅当CS 为0 时有效,与P3.2口相连。
arduino四位数码管的点 -回复
arduino四位数码管的点-回复乐鱼的请求非常清晰,下面我将为大家介绍一种常见的电子元件——四位数码管的点亮原理和使用方法。
一、介绍四位数码管的基本概念和结构(200-300字)四位数码管是一种常见的电子显示器件,用于显示0-9的数字,有时也可以显示一些特殊字符和字母。
它由四个七段数码管组成,每个七段数码管又由七个发光二极管构成。
通过控制每个发光二极管的亮灭状态,就可以显示不同的数字和字符。
数码管的外形通常为长方形,每个七段数码管由一个扁平的透明玻璃管封装,内部有七个发光二极管和一个控制芯片。
二、详细介绍四位数码管的亮灭控制原理(400-500字)四位数码管的亮灭受到两个方面的控制:位选控制和段选控制。
位选控制是通过控制四位数码管的四个位选引脚(通常标记为A、B、C、D)来实现的。
段选控制是通过控制七段数码管的七个段选引脚(标记为a、b、c、d、e、f、g)来实现的。
首先,在控制位选时,我们需要将要显示的数字分为四个位。
例如要显示4321,我们需要分别控制第一位、第二位、第三位和第四位。
当要显示第一位时,将A引脚置高电平,将B、C、D引脚置低电平;当要显示第二位、第三位和第四位时,同样的原理,将对应的引脚置高电平。
通过依次控制这四个位选引脚的状态,就可以实现显示不同位的数字。
接下来,在控制段选时,我们需要确定每个位需要亮灭的七段数码管。
例如,位0(第一位)需要显示4,位1(第二位)需要显示3,位2(第三位)需要显示2,位3(第四位)需要显示1。
然后,通过控制七个段选引脚的状态,来控制每个七段数码管的亮灭。
对于数字4而言,我们需要点亮a、b、d、e四个段。
通过控制对应的引脚,即可实现。
同样地,我们可以控制每个位需要亮灭的七段数码管,从而显示不同位的数字。
三、通过Arduino控制四位数码管的具体操作方法(800-1000字)为了方便控制四位数码管的位选和段选,我们可以使用Arduino开发板,通过编写相应的程序来实现。
数码管显示时间及点阵显示字符[技巧]
//数码管显示时间及点阵显示字符#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int//定义Max7219端口#define DUAN P0 //P0口控制段#define WEI P2 //P2口控制位sbit k_hour=P1^0; // 更改小时按键sbit k_min=P1^1; // 更改分钟按键sbit k_sec=P1^2; // 更改秒按键//定义数码管端口sbit Max7219_pinCLK = P1^2;sbit Max7219_pinCS = P1^1;sbit Max7219_pinDIN = P1^0;//Max7219位定义unsigned char key; //P3按键扫描(执行模块控制)code uchar seg7code[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0XBF }; //显示段码数码管字跟uchar wei[8]={0XFE,0XFD,0XFB,0XF7,0XEf,0XDf,0XBf,0X7f}; //位的控制端uchar numb[8]; //定义字符串uint sec=0,min,hour;//数码管初始定义uchar code disp2[7][8]={{0x00,0x3E,0x2A,0xFF,0xAA,0xBE,0xC0,0x00}, //电{0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00}, //一{0x00,0x00,0x1E,0x20,0x40,0x20,0x1E,0x00}, //V{0x00,0x00,0x4E,0x4A,0x4A,0x7A,0x00,0x00}, //5{0x00,0x00,0x42,0x7E,0x42,0x00,0x00,0x00}, //I{0x00,0x0C,0x1E,0x3C,0x3C,0x1E,0x0C,0x00}, //love{0x00,0x00,0x3E,0x40,0x40,0x3E,0x00,0x00}, //U};char flag;//定义点阵显示字符void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++)for(j=0;j<300;j++);}//公用的延时程序//功能:向MAX7219(U3)写入字节//入口参数:DATA//出口参数:无void Write_Max7219_byte(uchar DATA){uchar i;Max7219_pinCS=0;for(i=8;i>=1;i--){Max7219_pinCLK=0;Max7219_pinDIN=DATA&0x80;DATA=DA TA<<1;if(flag)Delay_xms(500);Max7219_pinCLK=1;}}//功能:向MAX7219写入数据//入口参数:address、dat//出口参数:无//说明:void Write_Max7219(uchar address,uchar dat){Max7219_pinCS=0;Write_Max7219_byte(address); //写入地址,即数码管编号Write_Max7219_byte(dat); //写入数据,即数码管显示数字Max7219_pinCS=1;}void Init_MAX7219(void){Write_Max7219(0x09, 0x00); //译码方式:BCD码Write_Max7219(0x0a, 0x03); //亮度Write_Max7219(0x0b, 0x07); //扫描界限;8个数码管显示Write_Max7219(0x0c, 0x01); //掉电模式:0,普通模式:1Write_Max7219(0x0f, 0x00); //显示测试:1;测试结束,正常显示:0 }void t_to_dis(){numb[0]=hour/10; //显示小时十位numb[1]=hour%10; //显示小时个位numb[2]=10; //显示横杠numb[3]=min/10; //显示分十位numb[4]=min%10; //显示分个位numb[5]=10; //显示横杠numb[6]=sec/10; //显示秒十位numb[7]=sec%10; //显示秒个位}//数码管求值函数void display()//显示函数{//数码管数据转换P2=0XFF;P0=seg7code[numb[0]];P2=wei[0];Delay_xms(80);P2=0XFF;P0=seg7code[numb[1]];P2=wei[1];Delay_xms(80);P2=0XFF;P0=seg7code[numb[2]];P2=wei[2];Delay_xms(80);P2=0XFF;P0=seg7code[numb[3]];P2=wei[3];Delay_xms(80);P2=0XFF;P0=seg7code[numb[4]];P2=wei[4];Delay_xms(80);P2=0XFF;P0=seg7code[numb[5]];P2=wei[5];Delay_xms(80);P2=0XFF;P0=seg7code[numb[6]];P2=wei[6];Delay_xms(80);P2=0XFF;P0=seg7code[numb[7]];P2=wei[7];Delay_xms(80);P2=0XFF;}void Display1(){//0P2=0X00;P0=0xc0;Delay_xms(200);//1P2=0X00;P0=0xf9;Delay_xms(200);//2P2=0X00;P0=0xa4;Delay_xms(200);//3P2=0X00;P0=0xb0;Delay_xms(200);//4P2=0X00;P0=0x99;Delay_xms(200);//5P2=0X00;P0=0x92;Delay_xms(200);//6P2=0X00;P0=0x82;Delay_xms(200);//7P2=0X00;P0=0xf8;Delay_xms(200);//8P2=0X00;P0=0x80;Delay_xms(200);//9P2=0X00;P0=0x90;Delay_xms(200); }//4位显示0~9void Display2(){P2=0XFE;P0=0x00;Delay_xms(200);P2=0XFD;P0=0x00;Delay_xms(200);P2=0XFB;P0=0x00;Delay_xms(200);P2=0XF7;P0=0x00;Delay_xms(200);P2=0XEF;P0=0x00;Delay_xms(200);P2=0XDF;P0=0x00;Delay_xms(200);P2=0XBF;P0=0x00;Delay_xms(200);P2=0X7F;P0=0x00;Delay_xms(200);}//数码管移位显示8void SetTime(){if(k_hour==0){hour++;while(!k_hour);if(hour>=24) hour=0;}if(k_min==0){min++;while(!k_min);if(min>=60) min=0;}if(k_sec==0){sec++;while(!k_sec);if(sec>=60) sec=0;}}//数码管按键函数void timer1(void)interrupt 3 //每一秒增加一{uchar i;TH1=0X3c;//定时初值TL1=0Xaf;//定时初值i++;{i=0;sec++;//秒加1if(sec>=60){sec=0; //秒清零min++; //60秒后分加1if(min>=60){min=0; //分清零hour++; //60分后时加1if(hour>=24)hour=0; //时清零}}}}//数码管中断函数void InitInterrupt(){TMOD=0X10;//定义定时器工作方式TH1=0X3c;TL1=0Xaf;ET1=1;TR1=1;//开定时器EA=1;//开中断}//数码管中断初始化void main1(){uchar m,n;Delay_xms(500);P2=0xaa;Delay_xms(500);P2=0x55;Delay_xms(500);flag=0;Init_MAX7219();flag=0;{for(m=0;m<7;m++){for(n=0;n<9;n++)Write_Max7219(n,disp2[m][n-1]);Delay_xms(500);}}}//点阵Main函数void main2(){InitInterrupt(); //中断初始化Display1();Display2();while(1){SetTime();//按键函数t_to_dis();//确定秒分时值display(); //显示秒分时值}}//数码管Main函数void ext_int0(void) interrupt 0 using 1{if(P3!=0xff){Delay_xms(10);key=P3;}while(P3!=0xff);switch(key){case 0xfe:main1(); break;case 0xfd:main2(); break;default:break;}}//判断有按键按下,所控制的程序void main(){IT0=1; //设定为边沿触发方式IP=0x01; //置外部中断0为高优先级中断P3=0xff; //置P3口为输入态EA=1; //开CPU中断EX0=1; //开外部中断0while(1); //等待外部中断。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Arduino驱动MAX7219四位数码管显示时间
默认使用Pin 2为MOSI(数据发送)引脚,Pin 3为CS(片选)引脚,Pin 4为SCLK(时钟)引脚,如有需要请修改代码前三行的define。
#define MO 2
#define CS 3
#define CLK 4
static int time_h = 21, time_m =25, time_s = 30; //此刻时间:时,分,秒
int alarm_clock_h = 8, alarm_clock_m = 00; //闹钟时间
unsigned long time = 0;
unsigned char buffer_led[5] = { 0x00,};//缓存
void SPI_init(void) //初始化SPI引脚
{
pinMode(CLK, OUTPUT);
pinMode(MO, OUTPUT);
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
digitalWrite(CLK, LOW);
digitalWrite(MO, HIGH);
}
void SPI_send(unsigned char reg, unsigned char data) //spi单向16位数据发送{
int x;
/*
Serial.print("reg = ");
Serial.print(reg, HEX);
Serial.print(" data = ");
Serial.println(data, HEX);
*/
digitalWrite(CS, LOW);
for (x = 0; x < 8; x++)
{
digitalWrite(MO, 0x80 & (reg << x)); //高位在前
digitalWrite(CLK, HIGH);
digitalWrite(CLK, LOW);
}
for (x = 0; x < 8; x++)
{
digitalWrite(MO, 0x80 & (data << x)); //高位在前 digitalWrite(CLK, HIGH);
digitalWrite(CLK, LOW);
}
digitalWrite(CS, HIGH);
}
void lcd_init(void)//初始化Max7219配置
{
SPI_send(0x0b, 0x07); //scan-limit
SPI_send(0x09, 0xff); //decode mode all
SPI_send(0x0c, 0x01); //shutdown off
SPI_send(0x0f, 0x00); //off display test
SPI_send(0x0a, 0x04); //intensity
delay(100);
}
void clear(void)//清除显示
{
for (int i = 1; i <= 8; i++)
{
SPI_send(i, 0x0F);
}
}
void led_display(void)//显示时间
{
char cache = 0x00;
if ((time_h / 10) == 0)buffer_led[0] = 0x00;
else buffer_led[0] = time_h / 10;
buffer_led[1] = time_h % 10 | 0x01;
buffer_led[2] = time_m / 10;
buffer_led[3] = time_m % 10;
SPI_send(8, buffer_led[0]);
SPI_send(7, buffer_led[1]);
SPI_send(6, 0x0a);
SPI_send(5, buffer_led[2]);
SPI_send(4, buffer_led[3]);
SPI_send(3, 0x0a);
SPI_send(2, time_s / 10);
SPI_send(1, time_s % 10);
}
void get_time()//获取时间并更新显示
{
static char ss = 1;
static unsigned long time_cc = 0;
if ((millis() - time_cc) > 1000 | millis() < 150)//秒
{
if (millis() <= 200) //若系统计时器溢出时时间,time_cc重计
{
time_cc = millis();
time_s ++;
delay(150);
}
else if (millis() > 200)//秒
{
time_s += (millis() - time_cc) / 1000;
// time_cc = millis()-990; //时间快进
time_cc = millis();
buffer_led[4] = (0x01 & ss) << 5;
ss = ~ss;
}
if (time_s > 59) //分
{
if (time_s - 60 > 1)//如果有延时间隔导致秒钟大于60秒,进行分钟缺失补偿 {
time_m += time_s / 60;
if (time_s % 60 == 0)time_m--;
time_s = time_s - (time_s / 60) * 60;
}
else time_s = 0;
time_m++;
buffer_led[4] = 0x80;
if (time_m > 59)//时
{
time_h++;
time_m = (time_m - 60);
buffer_led[4] = 0xf0;
}
if (time_h > 23)
{
time_h = 0;
time_s += 5; //时间误差补偿
}
}
// Serial.print("millis="); // Serial.print(time_cc);
// Serial.print(" time="); // Serial.print(time_h);
// Serial.print(":");
// Serial.print(time_m);
// Serial.print(":");
// Serial.println(time_s); led_display();//刷新数码管显示
}
}
void setup()
{
Serial.begin(9600);
SPI_init();
lcd_init();
clear();
}
void loop()
{
get_time();
}。