//-----------------------------------------------------------------
// 名称: 1602液晶头文件 LCD1602_4BIT.h
//-----------------------------------------------------------------
#ifndef _LCD1602_4BIT_H
#define _LCD1602_4BIT_H
#include <pic18.h> //可以省略
#define INT8U unsigned char
#define INT16U unsigned int
//#define _XTAL_FREQ 32000000UL
//LCD命令
#define _LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_SETMODE 0x04
#define LCD_SETVISIBLE 0x08
#define LCD_SHIFT 0x10
#define LCD_SETFUNCTION 0x20
#define LCD_SETCGADDR 0x40
#define LCD_SETDDADDR 0x80
//=================
//LCD控制引脚
#define RS LATBbits.LATB0
#define RW LATBbits.LATB1
#define E LATBbits.LATB2
//#define RS PORTBbits.RB0 //PIC16单片机用法
//#define RW PORTBbits.RB1
//#define E PORTBbits.RB2
//LCD数据与方向端口定义
#define PORT_LCD_DAT PORTB //读引脚用PORTB,不用LATB
#define TRIS_LCD_DAT TRISB
#define LATB_LCD_CTL LATB //控制口
//#define TRIS_LCD_CTL TRISB //控制口方向寄存器
//-----------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------
void LCD_Initialize(void);
void LCD_BUSY_WAIT(void);
void ClearScreen(void);
void Write_LCD_Command (INT8U data);
void Write_LCD_Data(INT8U data);
void Set_LCD_POS(INT8U r, INT8U c);
void LCD_ShowString(INT8U r, INT8U c,char *str);
void LCD_ShowChar(INT8U r, INT8U c,char ch);
void delay(INT16U xms); //? ms MHZ
#endif
//#endif //多一个也没关系
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------
// 名称: 1602液晶C文件 LCD1602_4BIT.c
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// 名称: 工作于四位模式的1602LCD显示程序 参考pic16f877程序
//-----------------------------------------------------------------
#define _XTAL_FREQ 32000000UL //32MHZ晶振
#include <pic18.h>
#define INT8U unsigned char
#define INT16U unsigned int
#include "LCD1602_4BIT.h"
void delay(INT16U xms) ////延时283us@32MHZ
{
INT16U a,b;
for(a=xms;a>0;a--)
for(b=320;b>0;b--);
}
//-----------------------------------------------------------------
// 液晶初始化
//-----------------------------------------------------------------
void LCD_Initialize(void)
{
Write_LCD_Command(LCD_SETFUNCTION + 0x08); //0x28,4位模式,双行,5x7点阵
delay(15);
Write_LCD_Command(LCD_SETFUNCTION + 0x08); //4位模式,双行,5x7点阵
delay(15);
Write_LCD_Command(LCD_SETFUNCTION + 0x08); //4位模式,双行,5x7点阵
delay(15);
//以上3句属软件启动,后两句后加的,避免下载后不显示,须关闭电源重开机才显示正常
Write_LCD_Command(LCD_SETVISIBLE + 0x04); //0x0c,开显示光标,不闪烁
delay(15);
//Write_LCD_Command(LCD_SETMODE + 0x02); //模式设置0x06,自动递增
delay(15);
Write_LCD_Command(0x01); //清屏
delay(15);
Write_LCD_Command(0x0f);delay(15); //开显示,显示光标,光标闪烁
//Write_LCD_Command(0x06);delay(15); //光标右移
Write_LCD_Command(0x80);delay(15); //首行显示位置
}
//-----------------------------------------------------------------
// 清除屏幕
//-----------------------------------------------------------------
void ClearScreen(void)
{
Write_LCD_Command(_LCD_CLEAR); //清屏
Write_LCD_Command(LCD_SETDDADDR + 0x00); //光标归位
}
//-----------------------------------------------------------------
// 写LCD命令
//-----------------------------------------------------------------
void Write_LCD_Command(unsigned char cmd)
{
TRIS_LCD_DAT = 0x00; //输出口
//delay(5)接近1500us @32MHZ 共2个delay(5)改为__delay_ms(2)偏慢,调用库函数慢
//PORT_LCD_DAT = (cmd & 0xf0) | 0x04;delay(5); //仿真延时取消也可以
//PORT_LCD_DAT &= 0xfb; // E = 0; //取高4位数据 成功
LATB = cmd & 0xf0;
RS = 0; RW = 0;E = 1;delay(5);E = 0;
//PORT_LCD_DAT = (cmd << 4) | 0x04;delay(5); //仿真延时取消也可以
LATB = cmd << 4;
//PORT_LCD_DAT &= 0xfb; // E = 0; //取低4位数据
RS = 0; RW = 0; E = 1;delay(5);E = 0;
LCD_BUSY_WAIT();
}
//-----------------------------------------------------------------
// 写LCD数据
//-----------------------------------------------------------------
void Write_LCD_Data(unsigned char dat)
{
LCD_BUSY_WAIT();
TRIS_LCD_DAT = 0x00; //输出口
//delay(5)接近1500us @32MHZ 共2个delay(5)改为__delay_ms(2)偏慢,调用库函数慢
//PORT_LCD_DAT = (dat & 0xf0) | 0x05; delay(5); //仿真延时取消也可以
//PORT_LCD_DAT &= 0xfb; //E = 0;
LATB = dat & 0xf0;
RS = 1; RW = 0; E = 1;delay(5);E = 0; //取高4位数据
//PORT_LCD_DAT = (dat << 4) | 0x05; delay(5); //仿真延时取消也可以
//PORT_LCD_DAT &= 0xfb; //E = 0; //取低4位数据
LATB = dat << 4;
RS = 1; RW = 0;E = 1;delay(5);E = 0;
}
//-----------------------------------------------------------------
// LCD忙等待
//-----------------------------------------------------------------
void LCD_BUSY_WAIT(void)
{
INT8U Hi,Lo;
TRIS_LCD_DAT = 0xf0; //高4位输入,低4位输出
//delay(5) delay(10)需2分12秒显示,单个字符定位准确,显示字符串完整 32MHZ
//delay(5)接近1500us @32MHZ 共4个delay(5)改为__delay_ms(2)
//用__delay_ms(2)仿真用4分钟显示字符
do{
//PORT_LCD_DAT = 0x00; //端口写0
LATB=0x00; //寄存器写0
RW = 1;RS = 0;
E = 1;delay(5);Hi = PORT_LCD_DAT;delay(5);E = 0; //这里不能加延时
E = 1;delay(5);Lo = PORT_LCD_DAT;delay(5);E = 0;
//PORT_LCD_DAT = 0x06;__delay_ms(2);Hi = PORT_LCD_DAT;__delay_ms(2);E = 0;
//PORT_LCD_DAT |= 0x04;__delay_ms(2);Lo = PORT_LCD_DAT;__delay_ms(2);E = 0;
}while(Hi & 0x80);
}
//-----------------------------------------------------------------
// 设置显示位置(行,列)
//-----------------------------------------------------------------
void Set_LCD_POS(INT8U r, INT8U c)
{
//
if(r == 0) Write_LCD_Command(0x80 | c);
else if(r == 1) Write_LCD_Command(0xc0 | c);
}
//-----------------------------------------------------------------
// 显示字符串(行,列,字符串)
//-----------------------------------------------------------------
void LCD_ShowString(INT8U r, INT8U c,char *str)
{
INT8U i;
Set_LCD_POS(r,c);
//
for(i = 0; i < 16 && str[i] != '\0';i++)
{ Write_LCD_Data(str[i]); }
//
//while(i < 16)
// {Write_LCD_Data(' ');i++; }
}
//-----------------------------------------------------------------
// 显示字符(行,列,字符)
//-----------------------------------------------------------------
void LCD_ShowChar(INT8U r, INT8U c,char ch)
{
Set_LCD_POS(r,c);
Write_LCD_Data(ch);
}
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//PIC18F4520单片机
// MPLAB IDE V8.60 picc18编译器,支持picc16f的编译器
#include <pic18.h>
//#include <delays.h>
//#include <stdio.h>
//#include <XLCD.h>
//__PROG_CONFIG(1,0xc800); //
//默认0x0700, 0xc800使能振荡器切换,使能故障保护时钟监视,内部振荡RA6/7作端口引脚
//__PROG_CONFIG(1,0xc100); //PIC的配置字1,使能振荡器切换,使能故障保护时钟监视,XT振荡模式
//__PROG_CONFIG(1,0x4800); //不使能振荡器切换,使能故障保护时钟监视,内部振荡RA6/7作端口引脚
//__PROG_CONFIG(1,0xc200); //PIC的配置字1 0xc200外部HS振荡
__PROG_CONFIG(2,0x0A16); //PIC的配置字2
__PROG_CONFIG(3,0x8100); //PIC的配置字3
__PROG_CONFIG(4,0x0081); //PIC的配置字4
__PROG_CONFIG(5,0xC00F); //PIC的配置字5
__PROG_CONFIG(6,0xE00F); //PIC的配置字6
__PROG_CONFIG(7,0x400F); //PIC的配置字7
#include "LCD1602_4BIT.h"
#define _XTAL_FREQ 32000000UL //8MHZ晶振
//32MHZ时钟可以采用最大的延时库函数 __delay_ms(20);
#define INT8U unsigned char
#define INT16U unsigned int
//PIC18F4520系统时钟源初始化
void PIC18_OSC_Init(void)
{
OSCCON = 0x70; //PIC18F4520的OSCCONbits.IRCF2:0=111内部RC时钟源8MHZ
OSCTUNEbits.PLLEN = 1; //使能内部4倍PLL功能 32MHZ
}
void main(void)
{
CMCON = 0x07; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
TRISA = 0x00;
//PIC18_OSC_Init( ); // MHZ
delay(2000);
LCD_Initialize(); // Initialize LCD
delay(2000);
//检测液晶屏显示情况
LCD_ShowChar(0,15,'H'); //第0行1列显示字符'H'(行,列,字符)
//LCD_ShowChar(1,0,'A'); //第0行1列显示字符'A'(行,列,字符)
delay(2000);delay(20);delay(20);
LCD_ShowString(0,3,"Testing TC74"); //第0行0列显示(行,列,字符串)
// LCD_ShowString(1,1,"Thermal sensor"); //第1行0列显示
//__delay_ms(20);__delay_ms(20);__delay_ms(20);__delay_ms(20);
delay(1); //延时283us@32MHZ
//Write_LCD_Command(_LCD_CLEAR); // CLEAR display
PORTA = 0xff; delay(2000);
PORTA = 0x00; delay(2000);
while(1);
}
pic16f877仿真通过
|