點(diǎn)陣廣告屏設(shè)計(jì) 仿真+原理圖+程序+流程圖可以實(shí)現(xiàn)從左往右或從下往上滾動(dòng)顯示
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
/*********************************************************************
修改時(shí)間:2020年10月7日19:42
功能:16*16LED點(diǎn)陣顯示
目的:用兩種滾動(dòng)模式顯示”創(chuàng)新實(shí)驗(yàn)班制作“
顯示方式:列掃描方式
取模軟件:PCtoLCD2002完美版
**********************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit datal595=P1^0; //列數(shù)據(jù)線
sbit datah595=P1^1; //行數(shù)據(jù)線
sbit clk595=P1^2; //數(shù)據(jù)輸入時(shí)鐘線
sbit str595=P1^3; //輸出存儲(chǔ)器鎖存時(shí)鐘線
sbit oe595=P1^4; //oe輸出使能
//取模方式:陽碼、逐行式、逆向、十六進(jìn)制、C51格式自定義 (使用Pctolcd2002軟件)
uchar code displaydata[]= //在ROM中定義一個(gè)可變長(zhǎng)度數(shù)組,供用戶填充一定個(gè)數(shù)的字模
{ //可填充的最大字模數(shù)取決于您所選用的單片機(jī)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,/*"創(chuàng)",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,/*"實(shí)",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,/*"驗(yàn)",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*/
//至此字模插入結(jié)束
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
};
/*----------------------------------
函數(shù)名字:delay_ms
形式參數(shù):無字符整型 i:延時(shí)多少
函數(shù)功能:以1ms為單位的函數(shù)延時(shí)
返 回 值:無
------------------------------------*/
void delay_ms(uint i)
{
uint j;
for(;i>0;i--)
for(j=110;j>0;j--);
}
/*----------------------------------
函數(shù)名字:senddata
形式參數(shù):無字符整型 datah:行的數(shù)據(jù)
無字符整型 datal:列的數(shù)據(jù)
函數(shù)功能:把數(shù)據(jù)發(fā)送給芯片74HC595
返 回 值:無
------------------------------------*/
void senddata(uint datah,uint datal) //向行和列的4個(gè)595同時(shí)發(fā)送數(shù)據(jù),顯示其中的一列數(shù)據(jù)
{
uchar i=0;
uint m,n;
oe595=0;
str595=0;
for(;i<16;i++) //行和列各有兩片595驅(qū)動(dòng),所以行和列分別需要連續(xù)送兩個(gè)字節(jié)數(shù)據(jù)
{
clk595=0;
m=datah; //行為高電平驅(qū)動(dòng)
n=~datal; //列為低電平驅(qū)動(dòng)
m&=0x8000;
n&=0x8000;
datah595=(bit)m; //在每個(gè)clk周期,同時(shí)送出行和列的1bit串行數(shù)據(jù)
datal595=(bit)n;
datah<<=1;
datal<<=1;
clk595=1;
}
str595=1; //一列數(shù)據(jù)送完,鎖存到輸出端進(jìn)行顯示
str595=0;
}
/*----------------------------------
函數(shù)名字:char_max
形式參數(shù):無字符字符型 *dat:兩個(gè)8位數(shù)據(jù)的第一個(gè)數(shù)據(jù)的地址
函數(shù)功能:受到取模軟件的限制,需要對(duì)字模表的數(shù)據(jù)進(jìn)行重新排列
將兩個(gè)8位的數(shù)據(jù)拼成顯示所需16位的數(shù)據(jù)
返回值 :uint:返回排列好的值
------------------------------------*/
uint char_max(uchar *dat)
{
uint l,h;
h = (uint)*(dat+1); //16位中的高字節(jié)數(shù)據(jù)
h <<= 8;
h &=0xff00;
l = (uint)*dat; //16位中的低字節(jié)數(shù)據(jù)
l &= 0x00ff;
return l|h;
}
/*----------------------------------
函數(shù)名字:horizontal
形式參數(shù):無字符字符型 time:字符移動(dòng)的速度
無字符字符型 counth:移動(dòng)全部字符所需的列數(shù)
無符號(hào)字符型指針 p:字符顯示數(shù)據(jù)的首地址
函數(shù)功能:顯示字符水平移動(dòng)
返回值 :無
------------------------------------*/
void horizontal(uchar time,uint count,uchar *p) //垂直移動(dòng)
{
uint datah,datal; //datah是行數(shù)據(jù),datal是列選通
uchar x,y;
uint z;
for(z=0;z<count;z++) //顯示字模表中的所有漢字(包括有用字模前后的的清屏數(shù)據(jù))
{
for(y=0;y<time;y++) //該屏數(shù)據(jù)重復(fù)顯示time次后刷新,實(shí)際上這是水平移動(dòng)的速度
{
for(x=0;x<16;x++) //發(fā)送一整屏數(shù)據(jù),16個(gè)16位
{
p += 2;
datah = char_max(p);
datal = 0x0001<<x; //列選通位移到相應(yīng)的列上進(jìn)行選通
// datah=~datah; //去掉此行前面的注釋則水平移動(dòng)程反白顯示
senddata(datah,datal); //將行和列數(shù)據(jù)發(fā)送出去進(jìn)行一列的顯示
}
p-=32; //指針恢復(fù)為這個(gè)漢字首地址,準(zhǔn)備重復(fù)顯示該屏數(shù)據(jù)time次
} //該屏數(shù)據(jù)經(jīng)過了time次的顯示,顯示數(shù)據(jù)準(zhǔn)備更新
p+=2; //指向了該漢字的下一列,左移一列漢字
} //移動(dòng)了字模表中的所有漢字,左移過程結(jié)束
oe595=1;
}
/*----------------------------------
函數(shù)名字: vertical
形式參數(shù): 無字符字符型 a:半角標(biāo)志 ;如果 a=16 則字符顯示數(shù)據(jù)中出現(xiàn)了半角字
無字符字符型 time:字符移動(dòng)的速度
無字符字符型 counth:移動(dòng)全部字符所需的行數(shù)
無符號(hào)字符型 指針 p:字符顯示數(shù)據(jù)的首地址
函數(shù)功能: 顯示字符垂直移動(dòng)
返回值 : 無
------------------------------------*/
void vertical(uchar a,uchar time,uint countv,uchar *p) //水平移動(dòng)
{
uint datah,datal; //datah是行數(shù)據(jù),datal是列選通
uchar x,y,e,w=0;
uint z;
uint datah1,datah2;
uchar *q;
q=p+32;
for(z=countv;z>0;z--) //顯示字模表中的所有漢字(包括有用字模前后的的清屏數(shù)據(jù))
{
for(e=0;e<16;e++) //拼字的過程,從一個(gè)漢字完整地過渡到下一個(gè)漢字
{
for(y=0;y<time;y++) //該屏數(shù)據(jù)重復(fù)顯示time次后刷新,實(shí)際上這是垂直移動(dòng)的速度
{
for(x=0;x<16;x++) //發(fā)送一整屏數(shù)據(jù),16個(gè)16位
{
/*處理p所指向漢字某一列的拼接*/
p += 2;
datah1 = char_max(p);
datah1>>=w; //這行語句改為左移同時(shí)下處改為右移,則顯示向下移動(dòng)
/*處理下一個(gè)漢字相應(yīng)列的拼接*/
q += 2;
datah2 = char_max(q);
datah2 <<= (16-w); //這行語句改為右移同時(shí)上處改為左移,則顯示向下移動(dòng)
/*準(zhǔn)備顯示這列數(shù)據(jù)*/
datah = datah1|datah2; //此時(shí)進(jìn)行拼接某漢字某一列的運(yùn)算操作
datal = 0x0001<<x; //列選通位移到相應(yīng)的列上進(jìn)行選通
//datah=~datah; //去掉此行前面的注釋則垂直移動(dòng)程反白顯示
senddata(datah,datal);
} //一整屏數(shù)據(jù)發(fā)送完畢
p-=32;q-=32; //指針恢復(fù)為這個(gè)漢字首地址,準(zhǔn)備重復(fù)顯示該屏數(shù)據(jù)time次
} //該屏數(shù)據(jù)經(jīng)過了time次的顯示,顯示數(shù)據(jù)準(zhǔn)備更新
w++; //顯示上移w行的拼接數(shù)據(jù)移位位數(shù)加1
if(w>=16) w=0; //如果上移了15行,w歸0,結(jié)束此次拼字循環(huán)
} //此次拼字循環(huán)結(jié)束
/*開始對(duì)下一組漢字進(jìn)行拼字操作*/
if((a==16)&&(z==2)) //如果字模表中含有半個(gè)漢字并且顯示最后一組漢字
{ p+=32;q+=16; } //則q+16,相當(dāng)于用16個(gè)零填充不足的半個(gè)漢字
else //其它情況下
{ p+=32;q+=32; } //p和q一律指向下一個(gè)漢字
} //拼完字模表中的所有漢字,上移過程結(jié)束(注:上移是現(xiàn)象,拼字是本質(zhì))
oe595=1;
}
void main(void)
{
uchar time=8; //調(diào)整這個(gè)值的大小將會(huì)改變漢字移動(dòng)的速度
uint size=sizeof(displaydata); //計(jì)算出上述在ROM中定義的可變長(zhǎng)度字模表填充數(shù)據(jù)后的大小
uint countv=((size-2)>>5)-1; // 8 //這些個(gè)漢字垂直移動(dòng)全部完成所需要的拼字次數(shù)
uint counth=countv<<4; //128 //這些個(gè)漢字水平移動(dòng)全部完成所需要的左移列數(shù)
uchar a=(uchar)((size-2)%32); //判斷字模表中是否會(huì)出現(xiàn)一個(gè)半角的數(shù)字或符號(hào)或字母
if(a==16) //如果余數(shù)為16,說明出現(xiàn)了半角情況
{
counth+=8; //這時(shí)左移時(shí)需要多移動(dòng)8列
countv+=1; //而右移時(shí)需要多拼一個(gè)漢字
}
while(1)
{
horizontal(time,counth,displaydata); //將字模表中的所有漢字進(jìn)行水平移動(dòng)
delay_ms(2000);
vertical(a,time,countv,displaydata); //將字模表中的所有漢字進(jìn)行垂直移動(dòng)
delay_ms(2000);
}
}
全部資料51hei下載地址:
16X16點(diǎn)陣燈.zip
(131.64 KB, 下載次數(shù): 169)
2020-12-10 17:07 上傳
點(diǎn)擊文件名下載附件
|