74HC595实现四位数码管显示
本帖最后由 、六弦 于 2013-6-3 18:00 编辑今天做了个数码管的显示,利用串行转并行的74hc595来驱动四个数码管,用arduino的定时器做了一个时钟,具体实现的功能是:串口与数码管同步时钟,利用串口发送时间数据可以调时。没有数码管也可以下载代码,从串口看输出时钟哦,也可以发送调时指令。(手机像素不好,大家将就着看看吧)。
//*************************************************************
// 实现功能:数码管显示时钟,通过串口设置时间(串口同步时钟)。
// 1.串口波特率设置为:9600
// 2.设置时间格式: Txxxxxx.例:12:34:56 发送:T123456
//*************************************************************
#include <TimerOne.h>
#define uchar unsigned char
#define SI_HdigitalWrite(4, HIGH)
#define SI_LdigitalWrite(4, LOW);
#define RCK_H digitalWrite(5, HIGH);
#define RCK_L digitalWrite(5, LOW);
#define SCK_H digitalWrite(6, HIGH);
#define SCK_L digitalWrite(6, LOW);
#define CS_HdigitalWrite(7, HIGH);
#define CS_LdigitalWrite(7, LOW);
uchar second,minute,hour;
String Rx = "";
uchar count[] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
void port_init(void)
{
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
}
//num =0 / 1 / 2 / 3
//mode = HIGH -> open / LOW -> close
void SMG_select(uchar num,uchar mode)
{
if(num<4)
{
switch(num)
{
case 0: num = 8; break;
case 1: num = 9; break;
case 2: num = 10;break;
case 3: num = 11;break;
}
digitalWrite(num,mode);
}
}
void write_data(uchar data)
{
uchar i;
CS_H;
for(i=0;i<8;i++)
{
if((data&0x80)==0x80)SI_H;
else SI_L;
SCK_H;
delayMicroseconds(20);
SCK_L;
data=data<<1;
}
RCK_L;
delay(1);
RCK_H;
CS_L;
}
void set_time()
{
while(Serial.available() >0)
{
Rx += char( Serial.read() );
delay(2);
}
if (Rx.length() >0)
{
if(Rx==84)
{
hour = (Rx-0x30)*10 + (Rx-0x30);
minute = (Rx-0x30)*10 + (Rx-0x30);
second = (Rx-0x30)*10 + (Rx-0x30);
}
Serial.println(" -----------------------");
Serial.print("|Set Time: ");
Serial.print(hour,DEC);
Serial.print(":");
Serial.print(minute,DEC);
Serial.print(":");
Serial.print(second,DEC);
Serial.println(" |");
Serial.println(" -----------------------");
Rx = "";
}
}
void setup()
{
Serial.begin(9600);
port_init();
// pinMode(13, OUTPUT);
Timer1.initialize(1000000);
Timer1.attachInterrupt( timerIsr );
}
void timerIsr()
{
//digitalWrite( 13, digitalRead( 13 ) ^ 1 );
second++;
if(second > 59)
{
second = 0;
minute ++;
if(minute > 59)
{
minute = 0;
hour ++;
if(hour > 23) hour = 0;
}
}
Serial.print("Time :");
Serial.print(hour,DEC);
Serial.print(":");
Serial.print(minute,DEC);
Serial.print(":");
Serial.println(second,DEC);
}
void loop()
{
set_time();
SMG_select(0,HIGH);
write_data(count);
delayMicroseconds(400);
SMG_select(0,LOW);
SMG_select(1,HIGH);
if(second%2) write_data(count + 0x80);
else write_data(count);
delayMicroseconds(400);
SMG_select(1,LOW);
SMG_select(2,HIGH);
write_data(count);
delayMicroseconds(400);
SMG_select(2,LOW);
SMG_select(3,HIGH);
write_data(count);
delayMicroseconds(400);
SMG_select(3,LOW);
} 用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错 应该是ULN2003分时驱动,这样没问题的 FoieDEEEE_仲敬 发表于 2013-6-3 20:15 static/image/common/back.gif
用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错
对,感觉不是很实用,如果增加其它的程序就会闪的很厉害.就算最好情况下显示效果都不是很好. 这个不太明白,还要在研究下。 FoieDEEEE_仲敬 发表于 2013-6-3 20:15 static/image/common/back.gif
用595驱动4位太勉强了,仔细看第四位数码管和第三位的数字都要混在一起了!595驱动2位倒是不错
第四位数码管和第三位的数字混在一起了,是因为每移位8bit就锁存一次,因此段选信号会在瞬间作为段显信号,所以明明不该亮起来的段会看起来微微亮,解决方法是段选和段显信号都发送完成之后再锁存。 为什么不用连个595来驱动4位的呢?
页:
[1]