- /*---------------------------------------------------------------------------------------------------------*/
 
- /* */
 
- /* 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