加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

液晶OCM12864,结构体,枚举,指针,规范化和模块化编程

发布时间:2020-12-15 18:34:31 所属栏目:百科 来源:网络整理
导读:来自:http://www.eeworld.com.cn/mcu/2011/0804/article_4786.html 1.首先来看看枚举和结构体的使用吧 /*****************************************************/ //使用平台:keil3以上版本 //程序功能:配置LCD选屏,LCD写入数据的参数配置,以及LCD函数

来自:http://www.eeworld.com.cn/mcu/2011/0804/article_4786.html

1.首先来看看枚举和结构体的使用吧

/*****************************************************/
//使用平台:keil3以上版本
//程序功能:配置LCD选屏,LCD写入数据的参数配置,以及LCD函数声明
//作者:刘园珍
//作者单位:东华理工大学电路与系统研究生
/*****************************************************/
#ifndef __lcd_stcon_H
#define __lcd_stcon_H

#include "config.h"
#include "LCD_config.h"

//选屏枚举
typedef enum
{
LCD_CS_LEFT = 0,
LCD_CS_RIGHT,
LCD_CS_ALL
}LCD_CSTYPE;

//LCD写信息配置结构体
typedef struct
{
U8 ROW;//行
U8 COL;//列
U8 NumALL;//写入的字符个数
U8 ZKIndex[16];//写入的字符所在字库的索引数组
}LCD_INFO;

//LCD清屏
void CLR_SCREEN(void);
//LCD写字符和汉字配置
void LCD_INFO_CONFIG(LCD_INFO *self,U8 x,U8 y,U8 n,FLASH *page);
//LCD写字符
void LCD_WR_CHAR(LCD_INFO *self);
//LCD写汉字
void LCD_WR_HZ(LCD_INFO *self);
//LCD初始化
void LCD_Initial(void);

#endif

2 然后再看看指针和结构体,枚举在程序中的使用

/*-----------------------------------------------------------------/
//使用平台:keil3以上版本
//程序功能:液晶OCM12864-1操作程序,包括点阵8x8字母,和点阵16x16汉字
//作者:刘园珍
//作者单位:东华理工大学电路与系统研究生
/-----------------------------------------------------------------*/
#include "LCD_Config.h"
#include "lcd_stcon.h"
#include "ZK.h"

//忙信号检查
void CheckBusy(void)
{
U8 signal;
LCD_RS = 0; //数据操作
LCD_RW = 1; //读操作
LCD_E = 1; //使能LCD
signal = LCD_PORT; //读数据口数据
LCD_E =0; //关闭LCD使能
while((signal&0x80)==0x80); //数据第7位为BUSY位,低电平为空闲
}

//选屏

void LCD_CS_SELECT(LCD_CSTYPE in_type)
{
switch(in_type)
{
case LCD_CS_LEFT:
LCD_CS1 = 1;
LCD_CS2 = 0;
break;
case LCD_CS_RIGHT:
LCD_CS1 = 0;
LCD_CS2 = 1;
break;
case LCD_CS_ALL:
LCD_CS1 = 1;
LCD_CS2 = 1;
break;
default:
break;
}
}

//写命令
void LCD_WR_CMD(U8 cmd)
{
CheckBusy(); //忙信号检查
LCD_RS = 0; //命令操作
LCD_RW = 0; //写操作
LCD_PORT = cmd; //送命令cmd
LCD_E = 1; //打开LCD使能
Delay2us; //短暂延时
LCD_E = 0; //关闭LCD使能
LCD_RW = 1;//读操作,关闭写操作
}

//写数据

void LCD_WR_DATA(U8 da)
{
CheckBusy();//检测忙信号
LCD_RS = 1; //数据操作
LCD_RW = 0; //写操作
LCD_PORT = da; //送数据da
LCD_E = 1; //打开LCD使能
Delay2us; //短暂延时
LCD_E = 0; //关闭LCD使能
LCD_RW = 1; //读操作,关闭写操作
}

//全屏写命令
void LCD_ALL_WR_CMD(U8 cmd)
{
LCD_CS_SELECT(LCD_CS_ALL); //选择全屏
LCD_WR_CMD(cmd);
}

//全屏写数据
void LCD_ALL_WR_DATA(U8 da)
{
LCD_CS_SELECT(LCD_CS_ALL); //选择全屏
LCD_WR_DATA(da);
}
//LCD左屏写命令
void LCD_L_WR_CMD(U8 cmd)
{
LCD_CS_SELECT(LCD_CS_LEFT); //选择左屏
LCD_WR_CMD(cmd);
}
//LCD右屏写命令
void LCD_R_WR_CMD(U8 cmd)
{
LCD_CS_SELECT(LCD_CS_RIGHT); //选择右屏
LCD_WR_CMD(cmd);
}
//LCD左屏写数据
void LCD_L_WR_DATA(U8 da)
{
LCD_CS_SELECT(LCD_CS_LEFT); //选择左屏
LCD_WR_DATA(da);
}
//LCD右屏写数据
void LCD_R_WR_DATA(U8 da)
{
LCD_CS_SELECT(LCD_CS_RIGHT); //选择右屏
LCD_WR_DATA(da);
}
//LCD清屏
void CLR_SCREEN(void)
{
U8 temp,j;
for(temp=0;temp<8;temp++)
{
LCD_ALL_WR_CMD(0xb8+temp); //写行地址命令
LCD_ALL_WR_CMD(0x40); // 写列地址命令
for(j=0;j<64;j++)
{
LCD_ALL_WR_CMD(0x40+j);//写要清的列地址
LCD_ALL_WR_DATA(0x00); //送数据0x00
}
}
}
void LCD_INFO_CONFIG(LCD_INFO *self,FLASH *page)//写信息配置
{
U8 temp;
self->ROW = x;
self->COL = y;
self->NumALL = n;
for(temp=0;temp<16;temp++)//清索引缓存
{
self->ZKIndex[temp] = 0;
}
for(temp=0;temp<n;temp++)//传递索引数据
{
self->ZKIndex[temp] = page[temp];
}
}
void LCD_WR_CHAR(LCD_INFO *self)//写8x8字符
{
U8 temp;
U8 total;
for(total=0;total<self->NumALL;total++)
{
if(((self->COL)+total)<8) //0-7为左屏
{
LCD_L_WR_CMD(PAGE_ADDRESS+(self->ROW)); //写行地址
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*8);//写列地址
for(temp=0;temp<8;temp++)
{
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*8+temp);//写要写入数据的列地址命令
LCD_L_WR_DATA(ZK8x8[(self->ZKIndex[total])*8+temp]);//写数据到左屏
}
}
else //8-15为右屏
{
LCD_R_WR_CMD(PAGE_ADDRESS+(self->ROW)); //写行地址
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*8);//写列地址
for(temp=0;temp<8;temp++)
{
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*8+temp);//写要写入数据的列地址命令
LCD_R_WR_DATA(ZK8x8[(self->ZKIndex[total])*8+temp]);//写数据到右屏
}
}
}
}
void LCD_WR_HZ(LCD_INFO *self)//写16x16汉字
{
U8 temp;
U8 total;
for(total=0;total<self->NumALL;total++)
{
if(((self->COL)+total)<4) //0-3为左屏
{
LCD_L_WR_CMD(PAGE_ADDRESS+(self->ROW));
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16);
for(temp=0;temp<16;temp++)
{
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16+temp);
LCD_L_WR_DATA(ZK16x16[(self->ZKIndex[total])*32+temp]);
}
LCD_L_WR_CMD(PAGE_ADDRESS+(self->ROW)+1);
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16);
for(temp=0;temp<16;temp++)
{
LCD_L_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16+temp);
LCD_L_WR_DATA(ZK16x16[(self->ZKIndex[total])*32+16+temp]);
}
}
else //4-7为右屏
{
LCD_R_WR_CMD(PAGE_ADDRESS+(self->ROW));
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16);
for(temp=0;temp<16;temp++)
{
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16+temp);
LCD_R_WR_DATA(ZK16x16[(self->ZKIndex[total])*32+temp]);
}
LCD_R_WR_CMD(PAGE_ADDRESS+(self->ROW)+1);
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16);
for(temp=0;temp<16;temp++)
{
LCD_R_WR_CMD(LIE_ADDRESS+((self->COL)+total)*16+temp);
LCD_R_WR_DATA(ZK16x16[(self->ZKIndex[total])*32+16+temp]);
}
}
}
}
//LCD初始化
void LCD_Initial(void)
{
CLR_SCREEN();//清屏
LCD_ALL_WR_CMD(0x3f);//0x3f打开LCD
}

3 函数调用

FLASH page0[]={0,1,2,3,4,5}; //thanks
FLASH page1[]={0,4}; //李跃忠老师
FLASH page2[]={6,6,6}; //---
FLASH page3[]={5,7}; //刘园珍
LCD_INFO MenuInfo;
void Menu(void);
void main(void)
{
LCD_Initial(); //LCD初始化
while(1)
{
Menu(); //调用显示菜单函数
}
}
void Menu(void)
{
LCD_INFO_CONFIG(&MenuInfo,page0);//initial "thanks"
LCD_WR_CHAR(&MenuInfo);
LCD_INFO_CONFIG(&MenuInfo,8,5,page1);//initial "李跃忠老师"
LCD_WR_HZ(&MenuInfo);
LCD_INFO_CONFIG(&MenuInfo,page2);//initial "---"
LCD_WR_CHAR(&MenuInfo);
LCD_INFO_CONFIG(&MenuInfo,page3);//initial "刘园珍"
LCD_WR_HZ(&MenuInfo);
}

4 总结

为什么强调使用枚举,结构体,指针-数组等方式来编写代码,完全是为了实现代码灵活,代码规范性和模块化实现。现在我在编程的过程中养成了这个习惯,在实现功能的前提下要求自己使用以上我说的方式来编写代码。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读