找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5467|回复: 6
收起左侧

16X16点阵广告屏设计 仿真+原理图+单片机程序+流程图(可实现行扫描和列扫描)

  [复制链接]
ID:668693 发表于 2020-12-10 17:09 | 显示全部楼层 |阅读模式
点阵广告屏设计  仿真+原理图+程序+流程图可以实现从左往右或从下往上滚动显示
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei截图20201210170210.png 51hei截图20201210170353.png

单片机源程序如下:
/*********************************************************************        
        修改时间: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, 下载次数: 141)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:825397 发表于 2021-2-25 21:34 | 显示全部楼层
很好的新手学习资料,赞一个
回复

使用道具 举报

ID:367948 发表于 2021-3-13 10:52 来自手机 | 显示全部楼层
写的很详细,适合初学者,谢谢楼主!
回复

使用道具 举报

ID:886808 发表于 2021-3-13 13:24 来自手机 | 显示全部楼层
好,注释特别详细!收藏备用。
回复

使用道具 举报

ID:886808 发表于 2021-3-13 13:27 来自手机 | 显示全部楼层
好,特别适用,收藏了,有空好好学学。赞!
回复

使用道具 举报

ID:903979 发表于 2021-4-12 00:36 | 显示全部楼层
很好的新手学习资料,赞一个
回复

使用道具 举报

ID:907621 发表于 2021-4-18 10:32 | 显示全部楼层
怎么用单片机同时控制两块板子
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表