找回密码
 立即注册
查看: 1628|回复: 39

新手学用STC32G12K128, 实践与思考(都是干货,盖楼砖瓦,实用基础)

[复制链接]
  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
    发表于 2023-10-29 21:15:57 | 显示全部楼层 |阅读模式
    本帖最后由 浦江一水 于 2023-11-15 20:09 编辑

    STC32G系列单片机 与以往传统51单片机相比,有许多不同和强大的新功能, 使我引起强烈兴趣.

    坛子里有资深人士曾建议, 新手上路,用DIP40封装的芯片,动手实践,做做实验比较方便。本人觉得言之有理。
    于是乎, 淘购了一片STC32G12K128, RMB 5.5元。按照STC手册提供的最小系统电原理图,找了一块洞洞板

    以及一些剩余的分列元件,拼凑了一块最小系统实验板。
    STC32G12K128 4KEY_实验板电原理图.jpg

    正面与反面

    正面与反面


    实验板中添加了四个按键、四个发光二极管、一个LCD16002显示屏接口、一个电源上电按钮开关。
    利用串口1(P3.0和P3.1)作为下载仿真口。
    经实践, 使用USB转TTL模块, 或者仅用一根USB线,就能连接PC机下载程序和通信实验。

    非常方便, 千里之行,始于足下,顺利走出了第一步。




    阶段性的学习实验小结

    自从用洞洞板做了STC32G12K128(DIP40)实验板以来,做了一些实验,阶段性的小结罗列一下:
    1,STC单片机 IO端口电平控制--“跑马灯” 程序练习,主要目的是学习掌握工程文件框架的基本建设;
    2,实验对LCD1602字符型显示屏的控制显示输出,对四键八值的输入练习;
    3,实验IIC单色OLED(128*64)点阵显示屏的控制,实现中西文混合显示;
    4,实验 STC32G12K128 对彩色显示屏(128*160)控制显示实现中西文混合显示, 实验12位ADC转换
    5,实验 驱动TM1638数码管模块,实现用三个IO端口,控制8个键输入,8个LED发光管亮灭控制,8位数码管数字和字符串显示。


    2023-11-15 编辑


    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-29 21:38:19 | 显示全部楼层
    本帖最后由 浦江一水 于 2023-11-6 10:46 编辑

    无论是学习C语言编程,还是学习Delphi编程,大凡初学编程语言练习的,都是先编一个“Hello World”程序。
    学习STC32G12K128单片机编程,也不例外,初学也就要整一个“点灯”(跑马灯)程序,先走完一个完整的编写、编译、连接、下载、运行的过程。

    模仿STC的例程,在自制的实验板上,顺利通过。


    //==============================================================================================
    // 文件: Main.C
    // 硬件: MCU: STC32G12K128(DIP40) + 4键 + 4LED 自制实验板
    // 功能: 学习STCSTC32G编程入门初步 练习建立最基本工程框架 + 跑马灯程序
    // 端口: 4LED: P2.0--P2.3 输出低电平驱动点亮
    // 备注: 下载时选择时钟 24MHZ
    //==============================================================================================
    #include "STC32G.h"   //包含此头文件后,不需要再包含"reg51.h"头文件

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

    //========================================================================
    // 函数: void delay_ms(u8 ms)
    // 描述: 延时函数。
    // 参数: ms,要延时的ms数
    // 返回: none.
    //========================================================================
    void delay_ms(unsigned int  ms)
    { unsigned int i;
      do{ i = MAIN_Fosc / 10000;
          while(--i);   //10T per loop
        } while(--ms);
    }
    //==== 主函数 ============================================================
    void main(void)
    {
        WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
        EAXFR = 1; //扩展寄存器(XFR)访问使能
        CKCON = 0; //提高访问XRAM速度
        //IO端口初始化
        P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
        P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
        P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
        P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
        P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
        //--主循环-----------------
        while(1)
        {
          P20 = 0;                  //LED1 On
          delay_ms(250);
          P20 = 1;                  //LED1 Off
          P21 = 0;                  //LED2 On
          delay_ms(250);
          P21 = 1;                  //LED2 Off
          P22 = 0;                  //LED3 On
          delay_ms(250);
          P22 = 1;                  //LED3 Off
          P23 = 0;                  //LED4 On
          delay_ms(250);
          P23 = 1;                  //LED4 Off
          P22 = 0;                  //LED3 On
          delay_ms(250);
          P22 = 1;                  //LED3 Off
          P21 = 0;                  //LED2 On
          delay_ms(250);
          P21 = 1;                  //LED2 Off
        }
    }
    //==== END ====================================================================


    实验与代码很简单,但是意义不凡:
    1。学习了C251编译环境的建立;
    2。学习了STC32G12K128单片机工程文件的建立;
    3。学习了如何下载和仿真调试;
    为进一步学习,打下了一点基础,以便再继续实践......

    00-基础工程-跑马灯.rar (17.59 KB, 下载次数: 25)

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9334

    回帖

    1万

    积分

    管理员

    积分
    13922
    发表于 2023-10-29 21:57:51 | 显示全部楼层
    洞洞板,手工搭,还是可以USB直接下载/仿真的,用 USB-TypeA 插头

    截图202310292205262606.jpg

    截图202310292207152680.jpg


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9334

    回帖

    1万

    积分

    管理员

    积分
    13922
    发表于 2023-10-29 22:00:45 | 显示全部楼层

    截图202310292159552813.jpg


    截图202310292158591265.jpg


    截图202310292200416773.jpg


    回复 支持 1 反对 0 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9334

    回帖

    1万

    积分

    管理员

    积分
    13922
    发表于 2023-10-29 23:15:07 | 显示全部楼层
    截图202310292314503692.jpg

    截图202310292315008537.jpg

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-30 09:47:15 | 显示全部楼层
    确实如管理员神农鼎所言, 只要用一根USB数据线, 连接PC机, 就能实现对实验板的下载调试.
    这正是说明, STC单片机的强大和便捷, 即便是新手, 也是很容易上手的.
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-30 10:33:04 | 显示全部楼层
    基于这块自制的实验板, 又做了驱动LCD1602显示屏的实验。
    在这个实验中,包含了三个内容的练习:
    1,实现四键八值的输入;                     短按K1(P3.2)显示“KEY=10”, 长按K1显示“KEY=11”, 短按K2显示“KEY=20”,......  其它键依次类推。。。
    2,对LCD1602显示屏的控制显示;       指定行列坐标位置显示字符串,或显示底划线,或闪烁。。。
    3,实验USART1串口通信,                   实现与PC机的串行通信交互,返回PC发送的字符串。加入简单的指令协议,使这个最小系统实验板成为“LCD1602串口屏”(接口仅用四线)。

    STC32G-DIP40-实验LCD1602.jpg

    工程文件目录结构如下:
    01-LCD1602+4KEY+USART1  -----  存放工程文件 LCD1602Disp.uvproj
                         |---------- USER   -----  存放编译输出的HEX文件, 以及OBJ,LST等中间临时文件(便于除HEX以外文件的清理)
                         |---------- OUT     -----  存放 Main.C主文件和各种外设文件,如KEY4_IO.C, LCD1602.C....等等。
    编程思考:
    1,工程目录结构简明,所有外设与主文件同目录,路径设置最简化。
    2,每一种外设文件仅有.C和.H两个文件,尽可能做到独立(尽量不要与其它文件交叉包含(除STC32G.H以外)),便于代码阅读和移植。
    3,所有编译输出文件,都放在OUT目录中,便于清理、打包存档。
    4,源代码文件编写时尽可能加入详细注释,有利于源码阅读理解和日久后自己的编程思路回忆。      

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-30 10:35:46 | 显示全部楼层
    本帖最后由 浦江一水 于 2023-11-6 10:51 编辑

    主程序源码:


    /******************************************************************
    * 工程: PxmTest STC32G12K128 + LCD1602
    * 实验: 基本系统: LCD1602串口显示屏 8位数据控制 USART1_串口通讯..4键8值..
    * 四键: P32/P33/P34/P35 四LED:P20/P21/P22/P23
    * 功能说明: 测试LCD1602和4键操作,练习串口通信, 制作成LCD1602串口显示屏
    * 编程: 浦晓明(浦江一水) 2023-10 ...
    *******************************************************************/
    #include "STC32G.H"            //此文件中定义了单片机的一些特殊功能寄存器
    #include <stdio.h>
    #include <string.h>
    #include "KEY4_IO.H"           //4键盘相关函数
    #include "LCD1602.H"           //LCD1602显示屏相关函数

    //波特率计算...      
    #define FOSC            11059200UL                  //晶振频率
    #define BRT             (256 - FOSC / 9600 / 32)    //按照波特率9600计算
    //#define BRT           (256 - FOSC / 115200 / 32)  //按照波特率115200计算

    sbit LED0  = P2^0;              //运行指示
    sbit LED1  = P2^1;              //运行指示
    sbit LED2  = P2^2;              //运行指示
    sbit LED3  = P2^3;              //运行指示

    char RxBuf[24],k;              //串口接收缓存
    unsigned short RxCount=0;      //接收计数器
    char S[20];                    //LCD显示缓存
    unsigned char X,Y;             //坐标
    unsigned char RxOK=0;          //串口通信接收到标志

    //毫秒级延时
    void delay(unsigned int ms)
    { unsigned int x,y;
      for(x = ms; x > 0; x--)
      for(y =114; y > 0; y--);
    }
    //串口初始化:
    void UART_init()
    {
      SCON= 0x50;
      TMOD= 0x20; //T1工作模式2  8位自动重装
      TH1 = BRT;  //0xFD;
      TL1 = BRT;  //0xFD; //比特率115200
      TR1 = 1;    //启动T1定时器
      AUXR= 0x40;
      SM0 = 0;
      SM1 = 1;    //串口工作方式1 10位异步
      REN = 1;    //串口允许接收
      ES  = 1;    //串口中断打开
      EA  = 1;    //开总中断
    }
    /*----------------------------
    通过串口1发送单字节数据
    ----------------------------*/
    void SendData(unsigned char ch)
    {
      SBUF = ch;                 //写数据到UART数据寄存器
      while(TI == 0);
      TI = 0;
    }
    /*----------------------------
    通过串口1发送字符串
    ----------------------------*/
    void SendString(char *s)
    {
      while (*s)            //检测字符串结束标志
      { SendData(*s++); }   //发送当前字符
    }
    //--------------------------------------------------------------
    // 串口1接收中断服务...
    //--------------------------------------------------------------
    void UART() interrupt 4
    { unsigned char ch=0;
      if(RI)          //检测是否接收完成
      { ch=SBUF;      //接收单字节
        RI = 0;       //清除标志位
        if(ch==0x0A)  //结尾标志
        { RxOK=1;     //接收到指令串置接收到标志
          if((RxCount>0)&&(RxBuf[RxCount-1]==0x0D)){ RxBuf[RxCount-1]=0;RxBuf[RxCount]=0; }
        }
                    else if(RxCount<19)RxBuf[RxCount++]=ch;
      }
    }
    //--------------------------------------------------------------
    // 主程序入口
    //--------------------------------------------------------------
    void main(void)
    { unsigned char i,mode;
            unsigned int wait=0;
      //IO端口初始化
      WTST  = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
      EAXFR = 1; //扩展寄存器(XFR)访问使能
      CKCON = 0; //提高访问XRAM速度
      //IO端口初始化//全部为准双向口
      P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
      P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
      P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
      P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
      P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
      //外设初始化
            UART_init();
      LCD_Init();    //初始化LCD1602
      LCD_CLS();     //测试清屏函数
      LCD_Blink(0);  //测试函数
      LCD_Cursor(0); //测试函数
      LCD_SetXY(0,0);//测试函数
      delay(5);
      LED0 = 0; delay(1000); //测试IO口控制 LED0亮
      LED1 = 0; delay(1000);
      LED2 = 0; delay(1000);
      LED3 = 0; delay(1000);
      LED0 = 1; delay(1000); //测试IO口控制 LED0灭  
      LED1 = 1; delay(1000);
      LED2 = 1; delay(1000);
      LED3 = 1; delay(1000);
      //显示屏初始界面  
      LCD_STR(0,0,"PXM_STC32G12K128");
      LCD_STR(1,0,"LCD1602+4KEY4LED");
      //测试通讯口发送字符串
            SendString("STC32G12K128_UART1_OK\r\n");
      delay(1000);
            //GETCH();
      //大循环
      while(1)
      { k=0;
        k=RDKEY();  //扫描按键
        if(k!=0)
        { sprintf(S,"KEY=%02X ",(unsigned int)k);   //当有键按下时, 显示键值,(<1秒为短按 >=1秒为长按)
          LCD_STR(1,10,S);                          //比如短按Key1,显示=10, 长按显示=11
        }  
        //运行指示
        if(wait==0)  {  LED0 = 0; }                               // LED亮
        if(wait==200){  LED0 = 1; RxOK=0;RxCount=0;RxBuf[0]=0; }  // LED灭
        wait=wait<2250?wait+1:0;  //计数器循环
        //串口屏通讯处理....
        if(RxOK)  //接收到指令串
        { //解析串口接收指令字符串,显示之
          switch(RxBuf[0])
          { case 'P':  //显示指令
                       X=RxBuf[1]-0x30;
                       Y=RxBuf[2]-0x30; if(Y>9)Y=Y-7;
                       for(i=0;i<RxCount-3;i++){ S=RxBuf[3+i]; S[i+1]=0; }
                       LCD_STR(X,Y,S);  //显示接收字符串
                       break;
            case '@':  X=RxBuf[1]-0x30;
                       Y=RxBuf[2]-0x30; if(Y>9)Y=Y-7;
                       LCD_SetXY(X,Y);  //光标定位
                       break;
            case '_':  mode=RxBuf[1]-0x30;if(mode>0)mode=1;
                       LCD_Cursor(mode);//光标显示        
                       break;
            case '*':  mode=RxBuf[1]-0x30;if(mode>0)mode=1;
                       LCD_Blink(mode); //光标闪动
                       break;
            case 'C':  mode=RxBuf[1]-0x30;
                       if(mode==0)LCD_STR(0,0,"                ");//清屏第一行
                       if(mode==1)LCD_STR(1,0,"                ");//清屏第二行
                                                                             if(mode>=2)LCD_CLS();                      //清全屏
                       break;
            default:   RxBuf[RxCount]=0; SendString(RxBuf); SendData(0x0D); SendData(0x0A); break;  //默认返回原串...
          }
          for(i=0;i<24;i++)RxBuf=0;RxOK=0; RxCount=0;
        }                            //清除接收缓存
        delay(10);     
      }
    }
    //******************************************************************************
    // 附件: LCD1602串口屏通信控制指令协议,9600,8,1,N
    //----------------------------------------------------------------------
    // 共五条指令, 说明如下...
    //----------------------------------------------------------------------
    // 1, 格式:  PXYsss...\r\n   +0D+0A
    //    其中:  P -- 命令字 指定坐标显示字符串;
    //           X -- 显示行坐标, X=0或1,表示第一行或第二行
    //           Y -- 显示列坐标, Y=0...F(超过9用ABCDEF的16进制表示)
    //           sss... 需要显示的字符串 (长度限于16字符)(LCD1602每行最多显示16字符)   
    //           \r\n  发送串结尾标志,回车换行符 即+0x0D+0x0A,(以下同)
    //    实例:  P00ABCDEFG+0.1234(\r\n) 在显示屏第一行首显示"ABCDEFG+0.1234"
    //----------------------------------------------------------------------
    // 2, 格式:  Cm\r\n
    //    其中:  C -- 命令字 清屏
    //           m -- 参数 0:清第一行 1:清第二行 2:清全屏           
    //    实例:  C0\r\n 显示屏第一行被清空;
    //----------------------------------------------------------------------
    // 3, 格式:  @XY\r\n
    //    其中:  @ -- 命令字 指定当前光标坐标
    //           X,Y -- 参数 X:行 Y:列           
    //    实例:  @01\r\n 当前光标在第一行第1列 (光标是否显示取决于以下指令)
    //----------------------------------------------------------------------
    // 4, 格式:  *m\r\n
    //    其中:  * -- 命令字 光标闪烁显示
    //           m -- 参数 0:不闪烁 1:闪烁           
    //    实例:  *1 在先前指定的坐标位置闪烁光标;
    //----------------------------------------------------------------------
    // 5, 格式:  _m\r\n
    //    其中:  _ -- 命令字 底画线显示
    //           m -- 参数 0:不显示底画线 1:显示底画线           
    //    实例:  _1 在先前指定的坐标位置显示底画线; (底画线显示后,光标闪烁取消)
    //*******************************************************************************


    01-LCD1602 4KEY USART1.rar (26.3 KB, 下载次数: 28)



    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-30 10:38:53 | 显示全部楼层
    关于按键外设的两个文件:



    /******************************************************************************
    * 文件: KEY4_IO.H  
    * 说明: 关于4键盘的函数: 用于STC32G12K128 自制实验板
    * 编程: 浦晓明(浦江一水) 2023.10
    * 特点: 利用延时计数功能,使得一个按键可返回不同的键值(每键有短按和长按两种键值)
    * 接口: KEY1--P3.2  KEY2--P3.3 KEY3--P3.4  KEY4--P3.5
    ***************************************************************************** */

    #ifndef _KEY4_IO_H_
    #define _KEY4_IO_H_

    //键端口定义
    sbit KEY1 = P3^2;
    sbit KEY2 = P3^3;
    sbit KEY3 = P3^4;
    sbit KEY4 = P3^5;

    //4键8值定义说明
    #define K1S 0x10  //短按K1键  
    #define K1L 0x11  //长按K1键  
    #define K2S 0x20  //短按K2键
    #define K2L 0x21  //长按K2键
    #define K3S 0x30  //短按K3键  
    #define K3L 0x31  //长按K3键  
    #define K4S 0x40  //短按K4键
    #define K4L 0x41  //长按K4键

    /* 键盘函数 */
    void KeyYS(unsigned int ms);        /* 消抖延时函数 */
    unsigned char RDKEY(void);          /* 读键子程序   */
    unsigned char GETCH(void);          /* 等待键入模块 */

    #endif




    /******************************************************************************
    * 文件: KEY4_IO.C  
    * 说明: 关于4键盘的函数: 用于STC32G12K128 自制实验板
    * 编程: 浦晓明(浦江一水) 2023.10
    * 特点: 利用延时计数功能,使得一个按键可返回不同的键值(每键有短按和长按两种键值)
    * 接口: KEY1--P3.2  KEY2--P3.3 KEY3--P3.4  KEY4--P3.5
    ***************************************************************************** */
    #include "STC32G.H"          //此文件中定义了STC32G系列单片机一些特殊功能寄存器
    #include <stdio.h>
    #include "KEY4_IO.H"

    /* 延时函数 延时约 0.2ms * ms @11.0592MHz */
    void KeyYS(unsigned int ms)
    { unsigned int i;
      while (ms)
      { ms--;
                    i=550;
                    while(i)i--;
            }
    }
    //读取键值函数
    unsigned char RDKEY(void)
    { unsigned char kv=0;
      unsigned int  ak=0;   //按键延时计数
      if(KEY1==0)
      { ak=0; KeyYS(5);     //消除抖动
        while((KEY1==0)&&(ak<500)){ ak++; KeyYS(10); } //等待键松开...
        if((ak>1)&&(ak<=250))kv=K1S;                              //根据不同计数时间
        else if (ak>250)     kv=K1L;                                     //返回不同的键值
      }
      if(KEY2==0)
      { ak=0; KeyYS(5);     //消除抖动
        while((KEY2==0)&&(ak<500)){ ak++; KeyYS(10); }
        if((ak>1)&&(ak<=250))kv=K2S;
        else if (ak>250)     kv=K2L;
      }
      if(KEY3==0)
      { ak=0; KeyYS(5);     //消除抖动
        while((KEY3==0)&&(ak<500)){ ak++; KeyYS(10); }
        if((ak>1)&&(ak<=250))kv=K3S;
        else if (ak>250)     kv=K3L;
      }
      if(KEY4==0)
      { ak=0; KeyYS(5);     //消除抖动
        while((KEY4==0)&&(ak<500)){ ak++; KeyYS(10); }
        if((ak>1)&&(ak<=250))kv=K4S;
        else if (ak>250)     kv=K4L;
      }
      return kv;            //若无键按下则返回0
    }
    //键等待函数
    unsigned char GETCH(void)
    { unsigned char wait_k=0;
      do { wait_k=RDKEY(); }while(wait_k==0);
      return wait_k;
    }

    /*** END *************************************************************************** */

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 148 天

    [LV.7]常住居民III

    5

    主题

    97

    回帖

    672

    积分

    高级会员

    积分
    672
     楼主| 发表于 2023-10-30 10:44:26 | 显示全部楼层
    关于LCD1602显示屏的两个文件:



    /******************************************************************************
    * 文件: 头文件 LCD1602.H
    * 说明: 关于LCD1602的驱动函数: 用于STC32G12K128 自制实验板
    * 编程: 浦晓明(浦江一水) 2023.10
    * 特点: 经典实用/简明扼要/便于移植
    * 接口: 数据口-P0 指令-P4.5 读写-P2.7 使能-P2.6
    ***************************************************************************** */

    #include "STC32G.h"

    #ifndef __LCD1602_H_
    #define __LCD1602_H_

    /*****************************************
      LCD1602PIN口定义 (数据口和控制位说明)
    ******************************************/
    #define LCD_DATAP     P0     //P0数据口(8位)

    sbit LCD_RS =P4^5;            //指令端 0:命令 1:数据
    sbit LCD_RW=P2^7;           //读写端 0;写入 1:读出(直接接地--只写方式)
    sbit LCD_E   =P2^6;            //使能端 0:失能 1:使能

    /*****************************************
      函数声明
    ******************************************/
    /*在11.0592MHz时钟下的延时1ms毫秒函数*/
    void LCD_Delay1ms(unsigned int ms);  //误差 0us
    /*LCD1602初始化子程序*/               
    void LCD_Init(void);
    /*LCD1602 清屏函数 */
    void LCD_CLS(void);                                                  
    /*LCD1602写入8位命令子函数*/
    void LCD_COM(unsigned char com);
    /*LCD1602写入8位数据子函数*/       
    void LCD_DAT(unsigned char dat);
    /*LCD1602指定坐标写字符串函数 X:行(0/1) Y:列(0-15) */       
    void LCD_STR(unsigned char X,unsigned char Y,unsigned char * str);
    void LCD_SetXY(unsigned char,unsigned char);  //定位
    void LCD_Cursor(unsigned char mode); //控制光标
    void LCD_Blink(unsigned char mode);    //控制闪烁       

    #endif




    /******************************************************************************
    * 文件: LCD1602.C
    * 说明: 关于LCD1602驱动函数的实现: 用于STC32G12K128 自制实验板
    * 编程: 浦晓明(浦江一水) 2023.10
    * 特点: 经典实用/简明扼要/便于移植
    * 接口: 数据口-P0 指令-P4.5 读写-P2.7 使能-P2.6
    ***************************************************************************** */

    #include "LCD1602.H"

    /*******************************************************************************
    * 函 数 名         : LCD1602_Delay1ms
    * 函数功能         : 延时函数,延时1ms
    * 输    入         : 无
    * 输    出         : 无
    * 说    名         : 该函数是在11.0592MHZ晶振下,12分频单片机的延时。//误差 0us
    *******************************************************************************/
    void Delay1ms()         //@11.0592MHz
    { unsigned char i, j;
      i = 15; j = 90;
      do { while (--j); } while (--i);
    }

    void LCD_Delay1ms(unsigned int ms)   
    { for (; ms>0; ms--)Delay1ms(); }

    /*******************************************************************************
    * 函 数 名         : LCD1602_COM(unsigned char com)
    * 函数功能         : 向LCD写入一个字节的命令
    * 输    入         : com
    * 输    出         : 无
    *******************************************************************************/
    void LCD_COM(unsigned char com)   //八位/四位数据口写入共用
    {
      LCD_E = 0; Delay1ms();  
      LCD_RW= 0; Delay1ms();    //选择写入
      LCD_RS= 0; Delay1ms();    //选择发送命令
      LCD_E = 0; Delay1ms();    //使能
      LCD_DATAP= com; LCD_Delay1ms(2); //先发送命令字节高四位
      LCD_E = 1; Delay1ms();    //写入时序(脉冲)
      LCD_E = 0; Delay1ms();  
    }
    /*******************************************************************************
    * 函 数 名         : LCD1602_DAT(unsigned char dat);
    * 函数功能         : 向LCD写入一个字节的数据
    * 输    入         : dat
    * 输    出         : 无
    *******************************************************************************/      
    void LCD_DAT(unsigned char dat)    //写入数据
    {
      LCD_E = 0; Delay1ms();  
      LCD_RW= 0; Delay1ms();  //选择写入
      LCD_RS= 1; Delay1ms();  //选择输入数据
      LCD_E = 0; Delay1ms();  //清零使能
      LCD_DATAP= dat; LCD_Delay1ms(2); //先发送数据字节高四位
      LCD_E = 1; Delay1ms();  //写入时序(脉冲)
      LCD_E = 0; Delay1ms();
    }
    /*******************************************************************************
    * 函 数 名       : LCD1602_Init(void)
    * 函数功能       : 初始化LCD屏
    * 输    入       : 无
    * 输    出       : 无
    *******************************************************************************/      
    void LCD_Init(void)   //LCD初始化子程序
    {
      LCD_COM(0x38);   //开显示
      LCD_COM(0x38);   //开显示
      LCD_COM(0x0C);   //开显示不显示光标
      LCD_COM(0x06);   //写一个指针加1
      LCD_COM(0x01);   //清屏
      LCD_COM(0x80);   //设置数据指针起点
    }
    /*******************************************************************************
    * 函 数 名       : LCD1602_CLS(void)
    * 函数功能       : 清屏
    *******************************************************************************/      
    void LCD_CLS(void)
    {
      LCD_COM(0x01);   //清屏
      LCD_COM(0x80);   //设置数据指针起点
    }
    /*LCD1602写入字符串函数*/
    //指定坐标函数 ( X:行[0-1] Y:列[0-15] )
    void LCD_STR(unsigned char X,unsigned char Y,unsigned char * str)

    { unsigned char i = 0;
      LCD_COM(0x80+X*0x40+Y);
      while(str[i]!= 0x0)LCD_DAT(str[i++]);
    }
    //设定坐标函数 ( X:行[0-1] Y:列[0-15] )
    void LCD_SetXY(unsigned char X,unsigned char Y)
    {
      if(X==0)LCD_COM(Y+0x80);
      if(X==1)LCD_COM(Y+0xC0);
    }
    //LCD定位显示光标函数 mode=0:光标关闭 mode=1:光标显示
    void LCD_Cursor(unsigned char mode)       
    {
      if(mode==0)LCD_COM(0x0C);  
      if(mode==1)LCD_COM(0x0E);  
    }
    //LCD定位显示光标函数 mode=0:关闭闪动 mode=1:开启闪动
    void LCD_Blink(unsigned char mode)       
    {
      if(mode==0)LCD_COM(0x0C);  
      if(mode==1)LCD_COM(0x0D);
    }   
    //*** END ****************************************************************************


    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-6 11:40 , Processed in 0.072943 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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