分享一个LCD12864多级屏幕菜单成果

2019-07-21 08:29发布

      前段时间在做一个课题,需要做出一多级屏幕菜单。便开始了多级屏幕菜单的研究之路,我一直想一直一个GUI库来做屏幕菜单,便开始了无限的找资料之旅。后面我发现了u8glib后面出了更新版的u8g2(可以完美支持中文),他是一款适合于多中屏幕型号的单 {MOD}屏GUI库,主要用在Arduino平台上,也有适用于ARM的版本,在github上可以下载到源码。网上很少看到有人将此GUI库用到STM32平台上的,我便开始试图将他移植到STM32平台上,在网上找到一些支离破碎的信息,通过这些信息成功的将u8g2移植到了STM32平台上。该库给我的直观感受是库文件看起来很多很杂(可能是适用的硬件平台较多吧),库文件放到STM32工程中会占据大量的代码段空间,总感觉怪怪的。看不懂该GUI库不懂怎么裁剪优化且不知道如何利用其写屏幕菜单,最终还是放弃的采用该GUI库。如果有大神对这方面有所了解还希望能传道授业解惑一下,不胜感激。
    在此我先奉献上移植成功的代码工程,是利用原子MINI板的工程制作的,屏幕使用的是LCD12864(st7920)。
使用附件总是上传不上,还是通过百度云分享给大家 链接:http://pan.baidu.com/s/1o7Xk6ym 密码:9u5z
    后面看多级屏幕菜单程序写法的资料时发现了一篇帖子中的多级菜单思路,感觉此思路不错,便开启了利用此思路制作自己的屏幕菜单系统之旅。
    在这里为表示对原创作者的尊重先附上所参考多级菜单的链接http://www.openedv.com/posts/list/46635.htm
下面是我所做屏幕菜单系统的成果展示:

主菜单 主菜单
准备菜单 准备菜单
控制菜单 控制菜单
SD卡文件菜单 SD卡文件菜单
监控状态菜单 监控状态菜单
打印选项菜单 打印选项菜单
调整参数菜单 调整参数菜单
是否停止打印菜单 是否停止打印菜单
最后附上一分钟左右的菜单操作演示视频:http://pan.baidu.com/s/1nvbWnZN



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
mmttjj
1楼-- · 2019-07-21 22:49
厉害了!!
mmttjj
2楼-- · 2019-07-21 23:27
楼主,我也在做一个相同的项目,怎么读取g代码文件呢
晓元无悔
3楼-- · 2019-07-22 01:58
游在云间 发表于 2018-3-6 12:22
楼主你好,请问还有更详细的资料吗?移植8080的接口没反应。可以多分享下资料或代码吗?

[mw_shl_code=c,true]/**
  ******************************************************************************
  * @file    lcd12864.h
  * @Author  xiaoyuan
  * @version V1.0
  * @date    2016-04-12
  * @brief   
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LCD12864_H
#define __LCD12864_H       

#include "stm32f10x.h"

#define PIN_CS  GPIO_Pin_0     //RS(CS)并行的指令/数据选择信号。串行的片选信号。
#define PIN_SID GPIO_Pin_1    //R/W(SID)并行的读写选择信号。串行的数据口
#define PIN_CLK GPIO_Pin_2    //E(CLK)并行的使能信号。串行的同步时钟。
#define PIN_PSB GPIO_Pin_3   // 并/串行接口选择:H并行,L串行
#define PIN_RST GPIO_Pin_4

#define SET_CS      GPIO_SetBits(GPIOA,GPIO_Pin_0)
#define RESET_CS    GPIO_ResetBits(GPIOA,GPIO_Pin_0)
#define SET_SID     GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define RESET_SID   GPIO_ResetBits(GPIOA,GPIO_Pin_1)
#define SET_SCLK     GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define RESET_SCLK   GPIO_ResetBits(GPIOA,GPIO_Pin_2)
#define SET_PSB     GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define RESET_PSB   GPIO_ResetBits(GPIOA,GPIO_Pin_3)
#define SET_RST     GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define RESET_RST   GPIO_ResetBits(GPIOA,GPIO_Pin_4)

#define LCD12864_MODE_CMD  (uint32_t)0xf8 //串行 写入命令要先写入0xf8
#define LCD12864_MODE_DTAE (uint32_t)0xfa //串行 写入数据要先写入0xfa


void LCD12864_Init(void);
void LCD12864_WriteByte(unsigned char byte);
void LCD12864_WriteData(uint8_t data) ;
void LCD12864_WriteCmd(uint8_t cmd) ;
void LCD12864_Clear(void);
void LCD12864_ShowString(uint8_t row,uint8_t col,uint8_t *data1);
void LCD12864_ShowNum(uint8_t row,uint8_t col,uint16_t num);
void LCD12864_ShowFloat(uint8_t row,uint8_t col,float fnum);
#endif
[/mw_shl_code]

[mw_shl_code=c,true]/**
  *******************  ***********************************************************
  * @file    lcd12864.c
  * @author  xiaoyuan
  * @version V1.0
  * @date    2016-04-16
  * @brief   This file provides all the lcd12864 functions.
  ******************************************************************************
  * @attention
  * 该代码是从xs128例程中移植过来的。
        * 串行模式
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "lcd12864.h"
#include "delay.h"

unsigned char adress_table[]=                 //定义液晶点阵的坐标
{
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,      //第一行汉字位置
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,      //第二行汉字位置
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,      //第三行汉字位置
0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F       //第四行汉字位置
};


/*************************************************************/
/*                      初始化液晶接口                       */
/*************************************************************/
void LCD12864_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能PA时钟
       
        GPIO_InitStructure.GPIO_Pin = PIN_CS|PIN_SID|PIN_CLK|PIN_PSB|PIN_RST;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);             //按上面设定初始化GPIOA端口
        RESET_PSB;           //PSB拉低定义为串行数据模式

}

/*************************************************************/
/*                   写一个字节的数据                     */
/*************************************************************/
void LCD12864_WriteByte(unsigned char byte)
{
unsigned char j;
for(j=0;j<8;j++)        
{
        if((byte<<j)&0x80)
                SET_SID;
        else
                RESET_SID;
        SET_SCLK;
        RESET_SCLK;
}
}

/*************************************************************/
/*                     向液晶发送数据                        */
/*************************************************************/
void LCD12864_WriteData(uint8_t data)
{
  SET_CS;
  RESET_SCLK;
  LCD12864_WriteByte(LCD12864_MODE_DTAE);
  LCD12864_WriteByte(data&0xF0);          //写高四位数据
  LCD12864_WriteByte(0xf0&(data<<4));     //写低四位数据
  RESET_CS;
}

/*************************************************************/
/*                      向液晶发送命令                       */
/*************************************************************/
void LCD12864_WriteCmd(uint8_t cmd)
{
  SET_CS;
  RESET_SCLK;
  LCD12864_WriteByte(LCD12864_MODE_CMD);
  LCD12864_WriteByte(cmd&0xF0);        //写高四位数据
  LCD12864_WriteByte(0xf0&(cmd<<4));        //写低四位数据
  RESET_CS;   
}

/***************************************************************************/
/*                            清屏子程序                                   */
/***************************************************************************/
void LCD12864_Clear(void)
{
    LCD12864_WriteCmd(0x30);//0011,0000 功能设置,一次送8位数据,基本指令集
    delay_us(80);       //延时80us
    LCD12864_WriteCmd(0x03);//AC归0,不改变DDRAM内容
    delay_ms(5);        //延时5ms
    LCD12864_WriteCmd(0x01);//0000,0001 清DDRAM
    delay_ms(5);        //延时5ms
    LCD12864_WriteCmd(0x06);//写入时,游标右移动
    delay_us(80);       //延时80us
    LCD12864_WriteCmd(0x0C);//0000,1100  整体显示,游标off,游标位置off
    delay_us(80);       //延时80us
}

/***************************************************************************/
/*                           向LCD12864发送字符串                               */
/***************************************************************************/
void LCD12864_ShowString(uint8_t row,uint8_t col,uint8_t *data1)   //row为写入数据所在的行数,col为写入数据所在的列数,*data1为写入的数据
{
  for(;row<4&&(*data1)!=0;row++)
  {
      for(;col<8&&(*data1)!=0;col++)
      {
          LCD12864_WriteCmd(adress_table[row*8+col]);
          delay_us(80);       //延时80us
           
          LCD12864_WriteData(*data1++);
          delay_us(80);       //延时80us
          LCD12864_WriteData(*data1++);
          delay_us(80);       //延时80us
      }
      col=0;
  }
}
/***************************************************************************/
/*                           向LCD12864发送整数                               */
/***************************************************************************/
void LCD12864_ShowNum(uint8_t row,uint8_t col,uint16_t num)  //显示整型变量的函数,最多显示16位的整数。只能显示正数。
{
        uint8_t temp[17];
        uint8_t str[17];
        int i=0,j=0;
        while(num != 0)          //这里不能用num%10 != 0,如果num是10的整数倍,
                          //例如,100,这样就会出错,根本就不能进入循环体。
        {
                temp = (num%10)+0x30;
                num/=10;
                i++;
        }
        i--;           //因为i在退出循环之前还自加了一次,此时,
                        //指向最后一个存储有用值的元素的后一个位置。
        while(i != -1)         //因为i=0时,temp[0]还是有用值。
        {
                str[j] = temp;
                j++;
                i--;       
        }
        str[j]='';  //因为i在退出循环之前还自加了一次,此时,
                      //指向最后一个存储有用值的元素的后一个位置。
        LCD12864_ShowString(row,col,str);       
}
/***************************************************************************/
/*                           向LCD12864发送小数                              */
/***************************************************************************/
void LCD12864_ShowFloat(uint8_t row,uint8_t col,float fnum) //显示有4位小数的浮点数,总位数不超过16位。
{
        long int num = fnum*10000;
        u8 temp[17];
        u8 str[17];
        int i=0,j=0;
        while(num != 0)                         
        {
                temp = (num%10)+0x30;
                num/=10;
                i++;
                if(i == 4)         //4位小数处理完后,加入小数点。
                {
                        temp = '.';
                        i++;
                }
        }
        i--;   
        while(i != -1)       
        {
                str[j] = temp;
                j++;
                i--;       
        }
        str[j]='';  
        LCD12864_ShowString(row,col,str);                               
}[/mw_shl_code]

这可是串行方式的LCD12864的驱动程序你可以参考下
晓元无悔
4楼-- · 2019-07-22 02:44
mmttjj 发表于 2018-8-29 16:33
楼主,我也在做一个相同的项目,怎么读取g代码文件呢

读取gcode文件本质上和读取txt文件是一样的(只是后缀不一样),具体你可以参考下原子的例程。如果你是在做3D打印机或CNC相关的可以参考下marlin固件。
mmttjj
5楼-- · 2019-07-22 08:40
 精彩回答 2  元偷偷看……
游在云间
6楼-- · 2019-07-22 13:12
晓元无悔 发表于 2018-9-8 21:10
[mw_shl_code=c,true]/**
  *********************************************************************** ...

谢谢代码,是我的驱动代码有问题

一周热门 更多>