找回密码
 立即注册
查看: 44|回复: 0

40-LCD1602显示程序-硬件M6800并行接口驱动,STC32G144K246实验箱演示程序

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:78
  • 最近打卡:2026-07-21 13:27:09
已绑定手机

231

主题

168

回帖

1069

积分

版主

积分
1069
发表于 2026-7-2 13:45:23 | 显示全部楼层 |阅读模式
40-LCD1602显示程序-硬件M6800并行接口驱动,STC32G144K246实验箱演示程序
主程序main.C代码如下(汇编版本在附件中):

/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/



/*************  功能说明    **************

本例程基于STC32G144K246为主控芯片的实验箱进行编写测试。

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

硬件LCM M6800接口驱动LCD1602字符屏.

显示效果为: LCD显示时间.

第一行显示 ---Clock demo---
第二行显示     12-00-00

LCD1602字符屏连接12864模块接口1~16PIN.

R150焊接0欧电阻,将16PIN短接到GND.

下载时, 选择时钟 48MHz (用户可自行修改频率).

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

#include "..\comm\STC32G144K246.h"

typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;

/****************  用户定义宏  ****************/

#define     MAIN_Fosc       48000000L   //定义主时钟

/****************  IO口定义  ******************/

sbit    LCD_B7  = P2^7;    //D7 -- Pin 14        LED- -- Pin 16
sbit    LCD_B6  = P2^6;    //D6 -- Pin 13        LED+ -- Pin 15
sbit    LCD_B5  = P2^5;    //D5 -- Pin 12        Vo   -- Pin 3
sbit    LCD_B4  = P2^4;    //D4 -- Pin 11        VDD  -- Pin 2
sbit    LCD_B3  = P2^3;    //D3 -- Pin 10        VSS  -- Pin 1
sbit    LCD_B2  = P2^2;    //D2 -- Pin  9
sbit    LCD_B1  = P2^1;    //D1 -- Pin  8
sbit    LCD_B0  = P2^0;    //D0 -- Pin  7

sbit    LCD_ENA = P4^4;    //Pin 6
sbit    LCD_RW  = P4^2;    //Pin 5  //LCD_RS      R/W   DB7--DB0        FOUNCTION
sbit    LCD_RS  = P4^5;    //Pin 4  //    0        0     INPUT      write the command to LCD model
                                    //    0        1     OUTPUT     read BF and AC pointer from LCD model
                                    //    1        0     INPUT      write the data to LCD  model
                                    //    1        1     OUTPUT     read the data from LCD model

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


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

u8  hour,minute,second;

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

void RTC(void);
void ClearLine(u8 row);
void Initialize_LCD(void);
void PutString(u8 row, u8 column, u8 *puts);
void DisplayRTC(void);
void delay_ms(u16 ms);
void WriteChar(u8 row, u8 column, u8 dat);
void LCM_Config(void);

/**********************************************/
void main(void)
{
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P4M0 |= 0x34;       //RS,WR,RD设置成推挽输出
    P4M1 &= ~0x34;

    P5M0 |= 0x02;       //RST设置成推挽输出
    P5M1 &= ~0x02;

    P2BP &= ~0xff;      //使能LCM的D8~D15数据脚硬件自动设置端口模式
   
    LCM_Config();
    Initialize_LCD();
    ClearLine(0);
    ClearLine(1);

    PutString(0,0,"---Clock demo---");
   
    hour   = 12;    //初始化时间值
    minute = 0;
    second = 0;
    DisplayRTC();

    while(1)
    {
        delay_ms(1000);
        RTC();
        DisplayRTC();
    }
}

//========================================================================
// 函数: void delay_ms(unsigned int ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数.
// 返回: none.
// 版本: VER1.0
// 日期: 2025-11-01
// 备注: 由于芯片使能了Cache功能,软件延时时间可能不太准确
//========================================================================
void delay_ms(u16 ms)
{
    u16 i;
    do{
        i = MAIN_Fosc / 6000;
        while(--i);
    }while(--ms);
}

//========================================================================
// 函数: void DisplayRTC(void)
// 描述: 显示时钟函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void DisplayRTC(void)
{
    if(hour >= 10)    WriteChar(1,4,(u8)(hour / 10 + '0'));
    else            WriteChar(1,4,' ');
    WriteChar(1,5,(u8)(hour % 10 +'0'));
    WriteChar(1,6,'-');
    WriteChar(1,7,(u8)(minute / 10+'0'));
    WriteChar(1,8,(u8)(minute % 10+'0'));
    WriteChar(1,9,'-');
    WriteChar(1,10,(u8)(second / 10 +'0'));
    WriteChar(1,11,(u8)(second % 10 +'0'));
}

//========================================================================
// 函数: void RTC(void)
// 描述: RTC演示函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void RTC(void)
{
    if(++second >= 60)
    {
        second = 0;
        if(++minute >= 60)
        {
            minute = 0;
            if(++hour >= 24)    hour = 0;
        }
    }
}

/************* LCD1602相关程序 ********************************************/
//8位数据访问方式    LCD1602        标准程序    梁工编写    2014-2-21

#define LineLength    16        //16x2

/*
total 2 lines, 16x2= 32
first line address:  0~15
second line address: 64~79

*/

#define C_CLEAR            0x01        //clear LCD
#define C_HOME             0x02        //cursor go home
#define C_CUR_L            0x04        //cursor shift left after input
#define C_RIGHT            0x05        //picture shift right after input
#define C_CUR_R            0x06        //cursor shift right after input
#define C_LEFT             0x07        //picture shift left after input
#define C_OFF              0x08        //turn off LCD
#define C_ON               0x0C        //turn on  LCD
#define C_FLASH            0x0D        //turn on  LCD, flash
#define C_CURSOR           0x0E        //turn on  LCD and cursor
#define C_FLASH_ALL        0x0F        //turn on  LCD and cursor, flash
#define C_CURSOR_LEFT      0x10        //single cursor shift left
#define C_CURSOR_RIGHT     0x10        //single cursor shift right
#define C_PICTURE_LEFT     0x10        //single picture shift left
#define C_PICTURE_RIGHT    0x10        //single picture shift right
#define C_BIT8             0x30        //set the data is 8 bits
#define C_BIT4             0x20        //set the data is 4 bits
#define C_L1DOT7           0x30        //8 bits,one line 5*7  dots
#define C_L1DOT10          0x34        //8 bits,one line 5*10 dots
#define C_L2DOT7           0x38        //8 bits,tow lines 5*7 dots
#define C_4bitL2DOT7       0x28        //4 bits,tow lines 5*7 dots
#define C_CGADDRESS0       0x40        //CGRAM address0 (addr=40H+x)
#define C_DDADDRESS0       0x80        //DDRAM address0 (addr=80H+x)

//========================================================================
// 函数: void LCM_Config(void)
// 描述: LCM配置函数。
// 参数: none.
// 返回: none.
// 版本: V1.0, 2024-8-17
// 备注:
//========================================================================
//LCMIFCFG  (7EFE50H)    TFT彩屏接口配置寄存器
#define    LCMIFIE         (0<<7)    //TFT彩屏接口中断使能控制位(bit7), 1->允许中断,0->禁止
#define    LCMIFIP         (0<<4)    //TFT彩屏接口中断优先级控制位(bit5~bit4), (最低)0~3(最高).
#define    LCMIFDPS        (0<<2)    //TFT彩屏接口数据脚选择位(bit3~bit2), D18_D8=0: 0或2->8位数据在P2, D18_D8=1: 0: P2-高字节, P0低字节, 2: P2-高字节,低字节P0[7:4] P4.7 P4.6 P4.3 P4.1.
#define    LCM_D16_D8      (0<<1)    //TFT彩屏接口数据宽度控制位(bit1), 0: 8位数据,1:16位数据
#define    LCM_M68_I80     1         //TFT彩屏接口数据模式选择位(bit0), 0: I8080模式,1:M6800模式

//LCMIFCFG2  (7EFE51H)    TFT彩屏接口配置寄存器2
#define    LCMIFCPS        (0<<5)    //TFT彩屏接口控制脚选择位(bit6~bit5), RS RD(E) WR(RW), 0->P4.5 P4.4 P4.2,1->P4.5 P3.7 P3.6, 2->P4.0 P4.4 P4.2, 3->P4.0 P3.7 P3.6
#define    LCMSETUPT       (4<<2)    //TFT彩屏接口数据建立时间控制位(bit4~bit2), 0~7, 对应1~8个LCMIF时钟, 对于6800模式就是E高电平时间, 至少20us.
#define    LCMHOLDT        3         //TFT彩屏接口数据保持时间控制位(bit1~bit0), 0~3, 对应1~4个LCMIF时钟

//LCMIFCR  (7EFE52H)    TFT彩屏接口控制寄存器
#define    ENLCMIF         (1<<7)    //TFT彩屏接口使能控制位(bit7), 1->允许TFT彩屏接口功能, 0->禁止
#define    LCM_WRCMD       4         //TFT彩屏接口触发命令(bit2~bit0), 4->写命令
#define    LCM_WRDAT       5         //TFT彩屏接口触发命令(bit2~bit0), 5->写数据
#define    LCM_RDCMD       6         //TFT彩屏接口触发命令(bit2~bit0), 6->读命令/状态
#define    LCM_RDDAT       7         //TFT彩屏接口触发命令(bit2~bit0), 7->读数据

void LCM_Config(void)
{
    LCMIFCFG  = LCMIFIE  | LCMIFIP   | LCMIFDPS | LCM_D16_D8 | LCM_M68_I80;
    LCMIFCFG2 = LCMIFCPS | LCMSETUPT | LCMHOLDT;    //RS:P45,E:P44,RW:P42; Setup Time,HOLD Time
    LCMIFSTA  = 0x00;    //TFT彩屏接口中断请求标志,软件清0
    LCMIFPSCR = (u8)(MAIN_Fosc/250000UL-1);    //TFT彩屏接口时钟预分频0~255, LCMIF时钟频率 = SYSclk/(LCMIFPSCR+1), LCD1602速度慢,最快250KHz
    LCMIFCR   = ENLCMIF;
}

//========================================================================
// 函数: void CheckBusy(void)
// 描述: 检测忙函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void CheckBusy(void)
{
    LCMIFSTA = 0;       //清除完成标志
    do
    {
        LCMIFCR   = ENLCMIF | LCM_RDCMD;    //读状态
        while((LCMIFSTA & 1) == 0);         //等待读完成
        LCMIFSTA = 0;   //清除完成标志
        LCD_ENA = 0;
    }while(LCMIFDATL & 0x80);   //bit7==0则空闲
}

//========================================================================
// 函数: void IniSendCMD(u8 cmd)
// 描述: 初始化写命令(不检测忙)
// 参数: cmd: 要写的命令.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void IniSendCMD(u8 cmd)
{
    LCMIFDATL = cmd;
    LCMIFCR   = ENLCMIF | LCM_WRCMD;    //写命令
    while((LCMIFSTA & 1) == 0);         //等待写完成
    LCMIFSTA = 0;   //清除完成标志
}

//========================================================================
// 函数: void Write_CMD(u8 cmd)
// 描述: 写命令(检测忙)
// 参数: cmd: 要写的命令.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void Write_CMD(u8 cmd)
{
    CheckBusy();    //检测忙
    LCMIFDATL = cmd;
    LCMIFCR   = ENLCMIF | LCM_WRCMD;    //写命令
    while((LCMIFSTA & 1) == 0);         //等待写完成
    LCMIFSTA = 0;   //清除完成标志
}

//========================================================================
// 函数: void Write_DIS_Data(u8 dat)
// 描述: 写显示数据(检测忙)
// 参数: dat: 要写的数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void Write_DIS_Data(u8 dat)
{
    CheckBusy();    //检测忙
    LCMIFDATL = dat;
    LCMIFCR   = ENLCMIF | LCM_WRDAT;    //写数据
    while((LCMIFSTA & 1) == 0);         //等待写完成
    LCMIFSTA = 0;   //清除完成标志
}

//========================================================================
// 函数: void Initialize_LCD(void)
// 描述: 初始化函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void Initialize_LCD(void)
{
    LCD_ENA = 0;
    LCD_RS  = 0;
    LCD_RW = 0;

    delay_ms(100);
    IniSendCMD(C_BIT8);     //set the data is 8 bits

    delay_ms(10);
    Write_CMD(C_L2DOT7);    //tow lines 5*7 dots

    delay_ms(6);
    Write_CMD(C_CLEAR);     //clear LCD RAM
    Write_CMD(C_CUR_R);     //Curror Shift Right
    Write_CMD(C_ON);        //turn on  LCD
}

//========================================================================
// 函数: void ClearLine(u8 row)
// 描述: 清除1行
// 参数: row: 行(0或1)
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void ClearLine(u8 row)
{
    u8 i;
    Write_CMD(((row & 1) << 6) | 0x80);
    for(i=0; i<LineLength; i++)    Write_DIS_Data(' ');
}

//========================================================================
// 函数: void WriteChar(u8 row, u8 column, u8 dat)
// 描述: 指定行、列和字符, 写一个字符
// 参数: row: 行(0或1),  column: 第几个字符(0~15),  dat: 要写的字符.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void WriteChar(u8 row, u8 column, u8 dat)
{
    Write_CMD((((row & 1) << 6) + column) | 0x80);
    Write_DIS_Data(dat);
}

//========================================================================
// 函数: void PutString(u8 row, u8 column, u8 *puts)
// 描述: 写一个字符串,指定行、列和字符串首地址
// 参数: row: 行(0或1),  column: 第几个字符(0~15),  puts: 要写的字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-9-30
// 备注:
//========================================================================
void PutString(u8 row, u8 column, u8 *puts)
{
    Write_CMD((((row & 1) << 6) + column) | 0x80);
    for ( ; *puts != 0; puts++)     //遇到停止符0结束
    {
        Write_DIS_Data(*puts);
        if(++column >= LineLength)  break;
    }
}

//******************** LCD Module END ***************************


40-LCD1602显示程序-硬件M6800并行接口驱动.zip

11.31 KB, 下载次数: 1

回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-22 10:20 , Processed in 0.068053 second(s), 42 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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