国内销售专线:0755-83404646 / 0755-83570678 / 13923751240

MCU的引脚(单片机IO口)驱动段码液晶屏详解

发布来源:www.xyhlcd.com   发布时间:2022-3-26

在我们日常生活之中最普通的显示屏就是段码液晶屏了,因为它省成本低效果好,那么液晶屏怎么驱动它显示呢?1、MCU+LCD驱动,2、MCU 的普通IO口来驱动。

第一种方法是大多说人常用的方法在此不在讲解,今天重点讲一下第二种方法来驱动段码液晶屏显示。

首先、讲那些液晶屏最适合MCU 的普通IO口来驱动液晶屏呢?1、笔段少显示简单;2、LCD液晶的引脚少占用MCU的IO口不多;3、1/2 BAIS的LCD。这里对MCU的IO有点要求,就是IO必须要是三态,低、高、高阻。

其次、电路如何来设计?  段码液晶屏主要是有两种引脚,一是COM和二是SEG,切记液晶屏不像数码管那样可以用直流驱动,液晶屏是靠一定的波形,COM和SEG的相位差来显示的 。

段码液晶屏-电路设计

上图是COM引脚电路,     SEG引脚和单片机的IO直接相连就可以了。

段码液晶屏

下面我们以下图的逻辑变,结合上面的说明1/4 Duty,1/2 Bais为例子来介绍软件的写法
  
/******************************************************************
功能描述: MCU的IO直接驱动LCD测试程序
人:Zheng Qiu Sheng
本:1.0   
函数命: 主函数main()
完成时间:2022年3月16日                                   
*****************************************************************/
#include <STC8xxxx.h>
#include <stdio.h>
#include "gpio.h"
/*************  外部函数和变量声明 *****************/
#define  uint   unsigned int
#define  uchar  unsigned char
 uchar  ScanCoun,ZZ;
#define MAIN_Fosc 22118400L //定义主时钟
//COM  SEG 的管脚定义
sbit COM0=P3^7; //COM0
sbit COM1=P3^6; //COM1
sbit COM2=P3^5; //COM2
sbit COM3=P3^4; //COM3
sbit SEG0=P1^0; //SEG0
sbit SEG1=P1^1; //SEG1
sbit SEG2=P1^2; //SEG2
sbit SEG3=P1^3; //SEG3
sbit SEG4=P1^4; //SEG4
sbit SEG5=P1^5; //SEG5
sbit SEG6=P1^6; //SEG6
sbit SEG7=P1^7; //SEG7
sbit SEG8=P5^4; //SEG8
sbit SEG9=P5^5; //SEG9
unsigned char ScanCoun=0;                  //动态扫描显示位数计数器
//0~9的段码查询表
 unsigned char code seg_code[12]={0xfa,0x60,0xd6,0xf4,0x6c,0xbc,0xbe,0xe0,0xfe,0xfc,0x02,0x01};
   //0   1    2   3    4    5    6    7    8   9     - Dot
//unsigned char DisplayBuf[6]={5,4,3,2,1,0};   //6位数字对应的显示暂存
////段码缓冲区
uchar SegBuf[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//COM1、COM2、COM3、COM4对应的段码
/////////////延时 ms//////////////
void DelayMS(uint  hh)
{ unsigned char i,j;
for(i=0; i<250; i++)
for(j=0; j<200;j++)
             ;
}

/******************************************************************
公司:深圳市兴宇合电子有限公司
功能描述: MCU的IO直接驱动LCD测试程序
人:Zheng Qiu Sheng
函数命: 主函数IO_set()
完成时间:2022年3月16日                                   
*****************************************************************/
void IO_set()
{
P3n_open_drain(1<<4);//P3^4高阻    COM3
P3n_open_drain(1<<5);//P3^5高阻    COM2
P3n_open_drain(1<<6);//P3^6高阻    COM1
P3n_open_drain(1<<7);//P3^7高阻    COM0

P1M1=0x00; //P1口为输出
P1M0=0xFF;                  //SEG0--SEG07
P5n_push_pull(1<<4);//P5^4输出   SEG8
P5n_push_pull(1<<5);//P5^5输出   SEG9
}

/////////////////////////////////////////////////////////////////////
///************************ IO配置函数****************************//
/////////////////////////////////////////////////////////////////////
void GPIO_config(void) //(库函数定义)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
///////////////P1口seg输出/////////////
GPIO_InitStructure.Pin  = GPIO_Pin_All; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化
///////////////P54---P55口=seg输出/////////////
GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5; //指定要初始化的IO, GPIO_Pin_5 ~ GPIO_Pin_4
GPIO_InitStructure.Mode = GPIO_OUT_PP;             //指定IO的推挽输出方式,GPIO_PullUp
GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);         //初始化
///////////////P34-P37 口=COM高阻/////////////
GPIO_InitStructure.Pin  = GPIO_Pin_7 | GPIO_Pin_6|GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_2;;//指定要初始化的IO, GPIO_Pin_7 ~ GPIO_Pin_4
GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化 /// P3M1|=0x04 P3M0&=0xFB
 }  
/******************************************************************
公司:深圳市兴宇合电子有限公司
功能描述: SGES数据转换成对应的com数据BUFFER
人:Zheng Qiu Sheng
函数命: 主函数Seg2Seg()
完成时间:2022年3月16日                                   
*****************************************************************/
void Seg2Seg()
{
unsigned char SegXX;
SegBuf[0]=0x00;SegBuf[1]=0x00; //一定要设置为0
SegBuf[2]=0x00;SegBuf[3]=0x00;
SegBuf[4]=0x00;SegBuf[5]=0x00;
SegBuf[6]=0x00;SegBuf[7]=0x00;
//把4位数字的SEG放到COM1、COM2、COM3、COM4对应的SEGBUF[]里面
//LCD的管脚定义与LED不同,它不是一个COM对应一位数字,而是对应每个数字的一部分SEG
// 1   2   3   4   5   6   7   8                | 9  10  11  12                13 14 15 16   
// 1f  1a  2f  2a  3f  3a  4f  4a -- segBuf【0】| 5f  5a  6f  6a -- segBuf【4】        ---- COM0 
// 1g  1b  2g  2b  3g  3b  4g  4b -- segBuf【1】| 5g  5b  6g  6b -- segBuf【5】      ---- COM1 
// 1e  1c  2e  2c  3e  3c  4e  4c -- segBuf【2】| 5e  5c  6e  6c -- segBuf【6】    ---- COM2 
// 1h  1d  2h  2d  3h  3d  4h  4d -- segBuf【3】| 5h  5d  6h  6d -- segBuf【7】---- COM3

 SegXX=seg_code[DY1];  //第1位数字 
 if (SegXX&0x80) SegBuf[0]|=0x02; //1a
 if (SegXX&0x40) SegBuf[1]|=0x02; //1b
 if (SegXX&0x20) SegBuf[2]|=0x02; //1c
 if (SegXX&0x10) SegBuf[3]|=0x02; //1d
 if (SegXX&0x08) SegBuf[0]|=0x01; //1f
 if (SegXX&0x04) SegBuf[1]|=0x01; //1g
 if (SegXX&0x02) SegBuf[2]|=0x01; //1e
 //if (SegXX&0x01) SegBuf[3]|=0x01; //1h

 SegXX=seg_code[DY0];  //第2位数字
 if (SegXX&0x80) SegBuf[0]|=0x08; //2a
 if (SegXX&0x40) SegBuf[1]|=0x08; //2b
 if (SegXX&0x20) SegBuf[2]|=0x08; //2c
 if (SegXX&0x10) SegBuf[3]|=0x08; //2d

 if (SegXX&0x08) SegBuf[0]|=0x04; //2f
 if (SegXX&0x04) SegBuf[1]|=0x04; //2g
 if (SegXX&0x02) SegBuf[2]|=0x04; //2e
 if (SegXX&0x01) SegBuf[3]|=0x04; //2h


 SegXX=(seg_code[W2 ]|0x01);   //第3位数字
 if (SegXX&0x80) SegBuf[0]|=0x20;//3a
 if (SegXX&0x40) SegBuf[1]|=0x20;//3b
 if (SegXX&0x20) SegBuf[2]|=0x20;//3c
 if (SegXX&0x10) SegBuf[3]|=0x20;//3d
 if (SegXX&0x08) SegBuf[0]|=0x10;//3f
 if (SegXX&0x04) SegBuf[1]|=0x10;//3g
 if (SegXX&0x02) SegBuf[2]|=0x10;//3e
 if (SegXX&0x01) SegBuf[3]|=0x10;//3h

 SegXX=seg_code[W1];   //第4位数字
 if (SegXX&0x80) SegBuf[0]|=0x80;//4a
 if (SegXX&0x40) SegBuf[1]|=0x80;//4b
 if (SegXX&0x20) SegBuf[2]|=0x80;//4c
 if (SegXX&0x10) SegBuf[3]|=0x80;//4d
 if (SegXX&0x08) SegBuf[0]|=0x40;//4f
 if (SegXX&0x04) SegBuf[1]|=0x40;//4g
 if (SegXX&0x02) SegBuf[2]|=0x40;//4g
 if (SegXX&0x01) SegBuf[3]|=0x40;//4h

SegXX=(seg_code[W0]|0x01);  //第5位数字     
 if (SegXX&0x80) SegBuf[4]|=0x02; //5a
 if (SegXX&0x40) SegBuf[5]|=0x02; //5b
 if (SegXX&0x20) SegBuf[6]|=0x02; //5c
 if (SegXX&0x10) SegBuf[7]|=0x02; //5d

 if (SegXX&0x08) SegBuf[4]|=0x01; //5f
 if (SegXX&0x04) SegBuf[5]|=0x01; //5g
 if (SegXX&0x02) SegBuf[6]|=0x01; //5e
 if (SegXX&0x01) SegBuf[7]|=0x01; //5h
}
/*******************************************
/////////////定时器初始化////////////
********************************************/
InitInterResource()
{
IE=0;       //关全部中断
TCON=0;     //清全部中断请求
IP=0;       //清中断优先级   
TMOD=0x01;  //T0工作方式1(16位定时器)
TH0=0xEC;   //T0定时器辅初值
TL0=0x78;
TR0=1;      //允许T0定时
ET0=1;      //允许T0中断
EA=0;       //关全局中断     
}
/******************************************************************
公司:深圳市兴宇合电子有限公司
功能描述: 主函数测试程序
人:Zheng Qiu Sheng
函数命: 主函数 main()
完成时间:2022年3月16日                                   
*****************************************************************/
void main()
 { 
DelayMS(20);
IO_set();
InitInterResource();
  EA=1;         //开全局中断
  while(1) ;


/******************************************************************
公司:深圳市兴宇合电子有限公司
功能描述: 定时器0中断服务程序  5ms定时器,8字数码管动态显示驱动
人:Zheng Qiu Sheng
函数命: 主函数 main()
完成时间:2022年3月16日                                   
********************************************************************/
void tmr0_p(void) interrupt 1
 {
   Seg2Seg();
   switch(ScanCoun)                //动态扫描显示
    { 
      case 0:                        //COM0正向驱动
Tdat1=SegBuf[0];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=SegBuf[4];
   SEG8 = (bit)(Tdat2&0x01);
   SEG9 = (bit)(Tdat2&0x02);
         COM0=0;
         P3n_push_pull(1<<7);//P3^7输出 COM0
         P3n_open_drain(1<<4);//P3^4高阻 COM3
       P3n_open_drain(1<<5);//P3^5高阻 COM2
   P3n_open_drain(1<<6);//P3^6高阻 COM0
         break;
          
     case 1:                        //COM0反向驱动
Tdat1=~SegBuf[0];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=~SegBuf[4];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);
          COM0=1;                      
         P3n_push_pull(1<<7);//P3^7输出 COM0
         P3n_open_drain(1<<4);//P3^4高阻 COM3
       P3n_open_drain(1<<5);//P3^5高阻 COM2
   P3n_open_drain(1<<6);//P3^6高阻 COM0
          break;
/////////////////////////////////////////////////////////                  
     case 2:                       //COM1正向驱动
       Tdat1=SegBuf[1];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=SegBuf[5];
    SEG8 = (bit)(Tdat2&0x01);
    SEG9 = (bit)(Tdat2&0x02);
          COM1=0;       
         P3n_push_pull(1<<6);//P3^6输出  COM1
         P3n_open_drain(1<<4);//P3^4高阻 COM3
        P3n_open_drain(1<<5);//P3^5高阻 COM2
    P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;
          
     case 3:                       //COM1反向驱动 
       Tdat1=~SegBuf[1];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=~SegBuf[5];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);
         COM1=1;                  
         P3n_push_pull(1<<6);//P3^6输出  COM1
         P3n_open_drain(1<<4);//P3^4高阻 COM3
        P3n_open_drain(1<<5);//P3^5高阻 COM2
    P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;
//////////////////////////////////////////////////////////////// 
      case 4:                       //COM2正向驱动
       Tdat1=SegBuf[2];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=SegBuf[6];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);     
          COM2=0;                     
         P3n_push_pull(1<<5);//P3^5输出  COM2
         P3n_open_drain(1<<4);//P3^4高阻 COM3
        P3n_open_drain(1<<6);//P3^6高阻 COM1
    P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;    
      case 5:                       //COM2反向驱动
        Tdat1=~SegBuf[2];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=~SegBuf[6];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);    
          COM2=1;         
         P3n_push_pull(1<<5);//P3^5输出  COM2
         P3n_open_drain(1<<4);//P3^4高阻 COM3
        P3n_open_drain(1<<6);//P3^6高阻 COM1
     P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;  
////////////////////////////////////////////////////////////////    
     case 6:                       //COM3正向驱动
       Tdat1=SegBuf[3];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=SegBuf[7];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);
          COM3=0;                      
         P3n_push_pull(1<<4);//P3^4输出  COM3
         P3n_open_drain(1<<5);//P3^5高阻 COM2
      P3n_open_drain(1<<6);//P3^6高阻 COM1
    P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;  
     case 7:                       //COM3反向驱动 
       Tdat1=~SegBuf[3];
    SEG0 = (bit)(Tdat1&0x01);  
SEG1 = (bit)(Tdat1&0x02); 
SEG2 = (bit)(Tdat1&0x04);  
SEG3 = (bit)(Tdat1&0x08);
    SEG4 = (bit)(Tdat1&0x10);  
SEG5 = (bit)(Tdat1&0x20);  
SEG6 = (bit)(Tdat1&0x40);  
SEG7 = (bit)(Tdat1&0x80); 
Tdat2=~SegBuf[7];
SEG8 = (bit)(Tdat2&0x01);
SEG9 = (bit)(Tdat2&0x02);
          COM3=1;                   
         P3n_push_pull(1<<4);//P3^4输出  COM3
         P3n_open_drain(1<<5);//P3^5高阻 COM2
      P3n_open_drain(1<<6);//P3^6高阻 COM1
   P3n_open_drain(1<<7);//P3^7高阻 COM0
          break;  
////////////////////////////////////////////////////////////////////
       }
     ScanCoun++;       //下一位
     if(ScanCoun>7) 
    ScanCoun=0;
 
      TL0=0x78;     //重新定时5ms
      TH0=0xec;
  ZZ++;
  EA=1;      
  }

显示正常的情况下,经过测试:COM脚输出的波形如下图:

段码液晶屏MCU引脚

所以在用MCU直接驱动LCD时,尽量去选择1/2BAIS的LCD, 很容易通过IO口模拟出上述波形,这并不是唯一的方式,还有其它的波形也能实现,在这里就不一一解释了。在只是个人的一得之见,在此,抛砖引玉,希望更多人把自己的经验分享出来,帮助那些需要帮助的人,减少他们的不解和困惑。

“赠人玫瑰 ,手留余香” 

 “质量第一、精益求精、追求卓越”之理念是兴宇合电子有限公司          始终如一的郑重承诺。对于不明白或者有疑问的问题请拨打电话:

0755-83404646 / 0755-83570678 / 13923751240
Copyright© 2001-2021 深圳市兴宇合电子有限公司 [拥有20年经验的LCD显示屏,液晶屏,液晶模组,液晶模块,LED背光源,LED数码管,深圳LCD/LCM液晶模组生产厂家]
国内销售专线:0755-83570678 前台电话:0755-83404646 大客户专线:13923751240 地址:深圳市宝安区石岩镇宏发工业园16栋5楼
粤ICP备11030976号   网站地图