基於STC89C52單片機的點陣屏(廣告牌)設計(含Proteus仿真)

一、所需元器件

  1. 52單片機芯片 X 1;
  2. 8*8 LED點陣 X 32;
  3. 74HC595位移寄存器 X 16 ;
  4. 74HC154譯碼器 X 1;
  5. 74HC04 X 4;
  6. PNP三極管 X 16;
  7. 電阻電容若干。

二、STC89C52

STC89C52是STC公司生產的一種低功耗、高性能CMOS8位微控制器,具有 8K 在系統可編程Flash存儲器。STC89C52使用經典的MCS-51內核,但做了很多的改進使得芯片具有傳統51單片機不具備的功能。在單芯片上,擁有靈巧的8 位CPU 和在系統可編程Flash,使得STC89C52爲衆多嵌入式控制應用系統提供高靈活、超有效的解決方案。

52單片機最小系統原理圖:

在這裏插入圖片描述

三、點陣

LED點陣屏通過LED(發光二極管)組成,以燈珠亮滅來顯示文字、圖片、動畫、視頻等,是各部分組件都模塊化的顯示器件,通常由顯示模塊、控制系統及電源系統組成。

8X8點陣實物圖

在這裏插入圖片描述

8X8點陣原理圖

在這裏插入圖片描述

四、點陣驅動原理

列驅動

74HC595具有8位移位寄存器和一個存儲器,三態輸出功能。 移位寄存器和存儲器有相互獨立的時鐘。數據在SH_cp(移位寄存器時鐘輸入)的上升沿輸入到移位寄存器中,在ST_cp(存儲器時鐘輸入)的上升沿輸入到存儲寄存器中去。如果兩個時鐘連在一起,則移位寄存器總是比存儲寄存器早一個脈衝。移位寄存器有一個串行移位輸入(Ds),和一個串行輸出(Q7’),和一個異步的低電平復位,存儲寄存器有一個並行8位的,具備三態的總線輸出,當使能OE時(爲低電平),存儲寄存器的數據輸出到總線。8位串行輸入/輸出或者並行輸出移位寄存器,具有高阻關斷狀態。
在這裏插入圖片描述

行驅動

74HC154是一款高速CMOS器件,譯碼器可接受4位高有效二進制地址輸入,並提供16個互斥的低有效輸出。74HC154可充當一個1-16的多路分配器。
引腳1-11 13-17 :輸出端。(outputs (active LOW))
引腳12:Gnd電源地 (ground (0 V))
引腳18-19:使能輸入端、低電平有效 (enable inputs (active LOW))
引腳20-23:地址輸入端 (address inputs)
引腳24:VCC電源正 (positive supply voltage)
在這裏插入圖片描述

行驅動電路原理圖

在這裏插入圖片描述

五、PCB layout圖

PCB 2維圖展示

在這裏插入圖片描述

PCB 3維圖展示 在這裏插入圖片描述

六、Proteus 仿真

仿真所需元器件

在這裏插入圖片描述

仿真圖單片機部分

在這裏插入圖片描述

仿真圖點陣屏部分

在這裏插入圖片描述

七、C程序代碼

#include<REG51.h>
#define uchar unsigned char
#define uint unsigned int
uchar speed=8;  //移動速度
//595芯片引腳
sbit ST=P3^5;
sbit SH=P3^6;
sbit DATA=P3^7;
//154芯片引腳
sbit EN=P2^4;
//按鍵
sbit K1=P1^0;
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;
sbit K5=P1^4;
sbit K6=P1^5;
//按鍵觸發標誌位
bit LeftFlag;
bit RightFlag;
bit UpFlag;
bit DownFlag;
bit ZJ1Flag;
bit ZJ2Flag=1;  //開始顯示模式
//延時函數
void delay(uchar ms)
{
 uchar y;
 for(;ms>0;ms--)
  for(y=120;y>0;y--);
}
uchar code hanzi[][32]={
}void SendByte(uchar a)   //向595發送字節
{
 uchar byte,i;
 byte=~a;
 for(i=0;i<8;i++)
 {
  SH=0;
  if(byte&0X80)
  DATA=1;
  else
  DATA=0;
  SH=1;
  byte<<=1;
 }
}
void LeftDisplay(void) //左移
{
 uchar i,j,scan,k;
 for(i=0;i<16;i++) //16個漢字
 {
  if(LeftFlag==1)  
  {
   for(k=0;k<speed;k++) //移動速度
   {
    scan=0;      //154譯碼
    if(LeftFlag==1) //
    {
     for(j=0;j<31;j+=2)
     {
      ST=0;
      SendByte(hanzi[i+7][j+1]);    //發送數據
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      ST=1; //一個上升沿送數據
      EN=0; 
      P2=scan;
      delay(4);
      EN=1;
      scan++;
     }
    }
    else
    break;
   }
   for(k=0;k<speed;k++)
   {
    scan=0;
    if(LeftFlag==1)
    {
     for(j=0;j<31;j+=2)
     {
      ST=0;
      SendByte(hanzi[i+8][j]);  //另外半個字
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      
      
      SendByte(hanzi[i+4][j]); 
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      ST=1;
      EN=0;
      P2=scan;
      delay(4);
      EN=1;
      scan++;
     }
    }
    else
    break;
   }
  }
  else
  break;
 }
}
void RightDisplay(void) //右移
{
 uchar i,j,k,scan;
 for(i=0;i<16;i++) 
 {
  if(RightFlag==1)
  {
  for(k=0;k<speed;k++)
   {
    scan=0;
    if(RightFlag==1)
    {
     for(j=0;j<31;j+=2)
     {
      ST=0;
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
     }
    }
    else
    break;
   }
   for(k=0;k<speed;k++)
   {
    scan=0;
    if(RightFlag==1)
    {
    for(j=0;j<31;j+=2)
     {
      ST=0;
      SendByte(hanzi[i][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+8][j+1]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
      }
    }
    else
    break;
   }
  }
  else
  break;
 }
}
void UpDisplay(void) //上移
{
 uchar i,j,k,scan;
 char temp=0;
 for(i=0;i<16;)  //16個字
 {
 if(UpFlag==1)
  {
   for(k=0;k<speed;k++)
   {
    scan=15-temp; //譯碼
    if(UpFlag==1)
    {
     for(j=0;j<2*temp+1;j+=2)
     {
     ST=0;
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
      }
    }
    else
    break;
   }
   temp++;  //控制譯碼
   if(temp==16) 
   {
    temp=0; //temp復位
    i+=8; //顯示下四個字
   }
  }
  else
  break;
 }
}
void DownDisplay(void) //下移
{
uchar i,j,k,scan;
 char temp=30;
 for(i=0;i<16;)
 {
  if(DownFlag==1)
  {
   for(k=0;k<speed;k++)
   {
    scan=0;
    if(DownFlag==1)
    {
     for(j=temp;j<31;j+=2) //開始j=30
     {
     ST=0;
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
     }
    }
    else
    break;
   }
   temp-=2;
   if(temp==-2) 
   {
    temp=30;
    i+=8;
   }
  }
  else
  break;
 }
}
void ZJDisplay1(void) //
{
 uchar i,j,k,scan,temp;
 for(i=0;i<16;)
 {
  if(ZJ1Flag==1)
  {
   for(k=0;k<speed;k++)
   {
    scan=0;
    if(ZJ1Flag==1)
    {
     for(j=0;j<2*temp+1;j+=2)
     {
     ST=0;
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
     }
    }
    else
    break;
   }
   temp++;
   if(temp==16)
   {
    temp=0;
    i+=8;
   }
   }
  else
  break;
 }
}
void ZJDisplay2(void) //
{
uchar i,j,k,scan,z=0;
 char temp=30;
 for(i=0;i<16;)
 {
  if(ZJ2Flag==1)
  {
   for(k=0;k<speed;k++)
   {
    scan=15-z;  //z譯碼控制
    if(ZJ2Flag==1)
    {
     for(j=temp;j<31;j+=2)
     {
     ST=0;
      SendByte(hanzi[i+7][j+1]);
      SendByte(hanzi[i+7][j]);
      SendByte(hanzi[i+6][j+1]);
      SendByte(hanzi[i+6][j]);
      SendByte(hanzi[i+5][j+1]);
      SendByte(hanzi[i+5][j]);
      SendByte(hanzi[i+4][j+1]);
      SendByte(hanzi[i+4][j]);
      SendByte(hanzi[i+3][j+1]);
      SendByte(hanzi[i+3][j]);
      SendByte(hanzi[i+2][j+1]);
      SendByte(hanzi[i+2][j]);
      SendByte(hanzi[i+1][j+1]);
      SendByte(hanzi[i+1][j]);
      SendByte(hanzi[i][j+1]);
      SendByte(hanzi[i][j]);
      ST=1;
      EN=0;
      P2=scan;
      delay(5);
      EN=1;
      scan++;
      }
    }
    else
    break;
   }
   temp-=2;
   z++;
   if(temp==-2)
   {
    temp=30;
    i+=8;
    z=0; 
   }
  }
  else
  break;
  }
  }
  void ClearFlag(void) //清標誌位
{
 LeftFlag=0;
 RightFlag=0;
 UpFlag=0;
 DownFlag=0;
 ZJ1Flag=0;
 ZJ2Flag=0;
}
void KeyScan(void)
{
 if(K1==0)
 {
  delay(10);
  if(K1==0)
  {
   while(!K1);
   ClearFlag();
   LeftFlag=1;
  }
 }
 if(K2==0)
 {
  delay(10);
  if(K2==0)
  {
   while(!K2);
   ClearFlag();
   RightFlag=1;
  }
 }
 if(K3==0)
 {
  delay(10);
  if(K3==0)
  {
   while(!K3);
   ClearFlag();
   UpFlag=1;
  }
 }
 if(K4==0)
 {
  delay(10);
  if(K4==0)
  {
   while(!K4);
   ClearFlag();
   DownFlag=1;
  }
 }
 if(K5==0)
 {
  delay(10);
  if(K5==0)
  {
   while(!K5);
   ClearFlag();
   ZJ1Flag=1;
  }
 }
 if(K6==0)
 {
  delay(10);
  if(K6==0)
  {
   while(!K6);
   ClearFlag();
   ZJ2Flag=1;
  }
 }
}
void main(void)
{
 TMOD=0X01;
 TH0=(65535-1000)/256;
 TL0=(65535-1000)%256;
 ET0=1;
 EA=1;
 TR0=1;
 while(1)
 {
  if(LeftFlag==1)
  {
   LeftDisplay();
  }
  if(RightFlag==1)
  {
   RightDisplay();
  }
  if(UpFlag==1)
  {
   UpDisplay();
  }
  if(DownFlag==1)
  {
   DownDisplay();
  }
  if(ZJ1Flag==1)
  {
   ZJDisplay1();
  }
  if(ZJ2Flag==1)
  {
   ZJDisplay2();
  }
 }
}
void timer0(void) interrupt 1    //刷新 按鍵
{
 TH0=(65535-1000)/256;
 TL0=(65535-1000)%256;
 KeyScan();
}

分享決定高度,學習拉開差距

作爲學習者給大家分享自己完成的此作品,希望對大家有幫助,當然上文若有不妥之處,歡迎指正。

歡迎大家留言,批評指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章