51单片机驱动的16*16 LED 点阵 0-9滚动 74HC595 74HC138 74HC04
有4个按键
proteus仿真原理图如下:
单片机源程序如下:
- /*2个点阵左/右移动显示*/
- /*头文件*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define NOP() _nop_()
- /*端口定义*/
- sbit EN_port = P1^3;
- sbit DA_in_port = P1^2;
- sbit CLK_port = P1^1; //时钟
- sbit Latch_port = P1^0;
- #define ABCD_port P1 //HC138 ABCD端口定义
- //sbit D_port = P1^7;
- //sbit C_port = P1^6;
- //sbit B_port = P1^5;
- //sbit A_port = P1^4;
- sbit S1 = P2^0;
- sbit S2 = P2^1;
- sbit S3 = P2^2;
- sbit S4 = P2^3;
- //显示的字库
- uchar code ziku_table[]={
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*显示8行空白*/
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xDF,0xFE,0xEF,0xFD,0xEF,0xFD,0xEF,0xFD,
- 0xEF,0xFD,0xEF,0xFD,0xEF,0xFD,0xEF,0xFD,0xDF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\0.BMP.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0x1F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,
- 0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x1F,0xFC,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\1.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFC,0xDF,0xFB,0xDF,0xFB,0xDF,0xFB,0xFF,0xFD,
- 0xFF,0xFD,0xFF,0xFE,0x7F,0xFF,0xBF,0xFF,0xDF,0xFB,0x1F,0xF8,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\2.BMP.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFC,0xDF,0xFB,0xDF,0xFB,0xFF,0xFD,0x7F,0xFE,
- 0xFF,0xFD,0xFF,0xFB,0xFF,0xFB,0xDF,0xFB,0xDF,0xFD,0x3F,0xFE,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\3.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFE,0xBF,0xFE,0xDF,0xFE,0xDF,0xFE,
- 0xEF,0xFE,0xEF,0xFE,0x0F,0xFC,0xFF,0xFE,0xFF,0xFE,0x3F,0xFC,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\4.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xF8,0xDF,0xFF,0xDF,0xFF,0xDF,0xFF,0x5F,0xFE,
- 0x9F,0xFD,0xFF,0xFB,0xFF,0xFB,0xDF,0xFB,0xDF,0xFD,0x3F,0xFE,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\5.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFC,0xBF,0xFD,0xDF,0xFF,0xDF,0xFF,0x5F,0xFE,
- 0x9F,0xFD,0xDF,0xFB,0xDF,0xFB,0xDF,0xFB,0xBF,0xFD,0x7F,0xFE,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\6.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xF8,0xDF,0xFD,0xDF,0xFD,0xFF,0xFE,0xFF,0xFE,
- 0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\7.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xFE,0xEF,0xFD,0xEF,0xFD,0xEF,0xFD,0xDF,0xFE,
- 0x3F,0xFF,0xDF,0xFE,0xEF,0xFD,0xEF,0xFD,0xEF,0xFD,0x1F,0xFE,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\8.BMP",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFE,0xBF,0xFD,0xDF,0xFB,0xDF,0xFB,0xDF,0xFB,
- 0xBF,0xF9,0x7F,0xFA,0xFF,0xFB,0xFF,0xFB,0xBF,0xFD,0x3F,0xFE,0xFF,0xFF,0xFF,0xFF,/*"C:\Users\Administrator\Desktop\点阵16x16陕显示数字\9.BMP",0*/0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*显示8行空白*/
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*显示8行空白*/
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- };
- uchar data disp_buff[64]; //64 个显示数据缓存
- //数据格式为 第1级第1行高八位,低八位,第2级第1行高八位,低八位,第1级第2行高八位。。。。。。
- uchar data disp_han; //目前显示到第几行
- void T0_Set() /*定义中断方式,中断时间*/
- {
- TMOD = 0x01; //定时0,工作在方式1
- TH0 = (65536-1000)/256;
- TL0 = (65536-1000)/256;
- TR0 = 1; //启动计数
- EA = 1; //开总中断
- ET0 = 1; //开定时器0中断
- return;
- }
- void delay_1ms(uchar x) //延时1ms程序
- {
- uchar j;
- while(x--){
- for(j=0;j<125;j++)
- {;}
- }
- }
- void main() //主程序
- {
- uchar i;
- uint data_temp[3];
- uint temp,temp1;
- uchar hanzi;
- uchar han;
- uchar shift=1;
- uchar mode=0;
- MM:shift=1;
- mode=0;
- if(mode==0)
- {
- for(i=0;i<64;i++) disp_buff[i]=0xff;
- T0_Set();
- while(1){
- for(hanzi=0;hanzi<10;hanzi++){ //最多显示多少个字
- for(shift=0;shift<16;shift++){ //一个字移位16位
- for(han=0;han<16;han++){ //一个字有16行数据
- data_temp[0]=ziku_table[(hanzi*32)+(han*2)+1]*0x100 + ziku_table[(hanzi*32)+(han*2)];
- data_temp[1]=ziku_table[((hanzi+1)*32)+(han*2)+1]*0x100 + ziku_table[((hanzi+1)*32)+(han*2)];
- data_temp[2]=ziku_table[((hanzi+2)*32)+(han*2)+1]*0x100 + ziku_table[((hanzi+2)*32)+(han*2)];
- M0: if(S2==0)
- {
- delay_1ms(10); //延时去抖动
- mode=1; //在1 2 3中切换
- while(!S2){;} //等待按键释放
- goto M1;
- }
- if(S3==0)
- {
- delay_1ms(10); //延时去抖动
- while(!S3){;} //等待按键释放
- goto MM;
- }
- if(S4==0)
- {
- delay_1ms(10); //延时去抖动
- while(!S4){;} //等待按键释放
- while(1)
- {
- if(S1==0){mode=0;break;}
- if(S2==0){mode=1;break;}
- if(S3==0){mode=0;break;}
- if(S4==0){break;}
- }
- }
- //左往右移动
- temp = data_temp[0];
- temp1 = data_temp[1];
- for(i=shift;i>0;i--){
- temp = (temp<<1) ;
- if((temp1&0x8000)!=0) temp = temp + 0x0001;
- temp1 = (temp1<<1);
- }
- disp_buff[han*4+3]=temp/0x100;
- disp_buff[han*4+2]=temp%0x100;
- //----------------------
- temp = data_temp[1];
- temp1 = data_temp[2];
- for(i=shift;i>0;i--){
- temp = (temp<<1) ;
- if((temp1&0x8000)!=0) temp = temp + 0x0001;
- temp1 = (temp1<<1);
- }
- disp_buff[han*4+1]=temp/0x100;
- disp_buff[han*4]=temp%0x100;
-
- }
- delay_1ms(15); //移位速度
- }
- }
- }//mode==0
- if(mode==1)
- {
- for(hanzi=0;hanzi<6;hanzi++){ //最多显示多少个字
- for(shift=0;shift<16;shift++){ //一个字移位16位
- for(han=0;han<16;han++){ //一个字有16行数据
- data_temp[0]=ziku_table[(hanzi*32)+(han*2)+1]*0x100 + ziku_table[(hanzi*32)+(han*2)];
- data_temp[1]=ziku_table[((hanzi+1)*32)+(han*2)+1]*0x100 + ziku_table[((hanzi+1)*32)+(han*2)];
- data_temp[2]=ziku_table[((hanzi+2)*32)+(han*2)+1]*0x100 + ziku_table[((hanzi+2)*32)+(han*2)];
- M1: if(S1==0)
- {
- delay_1ms(10); //延时去抖动
- mode=0; //在1 2 3中切换
- while(!S1){;} //等待按键释放
- goto M0;
- }
- if(S3==0)
- {
- delay_1ms(10); //延时去抖动
- while(!S3){;} //等待按键释放
- goto MM;
- }
- if(S4==0)
- {
- delay_1ms(10); //延时去抖动
- while(!S4){;} //等待按键释放
- while(1)
- {
- if(S1==0){mode=0;break;}
- if(S2==0){mode=1;break;}
- if(S3==0){mode=0;break;}
- if(S4==0){break;}
- }
- }
-
- //右往左移动
- temp = data_temp[0];
- temp1 = data_temp[1];
- for(i=shift;i>0;i--){
- temp = (temp>>1) ;
- if((temp1&0x0001)!=0) temp = temp + 0x8000;
- temp1 = (temp1>>1);
- }
- disp_buff[han*4+1]=temp/0x100;
- disp_buff[han*4+0]=temp%0x100;
- //------------------------------
- temp = data_temp[1];
- temp1 = data_temp[2];
- for(i=shift;i>0;i--){
- temp = (temp>>1) ;
- if((temp1&0x0001)!=0) temp = temp + 0x8000;
- temp1 = (temp1>>1);
- }
- disp_buff[han*4+3]=temp/0x100;
- disp_buff[han*4+2]=temp%0x100;
- }
- delay_1ms(15); //移位速度
- }
- }
- }
- }
- }
- void SLED_Disp() interrupt 1 using 3
- {
- uchar i;
- uchar data_buff;
- uchar temp;
- uchar zishu;
- uchar code Module_Quantity=2; //模块数量
- uchar han;
- TH0 = (65536-1000)/256;
- TL0 = (65536-1000)/256;
- Latch_port = 0; //HC595锁定输出,避免数据传输过程中,屏数据变化从而显示闪烁
- CLK_port = 0;
- han=disp_han;
- for(zishu=Module_Quantity;zishu>0;zishu--){
- temp = disp_han*Module_Quantity*2 + (zishu-1)*2+1;
- data_buff = disp_buff[temp];
- for(i=0;i<8;i++){
- if((data_buff&0x80)!=0) DA_in_port = 1;
- else DA_in_port = 0;
- CLK_port = 1;
- CLK_port = 0;
- data_buff <<= 1;
- }
- temp = disp_han*Module_Quantity*2 + (zishu-1)*2;
- data_buff = disp_buff[temp];
- for(i=0;i<8;i++){
- if((data_buff&0x80)!=0) DA_in_port = 1;
- else DA_in_port = 0;
- CLK_port = 1;
- CLK_port = 0;
- data_buff <<= 1;
- }
- }
-
- EN_port = 1; //关屏显示,原理为使HC138输出全为1,从而三极管截止,点阵不显示
- ABCD_port = (ABCD_port & 0x0f)|(han<<4); //HC138译码输出
- Latch_port = 1; //允许HC595数据输出到Q1-Q8端口
- EN_port = 0; //HC138输出有效,打开显示
- Latch_port = 0; //锁定HC595数据输出
- disp_han++; //显示下一行数据
- if(disp_han>=16) disp_han=0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
1 滚动0-9 仿真电路和源程序.rar
(59.32 KB, 下载次数: 104)
|