⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led点阵显示屏源程序.c

📁 本点阵电子显示屏系统以STC89C52单片机作为控制核心
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************
**
** 毕业设计:LED点阵显示屏源程序
** 山东理工大学 电气与电子工程学院 自动化专业
** 作者:胡成通
** 完成时间:2007-06-10
**
*********************************************************/
#include <reg51.h>
#include <stdio.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char

#define CS165_2 XBYTE[0xbff8];  //74HC165地址
#define CS165_3 XBYTE[0xbff8];  //
sbit cs_6116_138=P1^4;  //控制板上6116和138的片选,=0选中6116,=1选中74LS138
sbit cs_138=P2^7;
bit bdata fun_com; //单片机单机运行标志位
                 //当此标志位有效时=1,则循环调用动态显示子程序(暂时为7种显示//模式)
bit bdata fun_pc;//单片机显示PC通信的数据,
                 //标志位有效=1时,跳转到相应的子程序,处理PC通信数据,进行约定//的显示
uchar xdata show_buffer1[16][8];//显示缓冲区1,列为8字节数据(代表64点),
//一共有16行   
uchar xdata show_buffer2[16][8];  //两显示缓冲区存放在片外数据存储器(6116)
bit bdata showbuf_sign;  //显示缓冲区标志位,=0时使用show_buffer1,
//=1时使用show_buffer2
uchar xdata show_pc[16][42]; //用于存储PC通信的数据,最多可以20个汉字
//(或40个ASCII字符)加上相关的处理信息
uchar idata *show_pcpoint;  //用于在串行中断处理中,指向show_pc,
//将所有的通信数据信息放入此数组中
uchar idata **show_pcdata;  //指向PC通信有效显示数组的数据的首地址
uint  show_pccount; //对通信数据个数计数
bit bdata show_pccom; //PC正在通信标志位,=1有效
bit bdata show_pcend; //PC通信结束标志位

uint PC_COM(void);   //函数声明
void uart_int(void);
void show_static(uchar **);
void show_left(uchar **,uint);
void show_right(uchar **);
void show_up(uchar **);
void show_down(uchar **);
void show_upspread(uchar **);
void show_downspread(uchar **);
void show_down(uchar **);
void show_middle(uchar **);
void show_pcprocess(uint);


uchar xdata data_com[16][12]={
      0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,   //"山"
      0x41, 0x04, 0x41, 0x04, 0x41, 0x04, 0x41, 0x04,
      0x41, 0x04, 0x41, 0x04, 0x41, 0x04, 0x41, 0x04,
      0x41, 0x04, 0x7F, 0xFC, 0x40, 0x04, 0x00, 0x00,

      0x02, 0x00, 0x02, 0x00, 0x02, 0x04, 0xFF, 0xFE,  //"东"
      0x04, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x10,
      0x3F, 0xF8, 0x01, 0x00, 0x09, 0x40, 0x09, 0x20,
      0x11, 0x10, 0x21, 0x18, 0x45, 0x08, 0x02, 0x00,

      0x00, 0x08, 0x13, 0xFC, 0xFA, 0x48, 0x22, 0x48,
      0x23, 0xF8, 0x22, 0x48, 0xFA, 0x48, 0x23, 0xF8,
      0x20, 0x40, 0x20, 0x50, 0x23, 0xF8, 0x3C, 0x40,
      0xE0, 0x40, 0x40, 0x44, 0x0F, 0xFE, 0x00, 0x00,  //"理"

      0x00, 0x00, 0x00, 0x08, 0x7F, 0xFC, 0x01, 0x00,
      0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
      0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
      0x01, 0x04, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,  //"工"

      0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
      0x01, 0x04, 0xFF, 0xFE, 0x01, 0x00, 0x02, 0x80,
      0x02, 0x80, 0x02, 0x40, 0x04, 0x40, 0x04, 0x20,
      0x08, 0x10, 0x10, 0x0E, 0x60, 0x04, 0x00, 0x00,  //"大"

      0x22, 0x08, 0x11, 0x08, 0x11, 0x10, 0x00, 0x20,
      0x7F, 0xFE, 0x40, 0x02, 0x80, 0x04, 0x1F, 0xE0,
      0x00, 0x40, 0x01, 0x84, 0xFF, 0xFE, 0x01, 0x00,
      0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00   //"学"

                              };
/*=======================================================*/
/*====================主程序=============================*/
/*======================================================*/

void main(void)
    {
     uint all_pcdata; //PC通信的有效显示数据字节个数
     uart_int();      //初始化串口,设置波特率\开中断\串口工作模式
     show_pcpoint=show_pc[0][0]; //指针指向数据存储数组
   //  show_pccount=0; //通信数据个数计数清零
      show_pccom=0;  //通信标志位清零

     fun_pc=0;
     fun_com=1;

     while(1)
        {
         if(fun_com==1)
             {
              if(fun_com==1&&fun_pc==0)
                 {show_left(data_com,12); }
              if(fun_com==1&&fun_pc==0)
                 {show_right(data_com); }
              if(fun_com==1&&fun_pc==0)
                 {show_up(data_com); }
              if(fun_com==1&&fun_pc==0)
                 {show_down(data_com); }
              if(fun_com==1&&fun_pc==0)
                 {show_upspread(data_com); }
              if(fun_com==1&&fun_pc==0)
                 {show_downspread(data_com); }
              if(fun_com==1&&fun_pc==0)
                {show_middle(data_com);  }
             // show_static(data_com);
             }
           if(fun_pc==1)
               {
               all_pcdata=pc_com();  //检测PC通信进程,
//结束则置PC通信结束标志位show_pcend=1
                          //同时返回数据通信数据中有效的数据个数
               }
            if(show_pcend==1&&fun_pc==1) //如果PC正在执行通信,且通信已完成,//则执行此段程序
                {
                 show_pcprocess(all_pcdata);  //显示PC通信的数据
                 }
         }
    // show_static(show_buffer1);    //测试用,临时语句
    }

/*=====================PC通信数据处理子程序=====================*/
/*
**************************************************************
**子程序入口参数:无
** 子程序功能:读取PC通信信息,截取其中的数据信息和控制信息
**************************************************************
*/

uint PC_COM(void)
     {
     uint i,endcount,allcount;
     uchar idata *p1;
     bit bdata sign;
     endcount=0;

     p1=show_pc[0][12]; //指向数据区,起始位10字节,空位2字节
     for(i=0;i<10;i++)
         {
            allcount++;
          if(*p1==0x0a)
              {
               endcount++;
               if(endcount==10)
                   {
                    i=10;
                    show_pcend=1; //计数标志位0x0a已计满10个,已到数据结尾,//PC通信结束
                    return(p1-&show_pc[0][12]);   // 返回有效显示数据的个数
                   }
               }
          else
               {
                 endcount=0;
                 i=0;
               }
           if(allcount==652)   //已经检测到数组的结尾,仍没有检测到完全的结束//标志位,则退出程序
                   {i=10;      // 数组总容量为662,若倒数第10个仍不是
//结束标志位0x0a,则可断定数据传输有误
                   fun_pc=0;}

         }

     }

/*
**********************************************************
**子程序入口:无
**子程序功能:初始化串口,设置波特率\开中断\串口工作模式
**********************************************************
*/
void uart_int(void)
{
TMOD = 0x20;     // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xfc;     // 波特率9600,TH1=252    公式:波特率=(1/n)*(振荡器
//频率/12*[256-TH1])
TL1 = 0xfc;
SCON = 0x50;     // 设定串行口工作1方式
PCON&= 0xef;     // 波特率不倍增
ES = 1;          //开串口中断描方式进行
ET1=0;           //禁止定时器1中断
PS=1;            //设置串口通信服务程序为高优先级
EA = 1;          //开总中断

}

/*
**********************************************************
**子程序入口:无
**子程序功能:串口中断处理函数
**********************************************************
*/
uart_interrupt() interrupt 4 using 2    //串口中断处理程序
       {
         if(RI)           //接引起的中断处理程序
             {
              show_pcpoint=SBUF;   //将数据送入PC通信数据数组show_pc
              RI=0;
              show_pccount++;
              show_pccom=1; //通信标志位
              show_pcend=0; //通信结束标志位清零
              }
        }

/*===============================================================*/
/*=======================显示子程序========================= ====*/
/*===============================================================*/
/*----------------------静态显示子程序--------------------------*/
/*
*****************************************************************
**子程序入口:显示数据的首地址,数据必须是二位数组的格式
**子程序功能:静态显示显示缓冲区show_buffer1中的内容,只能显示一次
******************************************************************
*/
#define DECODE_AD XBYTE[0xbfff] //显示电路行扫描译码电路的地址
void shift_165(uchar *value);    //函数声明
void show_static(storep1)
     uchar **storep1;
    {
     uint i,j,k=0;
     uchar numcode1=0;        //显示电路上面的138译码器
     uchar numcode2=0x10;     //显示电路下面的138译码器
     // storep1=show_buffer1;  //子程序不需要形参时,可以默认显示
//显示缓冲区show_buffer1中的内容

          for(i=0;i<8;i++)          //上下两译码器各运行一次
              {
               shift_165(storep1[k]);   //子程序通过74HC165实现8字节数据信息//并行输入串行输出
                                       //子程序入口:8字节数据的首地址
               k++;
               DECODE_AD=numcode1;   
               numcode1++;
              }
           for(i=0;i<8;i++)
           {
               shift_165(storep1[k]);
               k++;
               DECODE_AD=numcode2;    
               numcode2=numcode2+0x10;
              }

    }


/*---------------------------显示左移子程序-------------------------*/
/*
**********************************************************************
**子程序入口:需要左移显示的数据的首地址,不可以是显示缓冲区的地址,
**            数据必须是二维数组,字节数暂时定为16*8字节
**            num应为二位数组的列数
**子程序功能:显示内容左移,开始部分和结束部分以空白填充;
**            程序只能滚动显示一次
*************************************************************************
*/
void show_left(storep2,num)    
    uchar xdata **storep2;
    uint num;
    {
     uint i,j,m;
     num=num+8;          //此时num等于显示缓冲区需要更新的次数,8为屏的宽度
     for(i=0;i<16;i++)   //对两个显示缓冲区清零
        {
        for(j=0;j<8;j++)
            {
            show_buffer1[i][j]=0x00;
            show_buffer2[i][j]=0x00;
            }
        }
     
     TMOD=TMOD&&0xf0;        //计数器0工作在方式1, 
     TMOD=TMOD||0x01;        //声明:计数器0只有各个显示子程序可以使用,
//其他子程序只能使用计数器0或计数器2
     TH0=(65536-25000)/256;  //晶振12MHZ,计数25000次,1S中断40次
     TL0=(65536-25000)%256;
     EA=1 ;                //CPU开中断,定时器0开中断
     ET0=1;
     PT0=0;                //定时器0为中断低优先级
     TR0=1;                //启动定时器0

     showbuf_sign=0;        //程序开始时使用show_buffer1显示缓冲区
     for(m=0;m<num;m++)
         {
         if(showbuf_sign==0)  //正在显示显示缓冲区show_buffer1中的内容,
//则更新show_buffer2中的内容
             {
              for(i=0;i<=m;i++)   //滚动左移显示移动的第m次,需要移动m列数据
                       //需要移位的个数,如第一次仅需更新显示缓冲区的最后一位
                  {
                    for(j=0;j<16;j++)
                        {
                          if(m>num-8)
                               show_buffer2[j][7-(num-m)]=0x00;
                          else
                               show_buffer2[j][7-i]=storep2[j][i];
                        }
                  }
              }
          else
               {
                for(i=0;i<=m;i++)  //滚动左移显示移动的第m次,需要移动m列数据
                                  //需要移位的个数,如第一次仅需更新
//显示缓冲区的最后一位
                  {
                    for(j=0;j<16;j++)
                        {
                          if(m>num-8)
                               show_buffer1[j][7-(num-m)]=0x00;
                          else
                               show_buffer1[j][7-i]=storep2[j][i];
                        }
                  }
          //数据完成一次移动
          showbuf_sign=~showbuf_sign;  //显示区标志位取反,
//显示另外一个显示缓冲区中的内容
               }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -