/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "NUC1xx.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSYS.h"
#include "LCD1602.h"
int main(void)
{
UNLOCKREG(); // 芯片注册解锁
SYSCLK->PWRCON.XTL12M_EN = 1; // 设定12M外部晶振
DrvSYS_Delay(5000); // 等待时钟就绪
LOCKREG();
LCD1602_Init();
LCD1602_WriteString(1,0,"hotpower-LOVE");
LCD1602_WriteString(0,1,"cortex-m0-10-26");
// DrvGPIO_ClrBit(E_GPA,2);
// DrvGPIO_ClrBit(E_GPA,3);
// DrvGPIO_ClrBit(E_GPA,4);
// DrvGPIO_ClrBit(E_GPA,5);
while(1);
}
/**********************************************
*****************************************/
#include "LCD1602.H"
#include "NUC1xx.h"
#include "DrvGPIO.h"
/*******************************************************************************
// 引脚定义 // (使用者根据实际更改)
******************************************************************************/
#define LCD_DB_Port E_GPA
//#define LCD_Ctr_Port E_PORT1
//#define LCD_PW_GND E_GPE,5,E_IO_OUTPUT //接LCD1602 VSSPin,需要强制输出0,做GND用
#define LCD_RS E_GPC,15
#define LCD_RW E_GPC,6
#define LCD_EN E_GPC,7
#define LCD_POWER_ON DrvGPIO_ClrBit(E_GPE,5); //接LCD1602 VSSPin,需要强制输出0,做GND用
#define LCD_VO_Adj DrvGPIO_ClrBit(E_GPC,14); //对比度调节
#define LCD_RS_Data DrvGPIO_SetBit(LCD_RS); // 数据寄存器
#define LCD_RS_Reg DrvGPIO_ClrBit(LCD_RS); // 指令寄存器
#define LCD_RW_Read DrvGPIO_SetBit(LCD_RW); // 读
#define LCD_RW_Write DrvGPIO_ClrBit(LCD_RW); // 写
#define LCD_EN_Set DrvGPIO_SetBit(E_GPC,7); // 高
#define LCD_EN_Clr DrvGPIO_ClrBit(E_GPC,7); // 低
//sbit LCD_RS = P1^0; //寄存器选择:1 数据;0 指令
//sbit LCD_RW = P1^1; //读写选择:1 读;0 写
//sbit LCD_EN = P1^2; //使能,读时为高电平,写时为高脉冲
//sbit LCD_Bsy= P0^7; //LCD DB7为忙检测端,1为忙,0为空闲
/*******************************************************************************
// 定义LCD1602指令集 // (详细请见技术手册)
******************************************************************************/
#define CMD_clear 0x01 // 清除屏幕
#define CMD_back 0x02 // DDRAM回零位
#define CMD_dec1 0x04 // 读入后AC(指针)减1,向左写
#define CMD_add1 0x06 // 读入后AC(指针)加1,向右写
#define CMD_dis_gb1 0x0f // 开显示_开光标_开光标闪烁
#define CMD_dis_gb2 0x0e // 开显示_开光标_关光标闪烁
#define CMD_dis_gb3 0x0c // 开显示_关光标_关光标闪烁
#define CMD_OFF_dis 0x08 // 关显示_关光标_关光标闪烁
#define CMD_set82 0x38 // 8位总线_2行显示
/*============================================================
液晶指令说明:
0x01-------------->清除屏幕,置AC为0,光标回位。
0x02-------------->DDRAM 地址为0,显示回原位,DDRAM内容不变.
0x03-------------->DDRAM 地址为0,显示回原位,DDRAM内容不变.
**********MODE指令************
0x04-------------->设置光标移动方向减量方式,并指定显示不移动。
0x05-------------->设置光标移动方向减量方式,并指定显示移动。
0x06-------------->设置光标移动方向增量方式,并指定显示不移动。
0x07-------------->设置光标移动方向增量方式,并指定显示移动。
**********DSPOFF指令************
0x08-------------->设置显示关、光标关、光标所在字符不闪烁.
**********DSPON指令************
0x0c-------------->显示开
0x0e-------------->显示开,光标开
0x0f-------------->显示开,光标开,光标闪烁
0x10-------------->光标移位,左移
0x14-------------->光标移位,右移
0x18-------------->显示移位,左移
0x1c-------------->显示移位,右移
**********INIT指令************
0x20-------------->4BIT模式,显示一行,5x7字体
0x24-------------->4BIT模式,显示一行,5x10字体
0x28-------------->4BIT模式,显示两行,5x7字体
0x2c-------------->4BIT模式,显示两行,5x10字体
0x30-------------->8BIT模式,显示一行,5x7字体
0x34-------------->8BIT模式,显示一行,5x10字体
0x38-------------->8BIT模式,显示两行,5x7字体
0x3c-------------->8BIT模式,显示两行,5x10字体
============================================================*/
unsigned char Table[] = {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00 // 日
};
static void LCD_GPIO_Init()
{
//DrvGPIO_Open(LCD_PW_GND); // 1602上电
LCD_POWER_ON;
LCD_VO_Adj;
}
void delaynms(unsigned char n)
{
unsigned char i,j;
unsigned int k;
i=2; //主频多少i就多少
//延时用这个很无奈,不同的系统有不同的方法
//好在只有初始化时使用,对系统影响不大
for(;i>0;i--)
{
for(j=0;j<n;j++)
{
for(k=0;k<980;k++);
}
}
}
/**********************************************************************
延时
**********************************************************************/
void delay_nus(unsigned int t)
{
unsigned int i=0;
while(t--)
{
for(i=0;i<1;i++);
}
}
/*******************************************************************************
描 述:忙检测 ,直到空闲时退出
参 数:无
返回值:无
备 注:LCD1602 DB7为1是,LCD1602忙,否则空闲。
******************************************************************************/
static void Checkbsy()
{
unsigned char temp;
do{
temp = ReadRegister(Com_Reg);
}while(temp & 0x80);
// LCD_RS = Com_Reg;
// LCD_RW = READ;
// LCD_DB = 0xff; //通过往端口写1,使单片机进入读模式
// LCD_EN = 1;
// while(LCD_Bsy); //等到LCD1602空闲时退出
// LCD_EN = 0;
}
/*******************************************************************************
描 述:写寄存器
参 数:_Register 要操作的寄存器(Com_reg 指令寄存器,Data_Reg 数据寄存器)
_Data 要写入的数据
返回值:无
备 注:
******************************************************************************/
static void WriteRegister(unsigned char _Register,int32_t _Data)
{
Checkbsy();
if(_Register != Data_Reg){
LCD_RS_Reg;
}else{
LCD_RS_Data;
}
// delay_nus(2);
LCD_RW_Write;
// delay_nus(2);
// LCD_RS = _Register;
// LCD_RW = WRITE;
// LCD_EN = 1;
DrvGPIO_SetPortBits(LCD_DB_Port,_Data<<2);
LCD_EN_Set;
//delay_nus(2);
// delay_nus(2);
//LCD_DB = _Data; //送数据
//LCD_EN = 0;
LCD_EN_Clr;
}
/*******************************************************************************
描 述:写CGROM
参 数:_len 要写入crgrom区的数据长度,_len最大为64
返回值:无
备 注:将预先定义好的字模写入cgram
******************************************************************************/
void CgramWrite(unsigned char _len)
{
unsigned char i;
WriteRegister(Com_Reg,0x06); // 设置cgrom地址自动加1
WriteRegister(Com_Reg,0x40); // cgrom 起始地址
for(i=0;i<_len;i++)
{
WriteRegister(Data_Reg,Table[i]); // 按数组写入数据
}
}
/*******************************************************************************
描 述:初始化LCD1602
参 数:
返回值:
备 注:8位2行显示,显示光标,闪烁
*******************************************************************************/
void LCD1602_Init(void)
{
LCD_GPIO_Init();
delaynms(15);
WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
//delaynms(150);
WriteRegister(Com_Reg,CMD_set82);
//delaynms(150);
WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
//delaynms(150);
WriteRegister(Com_Reg,CMD_set82);//8位点阵模式
WriteRegister(Com_Reg,CMD_clear);// 清屏
delaynms(15);
WriteRegister(Com_Reg,CMD_dis_gb1);// 开显示,显示光标,闪烁
CgramWrite(8);
WriteRegister(Com_Reg,CMD_clear);// 清屏
delaynms(15);
}
/*******************************************************************************
描 述:设置显示位置
参 数:x 列, y 行
返回值:
备 注:x和y均从0开始,y最大为1
*******************************************************************************/
static void LCD1602_SetXY(unsigned char x,unsigned char y)
{
if(y == 0)
{
WriteRegister(Com_Reg,0x80+x); // 第一行
}else{
WriteRegister(Com_Reg,0xC0+x); // 第二行
}
}
/*******************************************************************************
描 述:在指定位置显示一个字符
参 数:x 列, y 行 ,Data为要显示的字符
返回值:
备 注:x和y均从0开始,y最大为1
*******************************************************************************/
void LCD1602_WriteByte(unsigned char x,unsigned char y,unsigned char Data)
{
LCD1602_SetXY(x,y); // 设置地址
WriteRegister(Data_Reg,Data); // 将要显示的字符写入数据寄存器
}
/*******************************************************************************
描 述:从指定位置开始显示字符串
参 数:x 列, y 行 ,*String为要显示的字符串
返回值:
备 注:x和y均从0开始,y最大为1
*******************************************************************************/
void LCD1602_WriteString(unsigned char x,unsigned char y,unsigned char *String)
{
LCD1602_SetXY(x,y);
while(*String) // 判断是否已经写完
{
WriteRegister(Data_Reg,*String++); // 写入当前指向的字符,并将指针指向下一个字符
}
}
/*******************************************************************************
描 述:读寄存器
参 数:_Register 要操作的寄存器(Com_reg 指令寄存器,Data_Reg 数据寄存器)
返回值:数据寄存器或指令寄存器的内容
备 注:
******************************************************************************/
unsigned char ReadRegister(unsigned char _Register)
{
int32_t Data; //声明一个变量,用来保存从lcd1602读取到的值
int32_t temp;
if(_Register != Data_Reg){
LCD_RS_Reg;
}else{
LCD_RS_Data;
}
//delay_nus(2);
LCD_RW_Read;
delay_nus(2);
// LCD_RS = _Register;
// LCD_RW = READ;
//DrvGPIO_SetPortBits(LCD_DB_Port,0xff);
//LCD_DB = 0xff; //通过往端口写1,使单片机进入读模式
//LCD_EN = 1;
LCD_EN_Set;
delay_nus(2);
Data = DrvGPIO_GetPortBits(LCD_DB_Port);
//delay_nus(2);
LCD_EN_Clr;
//delay_nus(2);
temp=Data>>2;
return (int8_t)(Data>>2); //返回到的值
}
/***********************************************
*****************************************/
#ifndef _LCD1602_H_
#define _LCD1602_H_
/*******************************************************************************
// 基本宏定义
******************************************************************************/
#define WRITE 0
#define READ 1
#define Com_Reg 0
#define Data_Reg 1
extern void LCD1602_Init(void);
extern void LCD1602_WriteByte(unsigned char x,unsigned char y,unsigned char Data);
extern void LCD1602_WriteString(unsigned char x,unsigned char y,unsigned char *String);
extern unsigned char ReadRegister(unsigned char _Register);
#endif
1602程序也是参照论坛里的示例,今天10月26号第三届选美,特来向大叔示爱
|