8X8点阵的,本
经过发扬坚持不懈、不怕苦、不怕累的老一辈革命精神,8X24LED点阵终于成功点亮。并达到预期目标,将内容从右到左滚动显示。
电路结构:UDN2981A用于行扫描驱动,A6276SAX2用于列数据串行输出,两个可以驱动四个8X8点阵,我只用了其中三组,下次再增加一个,单片机用M8。
程序如下:
#include <avr/io.h>
#include <avr/interrupt.h>
#define unchar unsigned char
#define unint unsigned int
#define OUT PORTD
#define out_disable PORTB |= _BV(7)
#define out_enable PORTB &= ~_BV(7)
#define clk_int PORTB &= ~_BV(1)
unchar cache[5];
unchar column[][8]={
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
{0xF0,0x88,0x88,0xF0,0x88,0x88,0x88,0x0},// R
{0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x0},//A
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x0},// B
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x0},//B
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x0},//I
{0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x0},//T
{0x0,0x0,0x0,0x60,0x60,0x20,0x40,0x0},//
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x0},//I
{0,0,0,0,0,0},//
{0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x0},//L
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0},//O
{0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x0},//V
{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x0},//E
{0,0,0,0,0,0},//
{0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00},//Y
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0},//O
{0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x0},//U
{0x30,0x30,0x30,0x30,0x0,0x30,0x30,0x0},//
{0x0,0x50,0xA8,0x88,0x50,0x20,0x0,0x0},//
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
{0,0,0,0,0,0},//
};
unchar dig,gen,ret,scan,line,wei,a,d,b,c,x;
unint counter,shift;
unchar t,temp,cl;
//时钟脉冲
void clk()
{
PORTB |= _BV(1);
PORTB &= ~_BV(1);
}
//锁存
void len()
{
PORTB |= _BV(2);
PORTB &= ~_BV(2);
}
//发送数据高(1)
void dat_h()
{
PORTB |= _BV(0);
clk();
}
//发送数据低(0)
void dat_l()
{
PORTB &= ~_BV(0);
clk();
}
//延时
void delay(unint time)
{
unint x,y;
for (x=time; x>0; x--)
for (y=1000; y>0; y--);
}
//初始化IO口及数据
void io_int()
{
DDRD = 0xff;
DDRB = 0xff;
DDRC = 0xff;
clk_int;
// out_disable;
OUT = 0;
PORTC =0xff;
scan = 0x01;
}
//行扫描
void scan_re()
{
out_disable;
len();
OUT = scan;
if (scan != 0x80)
scan <<= 1;
else scan = 0x01;
out_enable;
}
//清屏
void clear(unchar cle)
{
unchar c;
for (c = cle;c>0; c--)
{
dat_l();
}
}
//定时器初始化
void time1_int()
{
TCCR1A = 0;
TCCR1B |= _BV(0);
TCNT1 = 0xf82f;
TIMSK |= _BV(TOIE1);
SREG = 0x80;//开总中断
}
//定时器1中断服务程序
ISR(TIMER1_OVF_vect)
{
PORTC = 0xaa;
delay(100);
PORTC = 0x55;
delay(100);
TIFR |= _BV(TOV1);
}
//发送列数据
void send_data(unchar temp)
{
if ((temp&wei) == wei)
dat_h();
else
dat_l();
if (wei != 0x04)
wei >>= 1;
else wei = 0x80;
}
void display()
{
for (gen=0;gen<8; gen++)
{
dig = ret/6;
x =ret%6;
wei = 0x80;
cache[0] = column[dig][gen];
cache[1] = column[dig+1][gen];
cache[2] = column[dig+2][gen];
cache[3] = column[dig+3][gen];
cache[4] = column[dig+4][gen];
for (t=0;t<6; t++)//显示第一个字
{
temp = cache[0];
send_data(temp);
}
for (t=0;t<6; t++)//显示第二个字
{
temp = cache[1];
send_data(temp);
}
for (t=0;t<6; t++)//显示第三个字
{
temp = cache[2];
send_data(temp);
}
for (t=0;t<6; t++)//显示第四个字
{
temp = cache[3];
send_data(temp);
}
for (t=0;t<x; t++)//第五个字缓冲
{
temp = cache[4];
send_data(temp);
}
scan_re();
delay(6000);
}
}
int main()
{
io_int();
while (1)
{
display();
counter++;
if (counter == 20)
{
counter = 0;
if (ret < 138)
ret ++;
else
{
ret = 0;
dig = 0;
}
}
}
} |