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. 刷新:由于刷新频率较高,每个数码管只能持续亮起很短的时间,然后迅速切换到下一个数码管。
通过快速刷新,人眼会感觉到所有数码管都同时亮起。
这样,通过不断地刷新和更新显示的数字,就可以实现数码管显示时间的功能。
需要注意的是,数码管只能显示数字,不能直接显示字母和其他符号。
如果需要显示字母、符号或者更复杂的信息,可能需要使用其他类型的显示器件。
- 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();
}。