找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6941|回復(fù): 8
收起左側(cè)

16X16點(diǎn)陣廣告屏設(shè)計(jì) 仿真+原理圖+單片機(jī)程序+流程圖(可實(shí)現(xiàn)行掃描和列掃描)

  [復(fù)制鏈接]
ID:668693 發(fā)表于 2020-12-10 17:09 | 顯示全部樓層 |閱讀模式
點(diǎn)陣廣告屏設(shè)計(jì)  仿真+原理圖+程序+流程圖可以實(shí)現(xiàn)從左往右或從下往上滾動(dòng)顯示
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖20201210170210.png 51hei截圖20201210170353.png

單片機(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)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:825397 發(fā)表于 2021-2-25 21:34 | 顯示全部樓層
很好的新手學(xué)習(xí)資料,贊一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:367948 發(fā)表于 2021-3-13 10:52 來自手機(jī) | 顯示全部樓層
寫的很詳細(xì),適合初學(xué)者,謝謝樓主!
回復(fù)

使用道具 舉報(bào)

ID:886808 發(fā)表于 2021-3-13 13:24 來自手機(jī) | 顯示全部樓層
好,注釋特別詳細(xì)!收藏備用。
回復(fù)

使用道具 舉報(bào)

ID:886808 發(fā)表于 2021-3-13 13:27 來自手機(jī) | 顯示全部樓層
好,特別適用,收藏了,有空好好學(xué)學(xué)。贊!
回復(fù)

使用道具 舉報(bào)

ID:903979 發(fā)表于 2021-4-12 00:36 | 顯示全部樓層
很好的新手學(xué)習(xí)資料,贊一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:907621 發(fā)表于 2021-4-18 10:32 | 顯示全部樓層
怎么用單片機(jī)同時(shí)控制兩塊板子
回復(fù)

使用道具 舉報(bào)

ID:1125084 發(fā)表于 2024-6-13 16:22 | 顯示全部樓層
非常棒,感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:1127480 發(fā)表于 2024-6-28 21:46 | 顯示全部樓層
無敵了這程序
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表