點陣廣告屏設計 仿真+原理圖+程序+流程圖可以實現從左往右或從下往上滾動顯示
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖20201210170210.png (139.09 KB, 下載次數: 91)
下載附件
2020-12-10 17:07 上傳
51hei截圖20201210170353.png (135.08 KB, 下載次數: 84)
下載附件
2020-12-10 17:07 上傳
單片機源程序如下:
/*********************************************************************
修改時間:2020年10月7日19:42
功能:16*16LED點陣顯示
目的:用兩種滾動模式顯示”創新實驗班制作“
顯示方式:列掃描方式
取模軟件:PCtoLCD2002完美版
**********************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit datal595=P1^0; //列數據線
sbit datah595=P1^1; //行數據線
sbit clk595=P1^2; //數據輸入時鐘線
sbit str595=P1^3; //輸出存儲器鎖存時鐘線
sbit oe595=P1^4; //oe輸出使能
//取模方式:陽碼、逐行式、逆向、十六進制、C51格式自定義 (使用Pctolcd2002軟件)
uchar code displaydata[]= //在ROM中定義一個可變長度數組,供用戶填充一定個數的字模
{ //可填充的最大字模數取決于您所選用的單片機ROM空間大小
0x00,0x00, /*表頭*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//在以下位置插入字模
0x40,0x00,0x20,0x00,0xD0,0x3F,0x4C,0x40,0x43,0x44,0x44,0x48,0xC8,0x47,0x10,0x40,
0x20,0x70,0x00,0x00,0xF8,0x0F,0x00,0x40,0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,/*"創",0*/
0x40,0x20,0x44,0x12,0x54,0x4A,0x65,0x82,0xC6,0x7F,0x64,0x02,0x54,0x0A,0x44,0x92,
0x00,0x60,0xFC,0x1F,0x44,0x00,0x44,0x00,0xC4,0xFF,0x42,0x00,0x40,0x00,0x00,0x00,/*"新",1*/
0x10,0x04,0x0C,0x84,0x04,0x84,0x84,0x44,0x14,0x47,0x64,0x24,0x05,0x14,0x06,0x0C,
0xF4,0x07,0x04,0x0C,0x04,0x14,0x04,0x24,0x04,0x44,0x14,0x84,0x0C,0x04,0x00,0x00,/*"實",2*/
0x02,0x08,0xFA,0x18,0x82,0x48,0x82,0x84,0xFE,0x44,0x80,0x3F,0x40,0x40,0x20,0x44,
0x50,0x58,0x4C,0x41,0x43,0x4E,0x4C,0x60,0x50,0x58,0x20,0x47,0x40,0x40,0x00,0x00,/*"驗",3*/
0x84,0x10,0x84,0x30,0xFC,0x1F,0x84,0x08,0x84,0x88,0x00,0x42,0xF8,0x21,0x00,0x18,
0xFF,0x07,0x00,0x00,0x84,0x20,0x84,0x20,0xFC,0x3F,0x84,0x20,0x84,0x20,0x00,0x00,/*"班",4*/
0x40,0x00,0x50,0x00,0x4E,0x3E,0x48,0x02,0x48,0x02,0xFF,0xFF,0x48,0x12,0x48,0x22,
0x48,0x1E,0x40,0x00,0xF8,0x0F,0x00,0x40,0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,/*"制",5*/
0x00,0x01,0x80,0x00,0x60,0x00,0xF8,0xFF,0x07,0x00,0x40,0x00,0x30,0x00,0x0F,0x00,
0xF8,0xFF,0x88,0x08,0x88,0x08,0x88,0x08,0x88,0x08,0x08,0x08,0x08,0x00,0x00,0x00,/*"作",6*/
//至此字模插入結束
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
/*----------------------------------
函數名字:delay_ms
形式參數:無字符整型 i:延時多少
函數功能:以1ms為單位的函數延時
返 回 值:無
------------------------------------*/
void delay_ms(uint i)
{
uint j;
for(;i>0;i--)
for(j=110;j>0;j--);
}
/*----------------------------------
函數名字:senddata
形式參數:無字符整型 datah:行的數據
無字符整型 datal:列的數據
函數功能:把數據發送給芯片74HC595
返 回 值:無
------------------------------------*/
void senddata(uint datah,uint datal) //向行和列的4個595同時發送數據,顯示其中的一列數據
{
uchar i=0;
uint m,n;
oe595=0;
str595=0;
for(;i<16;i++) //行和列各有兩片595驅動,所以行和列分別需要連續送兩個字節數據
{
clk595=0;
m=datah; //行為高電平驅動
n=~datal; //列為低電平驅動
m&=0x8000;
n&=0x8000;
datah595=(bit)m; //在每個clk周期,同時送出行和列的1bit串行數據
datal595=(bit)n;
datah<<=1;
datal<<=1;
clk595=1;
}
str595=1; //一列數據送完,鎖存到輸出端進行顯示
str595=0;
}
/*----------------------------------
函數名字:char_max
形式參數:無字符字符型 *dat:兩個8位數據的第一個數據的地址
函數功能:受到取模軟件的限制,需要對字模表的數據進行重新排列
將兩個8位的數據拼成顯示所需16位的數據
返回值 :uint:返回排列好的值
------------------------------------*/
uint char_max(uchar *dat)
{
uint l,h;
h = (uint)*(dat+1); //16位中的高字節數據
h <<= 8;
h &=0xff00;
l = (uint)*dat; //16位中的低字節數據
l &= 0x00ff;
return l|h;
}
/*----------------------------------
函數名字:horizontal
形式參數:無字符字符型 time:字符移動的速度
無字符字符型 counth:移動全部字符所需的列數
無符號字符型指針 p:字符顯示數據的首地址
函數功能:顯示字符水平移動
返回值 :無
------------------------------------*/
void horizontal(uchar time,uint count,uchar *p) //垂直移動
{
uint datah,datal; //datah是行數據,datal是列選通
uchar x,y;
uint z;
for(z=0;z<count;z++) //顯示字模表中的所有漢字(包括有用字模前后的的清屏數據)
{
for(y=0;y<time;y++) //該屏數據重復顯示time次后刷新,實際上這是水平移動的速度
{
for(x=0;x<16;x++) //發送一整屏數據,16個16位
{
p += 2;
datah = char_max(p);
datal = 0x0001<<x; //列選通位移到相應的列上進行選通
// datah=~datah; //去掉此行前面的注釋則水平移動程反白顯示
senddata(datah,datal); //將行和列數據發送出去進行一列的顯示
}
p-=32; //指針恢復為這個漢字首地址,準備重復顯示該屏數據time次
} //該屏數據經過了time次的顯示,顯示數據準備更新
p+=2; //指向了該漢字的下一列,左移一列漢字
} //移動了字模表中的所有漢字,左移過程結束
oe595=1;
}
/*----------------------------------
函數名字: vertical
形式參數: 無字符字符型 a:半角標志 ;如果 a=16 則字符顯示數據中出現了半角字
無字符字符型 time:字符移動的速度
無字符字符型 counth:移動全部字符所需的行數
無符號字符型 指針 p:字符顯示數據的首地址
函數功能: 顯示字符垂直移動
返回值 : 無
------------------------------------*/
void vertical(uchar a,uchar time,uint countv,uchar *p) //水平移動
{
uint datah,datal; //datah是行數據,datal是列選通
uchar x,y,e,w=0;
uint z;
uint datah1,datah2;
uchar *q;
q=p+32;
for(z=countv;z>0;z--) //顯示字模表中的所有漢字(包括有用字模前后的的清屏數據)
{
for(e=0;e<16;e++) //拼字的過程,從一個漢字完整地過渡到下一個漢字
{
for(y=0;y<time;y++) //該屏數據重復顯示time次后刷新,實際上這是垂直移動的速度
{
for(x=0;x<16;x++) //發送一整屏數據,16個16位
{
/*處理p所指向漢字某一列的拼接*/
p += 2;
datah1 = char_max(p);
datah1>>=w; //這行語句改為左移同時下處改為右移,則顯示向下移動
/*處理下一個漢字相應列的拼接*/
q += 2;
datah2 = char_max(q);
datah2 <<= (16-w); //這行語句改為右移同時上處改為左移,則顯示向下移動
/*準備顯示這列數據*/
datah = datah1|datah2; //此時進行拼接某漢字某一列的運算操作
datal = 0x0001<<x; //列選通位移到相應的列上進行選通
//datah=~datah; //去掉此行前面的注釋則垂直移動程反白顯示
senddata(datah,datal);
} //一整屏數據發送完畢
p-=32;q-=32; //指針恢復為這個漢字首地址,準備重復顯示該屏數據time次
} //該屏數據經過了time次的顯示,顯示數據準備更新
w++; //顯示上移w行的拼接數據移位位數加1
if(w>=16) w=0; //如果上移了15行,w歸0,結束此次拼字循環
} //此次拼字循環結束
/*開始對下一組漢字進行拼字操作*/
if((a==16)&&(z==2)) //如果字模表中含有半個漢字并且顯示最后一組漢字
{ p+=32;q+=16; } //則q+16,相當于用16個零填充不足的半個漢字
else //其它情況下
{ p+=32;q+=32; } //p和q一律指向下一個漢字
} //拼完字模表中的所有漢字,上移過程結束(注:上移是現象,拼字是本質)
oe595=1;
}
void main(void)
{
uchar time=8; //調整這個值的大小將會改變漢字移動的速度
uint size=sizeof(displaydata); //計算出上述在ROM中定義的可變長度字模表填充數據后的大小
uint countv=((size-2)>>5)-1; // 8 //這些個漢字垂直移動全部完成所需要的拼字次數
uint counth=countv<<4; //128 //這些個漢字水平移動全部完成所需要的左移列數
uchar a=(uchar)((size-2)%32); //判斷字模表中是否會出現一個半角的數字或符號或字母
if(a==16) //如果余數為16,說明出現了半角情況
{
counth+=8; //這時左移時需要多移動8列
countv+=1; //而右移時需要多拼一個漢字
}
while(1)
{
horizontal(time,counth,displaydata); //將字模表中的所有漢字進行水平移動
delay_ms(2000);
vertical(a,time,countv,displaydata); //將字模表中的所有漢字進行垂直移動
delay_ms(2000);
}
}
全部資料51hei下載地址:
16X16點陣燈.zip
(131.64 KB, 下載次數: 169)
2020-12-10 17:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|