我自从买了1602,反反复复对照了好几个程序,反复修改,就是不显示。我是在不明白,我一度怀疑我的1602是坏的,但也没有新的可以用,请大家先帮我看看程序写的有问题吗???或者那些地方容易出错???程序可能有点乱,因为前前后后修改了好几遍,像赋值数据端口有像这样的额“LCD1602_DATA_PORT = byte ”也有像这样的“ GPIO_SET_OUT_DATA(PB,0x0f);”,但实质是一样的。
#include <stdio.h>
#include "M451Series.h"
#include "LCD.h"
#define LCD1602_BUS_NUM 4
//8位数据总线,DB0-DB7 按顺序接到一个IO口的 0-7位
//4位总线,DB4 - DB7 按顺序接到一个IO口的 4-7位,液晶上的DB0-DB3空着,IO口上的0-3位可以正常作为其他用途
#define LCD1602_DATA_PORT PB->DOUT // LCD1602的数据总线
//这里采用新唐本身的函数
#define LCD1602_RS PC0 // LCD1602的RS
#define LCD1602_RW PC1 // LCD1602的RW
#define LCD1602_E PC2 // LCD1602的E控制线
#define LCD1602_Busy PB7 // 定义LCD1602的测忙线,应该是LCD1602_DB0_DB7的第8``````````````````````````````````````````````````````````````````````````````````````位IO口
#define LCD1602_LINE1_HEAD 0x80
#define LCD1602_LINE2_HEAD 0xC0
extern void Delayms(uint32_t);
extern void Delayus(uint32_t);
//********************************************************************************************
// 读LCD忙程序 [底层协议] // (所有底层协议都无需关注)
// LCD1602测忙,若LCD1602处于忙状态,本函数将等待至非忙状态
//********************************************************************************************/
void LCD1602_TestBusy(void){
LCD1602_DATA_PORT = 0xff; //设备读状态
CLK_SysTickDelay(5);
LCD1602_RS = 0; //RS=0指指令
CLK_SysTickDelay(5);
LCD1602_RW = 1; //RW=1为读
LCD1602_E = 1;
while(LCD1602_Busy); //等待LCD不忙
LCD1602_E = 0;
}
//向LCD1602写入一个指令或者数据
//R_S 1是数据 0是命令
void LCD1602_WriteByte(uint8_t R_S, uint8_t byte)
{
//LCD1602_TestBusy();
LCD1602_RS = R_S;
LCD1602_RW = 0;
#if (LCD1602_BUS_NUM == 8) //8位总线
LCD1602_E = 0;
LCD1602_DATA_PORT = byte;
CLK_SysTickDelay(5);
LCD1602_E = 1;
CLK_SysTickDelay(5);
LCD1602_E = 0;
#elif (LCD1602_BUS_NUM == 4) //4位总线
GPIO_SET_OUT_DATA(PB,0x0f); //高四位清0
GPIO_SET_OUT_DATA(PB,(byte&0xf0));//送入高四位数据
LCD1602_E = 0;
CLK_SysTickDelay(5);
LCD1602_E = 1;
CLK_SysTickDelay(5);
LCD1602_E = 0;
GPIO_SET_OUT_DATA(PB,0x0f); //高四位清0
GPIO_SET_OUT_DATA(PB,(byte<<4&0xf0));//送入低四位数据
CLK_SysTickDelay(5);
LCD1602_E = 1;
CLK_SysTickDelay(5);
LCD1602_E = 0;
#endif
}
void LCD1602_WriteCMD(uint8_t LCD1602_command) {
LCD1602_WriteByte(0x00,LCD1602_command);
}
void LCD1602_WriteData(uint8_t LCD1602_data){
LCD1602_WriteByte(0x01,LCD1602_data);
}
//********************************************************************************************
// 打印字符串程序 // (本函数调用指针函数)
//在第x行 第y列 开始显示字符串
//字符串最长48个
//********************************************************************************************/
void LCD1602_SetXY(uint8_t x,uint8_t y)
{
uint8_t address;
if(x>2 || x ==0) x = 1;
if(y>40 || y == 0) y = 1;
if(y == 1)
{
address=LCD1602_LINE1_HEAD+x;
}
else
{
address=LCD1602_LINE2_HEAD+x;
}
LCD1602_WriteByte(0,address);
}
void LCD1602_PrintString(uint8_t x,uint8_t y,char *str){
LCD1602_SetXY(x,y);
//Delayus(50);
while(*str != 0){
LCD1602_WriteByte(1,*str++);
}
}
//********************************************************************************************
// 打印单字符程序 //
//在第x行 第y列 显示字符
//* *******************************************************************************************/
void LCD1602_PrintChar(uint8_t x,uint8_t y,char t){
LCD1602_SetXY(x,y);
LCD1602_WriteByte(1,t);
}
void LCD1602_ClearScreen(void)
{
LCD1602_WriteByte(0,0x01);
Delayms(5);
}
//********************************************************************************************
// LCD初始化 //(使用者可自定义,加 * 号程序行必须保留但可修改)
//********************************************************************************************/
void LCD1602_Init(void){
LCD1602_DATA_PORT = 0;
#if (LCD1602_BUS_NUM == 8) //8位总线
LCD1602_WriteByte(0,0x38); // 8总线,显示2行,每个字符为5*7个像素
// Delayms(5);
// LCD1602_WriteByte(0,0x38);
// Delayms(5);
// LCD1602_WriteByte(0,0x38);
// Delayms(5);
// LCD1602_WriteByte(0,0x38);
#elif (LCD1602_BUS_NUM == 4) //4位总线
LCD1602_WriteCMD(0x28); // 4总线,显示2行,每个字符为5*7个像素
//需要设置两次
LCD1602_WriteCMD(0x28); // 先不改
#endif
LCD1602_WriteByte(0,0x01); //显示清屏
LCD1602_WriteByte(0,0x02); // 数据指针指向第1行第1个字符位置
LCD1602_WriteByte(0,0x06); // 显示光标移动设置:文字不动,光标右移
LCD1602_WriteByte(0,0x0c); // 显示开及光标设置:显示开,光标开,闪烁开
}
|