whoyzf 发表于 2024-11-5 16:03:26

段码LCD驱动代码,简洁版。0.5s增加数字加1

本帖最后由 whoyzf 于 2024-11-5 18:10 编辑






/*********************************************************/
#define MAIN_Fosc                11059200L      //定义主时钟

#include      "STC8H4K64TL.h"


/*************      功能说明      **************
888e
硬件连接及LCD_buff
                                        SEG22      SEG21      SEG20      SEG19      SEG18      SEG17               
12      3         4                10         9         8         7         6         5               
                        COM0                3A      4A      2A      4D      1A      4G                C0SEGV2
                COM1                        3B      3F      2B      2F      1B      1F                C1SEGV2
      COM2                              3C      3G      2C      2G      1C      1G                C2SEGV2
COM3                                        3D      3E      2D      2E      1D      1E                C1SEGV2



******************************************/

/*************      本地常量声明      **************/


/*************      本地IO定义      **************/


/*************      本地变量声明      **************/

bit      B_500mS;      // 0.5秒时隙标志
bit      B_20ms;                // 20ms时隙标志
u8      OpTime;                // 此变量非0时, 不睡眠, 连续运行程序(本例串口唤醒后连续运行5秒, 以便正确接收串口数据)


u8 uc0_5sflag=0;

/*************      本地函数声明      **************/

u8                Timer0_Config(u32 reload);      //reload值是主时钟周期数
void      LCD_config(void);

void      ReadKey(void);      //50ms call

unsigned char segmentCodes = {
    0x3F, // 0   - a-g: 00011111
    0x06, // 1   - a-g: 00000110
    0x5B, // 2   - a-g: 01011011
    0x4F, // 3   - a-g: 01001111
    0x66, // 4   - a-g: 01100110
    0x6D, // 5   - a-g: 01101101
    0x7d, // 6   - a-g: 01111101
    0x07, // 7   - a-g: 00000111
    0x7F, // 8   - a-g: 01111111
    0x6f// 9   - a-g: 01101111
};

/****************** 对第1~5数字装载显示函数 ***************************/
u8 code t_display[]={                                                //标准字库
//         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
      0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black         -   H    J         K          L         N      o   P         U   t    G    Q    r   M    y
      0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};



void displayThreeDigits(unsigned int number) ;
void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units);

// 函数用于显示一个三位数
void displayThreeDigits(unsigned int number) {
    unsigned char hundreds ;      // 百位
    unsigned char tens ;       // 十位
    unsigned char units ;            // 个位


      hundreds = number / 100;      // 百位
      tens = (number / 10) % 10;       // 十位
      units = number % 10;            // 个位
      
    // 初始化寄存器
    C0SEGV2 = 0x00;
    C1SEGV2 = 0x00;
    C2SEGV2 = 0x00;
    C3SEGV2 = 0x00;

updateSegments(hundreds,tens,units);
}

// 函数用于更新段寄存器
void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units) {
      
    // 左起第一位,控制1A到1G位
    if ((segmentCodes & 0x01) == 0) C0SEGV2 &= 0xfb; else C0SEGV2 |= 0x04; // 1A位是0,或者1
    if ((segmentCodes & 0x02) == 0) C1SEGV2 &= 0xfb; else C1SEGV2 |= 0x04; // 1B位是0,或者1
    if ((segmentCodes & 0x04) == 0) C2SEGV2 &= 0xfb; else C2SEGV2 |= 0x04; // 1C位是0,或者1
    if ((segmentCodes & 0x08) == 0) C3SEGV2 &= 0xfb; else C3SEGV2 |= 0x04; // 1D位是0,或者1
    if ((segmentCodes & 0x10) == 0) C3SEGV2 &= 0xfd; else C3SEGV2 |= 0x02; // 1E位是0,或者1
    if ((segmentCodes & 0x20) == 0) C1SEGV2 &= 0xfd; else C1SEGV2 |= 0x02; // 1F位是0,或者1
    if ((segmentCodes & 0x40) == 0) C2SEGV2 &= 0xfd; else C2SEGV2 |= 0x02; // 1G位是0,或者1

    // 左起第二位,控制2A到2G位
    if ((segmentCodes & 0x01) == 0) C0SEGV2 &= 0xef; else C0SEGV2 |= 0x10;
    if ((segmentCodes & 0x02) == 0) C1SEGV2 &= 0xef; else C1SEGV2 |= 0x10;
    if ((segmentCodes & 0x04) == 0) C2SEGV2 &= 0xef; else C2SEGV2 |= 0x10;
    if ((segmentCodes & 0x08) == 0) C3SEGV2 &= 0xef; else C3SEGV2 |= 0x10;
    if ((segmentCodes & 0x10) == 0) C3SEGV2 &= 0xf7; else C3SEGV2 |= 0x08;
    if ((segmentCodes & 0x20) == 0) C1SEGV2 &= 0xf7; else C1SEGV2 |= 0x08;
    if ((segmentCodes & 0x40) == 0) C2SEGV2 &= 0xf7; else C2SEGV2 |= 0x08;

    // 左起第三位,控制3A到3G位
    if ((segmentCodes & 0x01) == 0) C0SEGV2 &= 0xbf; else C0SEGV2 |= 0x40;
    if ((segmentCodes & 0x02) == 0) C1SEGV2 &= 0xbf; else C1SEGV2 |= 0x40;
    if ((segmentCodes & 0x04) == 0) C2SEGV2 &= 0xbf; else C2SEGV2 |= 0x40;
    if ((segmentCodes & 0x08) == 0) C3SEGV2 &= 0xbf; else C3SEGV2 |= 0x40;
    if ((segmentCodes & 0x10) == 0) C3SEGV2 &= 0xdf; else C3SEGV2 |= 0x20;
    if ((segmentCodes & 0x20) == 0) C1SEGV2 &= 0xdf; else C1SEGV2 |= 0x20;
    if ((segmentCodes & 0x40) == 0) C2SEGV2 &= 0xdf; else C2SEGV2 |= 0x20;
               
}



void main(void)
{
      unsigned char ucshow=0,i=0;
      P0M1 = 0;      P0M0 = 0;
      P1M1 = 0;      P1M0 = 0;
      P2M1 = 0;      P2M0 = 0;
      P3M1 = 0X80;      P3M0 = 0;
      P4M1 = 0;      P4M0 = 0;
      P5M1 = 0;      P5M0 = 0;
      P6M1 = 0;      P6M0 = 0;
      P7M1 = 0;      P7M0 = 0;

      Timer0_Config(MAIN_Fosc / 50);      //reload值是主时钟周期数,(中断频率, 50次/秒)

      EA = 1;
P37=0;
      
//      OpTime= 0;
//      DisMode = 0;
//         RTC_config();
      LCD_config();
while(1)
{
if(uc0_5sflag==1)
{
uc0_5sflag=0;
      
ucshow++;

//      COMLENM=ucshow;
//      COMLENL=(255-ucshow);
//      C0SEGV2=ucshow;
//      C1SEGV2=ucshow;
//      C3SEGV2=ucshow;
C0SEGV2 = 0x00;      
      C1SEGV2 = 0x00;      
      C2SEGV2 = 0x00;      
      C3SEGV2 = 0x00;      

      // 设置C0SEGV2, C1SEGV2, C2SEGV2, C3SEGV2寄存器
//      C0SEGV2 = segValues;
//      C1SEGV2 = segValues;
//      C2SEGV2 = segValues;
//      C3SEGV2 = segValues;
//i=8;
/*      
//左起第一位,      
if ((segmentCodes & 0x01) == 0)   C0SEGV2 &= 0xfb; // 1A位是0
          else                           C0SEGV2 |= 0x04; // 1A位是1   
if ((segmentCodes & 0x02) == 0)   C1SEGV2 &= 0xfb; // 1B位是0
          else                           C1SEGV2 |= 0x04; // 1B位是1   
if ((segmentCodes & 0x04) == 0)   C2SEGV2 &= 0xfb; // 1C位是0
          else                           C2SEGV2 |= 0x04; // 1C位是1   
if ((segmentCodes & 0x08) == 0)   C3SEGV2 &= 0xfb; // 1D位是0
          else                           C3SEGV2 |= 0x04; // 1D位是1   
               
if ((segmentCodes & 0x10) == 0)   C3SEGV2 &= 0xfd; // 1E位是0
          else                           C3SEGV2 |= 0x02; // 1E位是1   
if ((segmentCodes & 0x20) == 0)   C1SEGV2 &= 0xfd; // 1F位是0
          else                           C1SEGV2 |= 0x02; // 1F位是1   
if ((segmentCodes & 0x40) == 0)   C2SEGV2 &= 0xfd; // 1G位是0
          else                           C2SEGV2 |= 0x02; // 1G位是1   
//if ((segmentCodes & 0x08) == 0)                  // 1H位是0
//          else                                              // 1H位是1   

//左起第二位,      
if ((segmentCodes & 0x01) == 0)   C0SEGV2 &= 0xef; // 2A位是0
          else                           C0SEGV2 |= 0x10; // 2A位是1   
if ((segmentCodes & 0x02) == 0)   C1SEGV2 &= 0xef; // 2B位是0
          else                           C1SEGV2 |= 0x10; // 2B位是1   
if ((segmentCodes & 0x04) == 0)   C2SEGV2 &= 0xef; // 2C位是0
          else                           C2SEGV2 |= 0x10; // 2C位是1   
if ((segmentCodes & 0x08) == 0)   C3SEGV2 &= 0xef; // 2D位是0
          else                           C3SEGV2 |= 0x10; // 2D位是1   
                                                                                                                                                                                                                                 
if ((segmentCodes & 0x10) == 0)   C3SEGV2 &= 0xf7; // 2E位是0
          else                           C3SEGV2 |= 0x08; // 2E位是1   
if ((segmentCodes & 0x20) == 0)   C1SEGV2 &= 0xf7; // 2F位是0
          else                           C1SEGV2 |= 0x08; // 2F位是1   
if ((segmentCodes & 0x40) == 0)   C2SEGV2 &= 0xf7; // 2G位是0
          else                           C2SEGV2 |= 0x08; // 2G位是1   
//if ((segmentCodes & 0x08) == 0)                  // 1H位是0
//          else   

//左起第二位,      
if ((segmentCodes & 0x01) == 0)   C0SEGV2 &= 0xbf; // 3A位是0
          else                           C0SEGV2 |= 0x40; // 3A位是1   
if ((segmentCodes & 0x02) == 0)   C1SEGV2 &= 0xbf; // 3B位是0
          else                           C1SEGV2 |= 0x40; // 3B位是1   
if ((segmentCodes & 0x04) == 0)   C2SEGV2 &= 0xbf; // 3C位是0
          else                           C2SEGV2 |= 0x40; // 3C位是1   
if ((segmentCodes & 0x08) == 0)   C3SEGV2 &= 0xbf; // 3D位是0
          else                           C3SEGV2 |= 0x40; // 3D位是1   
                                                                                                                                                                                                                                 
if ((segmentCodes & 0x10) == 0)   C3SEGV2 &= 0xdf; // 3E位是0
          else                           C3SEGV2 |= 0x20; // 3E位是1   
if ((segmentCodes & 0x20) == 0)   C1SEGV2 &= 0xdf; // 3F位是0
          else                           C1SEGV2 |= 0x20; // 3F位是1   
if ((segmentCodes & 0x40) == 0)   C2SEGV2 &= 0xdf; // 3G位是0
          else                           C2SEGV2 |= 0x20; // 3G位是1   
//if ((segmentCodes & 0x08) == 0)                  // 1H位是0
//          else   

*/
displayThreeDigits(i);



                        
                i++;      
if(i>250)i=0;            

      
      
      
      if(ucshow>=0xFF)
      {
         ucshow=0x00;
//                        X32KCR = 0x00;
         }
}



}

      
}


/********************* INT0中断函数 *************************/
void Ext_INT0 (void) interrupt 0
{
      OpTime = 6;
}



/********************** LCD配置函数 *****************************/
void      LCD_config(void)
{
//      u8      i;

      P_SW2 |= 0x80;                // SFR enable
      
//      X32KCR = 0x80 + 0x40;                //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
//P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
//      P1IE = ~0xc0;                              //P1.6 P1.7关闭数字输入功能
//      X32KCR = 0x80;
      
      LCDCFG= 0xc0 + 7;      // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
//      LCDCFG|=0x07;
      
      //      X32KCR = 0x80 + 0x40;                //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
      P1IE = ~0xc0;                              //P1.6 P1.7关闭数字输入功能
      X32KCR = 0x80;
      
      
      
      DBLEN   = 0;                // 设置LCD显示时的死区时间长度, 取值0~7.
      COMLENH      = 0;                // COM时间长度设置 高字节COMLEN,一共20bit.
      COMLENM      = 0;                // COM时间长度设置 中字节COMLEN      LCD刷新率 = LCD时钟频率 / ((DBLEN+COMLEN+1) *2 * COM数)
      COMLENL      = 65;                // COM时间长度设置 低字节COMLEN      LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
      BLINKRATE = 60;                // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE Hz

      COMON= 0x0f;                // COM使能寄存器
      SEGON1 = 0x00;                // SEG线使能寄存器1, SEG7~SEG0
      SEGON2 = 0x00;                // SEG线使能寄存器2, SEG15~SEG8
      SEGON3 = 0x7e;                // SEG线使能寄存器3, SEG23~SEG16
      SEGON4 = 0x00;                // SEG线使能寄存器4, SEG31~SEG24
      SEGON5 = 0x00;                // SEG线使能寄存器5, SEG39~SEG32
      
//      P5n_pure_input(0x03);      //P5.0 P5.1 设置为高阻输入      COM0 COM1
//      P3n_pure_input(0x60);      //P3.5 P3.6 设置为高阻输入      COM2 COM3
//    P3M0 = 0x00; P3M1 = 0xFF;
//    P5M0 = 0x00; P5M1 = 0xFF;

//    P3DR = 0x00;
//    P0DR = 0x00;


//      LCDCFG2 = 0x0f;                        // SEG0~3切换到P7.7~7.4
//      P7n_pure_input(0xf0);      //P7.7~P7.4 设置为高阻输入      SEG0~SEG3 (对应P7.7~7.4)
//      P4n_pure_input(0x80);      //P4.7      设置为高阻输入      SEG4
//      P1n_pure_input(0x03);      //P1.1~P1.0 设置为高阻输入      SEG5 SEG6       (对应P1.1 P1.0)
//      P0n_pure_input(0x60);      //P0.7~P0.5 设置为高阻输入      SEG7 SEG8 SEG9(对应P0.7 P0.6 P0.5)
//      P5n_pure_input(0x0C);      //P5.3 P5.2 设置为高阻输入      SEG10 SEG11   (对应P5.3 P5.2)
//      P0n_pure_input(0x1f);      //P0.4~P0.0 设置为高阻输入      SEG12~SEG16(对应P0.4 ~ 0.0)
//      P4n_pure_input(0x60);      //P4.6 P4.5 设置为高阻输入      SEG17 SEG18
//      P2n_pure_input(0xF0);      //P2.7~P2.0 设置为高阻输入      SEG19~SEG26(对应P2.7~2.0)
//    P2M0 = 0x00; P2M1 = 0xFF;
//    P4M0 = 0x00; P4M1 = 0xFF;
//          P2DR = 0x00;
//    P4DR = 0x00;
//      P4n_pure_input(0x1e);      //P4.4~P4.1 设置为高阻输入      SEG27~SEG30(对应P4.4~4.1)
//      P3n_pure_input(0x80);      //P3.7      设置为高阻输入      SEG31
//      P7n_pure_input(0x0f);      //P7.3~P7.0 设置为高阻输入      SEG32~SEG35(对应P7.3~7.0)
//      P6n_pure_input(0x0f);      //P6.0~P6.3 设置为高阻输入      SEG36~SEG39(对应P6.3~6.0)

      
      C0SEGV2 = 0x00;      
      C1SEGV2 = 0x00;      
      C2SEGV2 = 0x00;      
      C3SEGV2 = 0x00;               
      

      LCDCR = (0<<1) + 1;      // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式.+0:禁止LCD模块,+1:允许LCD模块.
      
}



//========================================================================
// 函数:u8      Timer0_Config(u32 reload)
// 描述: timer0初始化函数.
// 参数: reload: 重装值.
// 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-3-5
//========================================================================
u8      Timer0_Config(u32 reload)      //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
      TR0 = 0;      //停止计数

      if(reload >= (65536UL * 12))      return 1;      //值过大, 返回错误
      if(reload < 65536UL)      AUXR |= 0x80;                //1T mode
      else
      {
                AUXR &= ~0x80;      //12T mode
                reload = reload / 12;
      }
      reload = 65536UL - reload;
      TH0 = (u8)(reload >> 8);
      TL0 = (u8)(reload);

      ET0 = 1;      //允许中断
      TMOD = (TMOD & ~0x03) | 0;      //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
      TR0 = 1;                        //开始运行
      return 0;
}

//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2016-5-12
//========================================================================
void timer0_ISR (void) interrupt TIMER0_VECTOR
{
      static u8 i;
      
   B_20ms = 1;      //20ms时隙标志
      
      i++;
      if(i>=5)
      {
                i=0;
    uc0_5sflag=1;
//          P37=!P37;
      }
      
}






页: [1]
查看完整版本: 段码LCD驱动代码,简洁版。0.5s增加数字加1