本帖最后由 xiaohuihui241 于 2013-9-4 21:17 编辑
各位大侠,本人使用的是AT91sam7x256单片机和LCD1602,出现了很奇怪的问题,希望得到大家的帮助,主要问题如下:
图1
图2
看了以上两个图片,让大家先有个感官认识,然后听我叙述一下这个问题吧,前提:图1、图2是在同一个对比度下的显示,而且使用同样的程序运行。
在使用AXD进行仿真的时候能够出现图1的显示,能够按照我程序的要求显示,但是貌似亮度很暗,显示有鬼影的情况。但是将程序下载到Flash中以后,脱机运行,上电后择时而出现图1的状态,时而出现图2的状态,并且几次掉电再上电试验中,出现图2情况几率要远大于出现图1的情况,大概就是这个情况,不知道大侠们有没有明白,如果知道原因,希望不吝赐教,小弟多谢了~~~
附上LCD1602.c看看能不能发现问题~~~
#include "1602.h"
#include "/at91sam7x256/include/AT91SAM7X256.h"
#include "/at91sam7x256/include/lib_AT91SAM7X256.h"
LCD1602ControlPortStruct *SetControlPort;
LCD1602ControlPortStruct *ClearControlPort;
void delay_1us(void)
{
int i;
for(i=0;i<5;i++);
}
void delay_nus(unsigned int n)
{
while(n--)
delay_1us();
}
/////\brief 设定液晶的控制端口
/////\param Port 控制端口的地址
/////\note 已经包含了液晶的初始化过程,在调用该函数之前应初始化相应的端口
void LCD1602_initPort( unsigned int SetPort, unsigned int ClearPort)
{
SetControlPort = (LCD1602ControlPortStruct *)SetPort;
ClearControlPort = (LCD1602ControlPortStruct *)ClearPort;
LCD1602_Reset();
}
//
///\brief 初始化液晶
void LCD1602_Reset(void)
{
LCD1602_WriteCommand(LCD_MODE_BIT_4);
LCD1602_WriteCommand(LCD_MODE_LINE_2);
LCD1602_WriteCommand(LCD_DISP_DISP_ON);
LCD1602_WriteCommand(LCD_CLEAR);
delay_nus(3000);
}
//
/////\brief 向液晶发送一个比特的数据
/////\param data 发送的数据
void LCD_en_write(void) //液晶使能
{
/*EN端为使能端,当EN端由高电平跳变成低电平时,液晶模块执行命令*/
//SetControlPort->EN = H;
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, 1 << 14);
delay_1us();
//ClearControlPort->EN = L;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, 1 << 14);
}
void LCD1602_WriteByte(unsigned char data)
{
//ClearControlPort->DATA=0XF; //恢复DATA IO口
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, 1 << 27 | 1 << 28 | 1 << 29 | 1 << 30);
SetControlPort->DATA = data >> 4;//写高四位
//AT91F_PIO_SetOutput(AT91C_BASE_PIOB, 1 << 21);
LCD_en_write();
//ClearControlPort->DATA=0XF; //恢复DATA IO口
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, 1 << 27 | 1 << 28 | 1 << 29 | 1 << 30);
SetControlPort->DATA = data;//写低四位
LCD_en_write();
}
//
/////\brief 向液晶发送一个比特的命令
/////\param command 发送的命令
void LCD1602_WriteCommand(unsigned char command)
{
delay_nus(50);
/*RS高电平时选择数据寄存器、低电平时选择指令寄存器*/
//ClearControlPort->RS = L;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, 1 << 12);
LCD1602_WriteByte(command);
}
///\brief 在液晶的当前位置显示一个字符
///\param data 显示的字符
void LCD1602_WriteChar(unsigned char data)
{
delay_nus(50);
/*RS高电平时选择数据寄存器、低电平时选择指令寄存器*/
//SetControlPort->RS = H;
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, 1 << 12);
LCD1602_WriteByte(data);
}
//
/////\brief 设定当前的显示位置
/////\param X 列数
/////\param Y 行数
void LCD1602_SetXY(unsigned char X, unsigned char Y)
{
unsigned char address;
X%=16;
Y%=2;
address = (Y == 0) ? (0x80 + X) : (0xc0 + X);
LCD1602_WriteCommand(address);
}
void LCD1602_write_char(unsigned char x,unsigned y,unsigned char data)
{
LCD1602_SetXY(x,y);
LCD1602_WriteChar(data);
}
//
/////\brief 在当前位置显示一个字符串
/////\param s 字符串的首地址
void LCD1602_WriteString(unsigned char *s)
{
//LCD1602_SetXY(0,0);
while (*s != 0)
LCD1602_WriteCommand(*s++);
}
void LCD_write_Data(unsigned char X,unsigned char Y,unsigned char Z,unsigned int Data)
{
unsigned char i=0,p[16],count=1;
Z=(X+1)>Z? Z:(X+1);
for(i=0;i<Z;i++)
{
p=Data%10;
LCD1602_SetXY(X,Y);
if(count) LCD1602_WriteChar(0X30+p);
else LCD1602_WriteChar(' ');
Data=Data/10;
if(Data==0) count=0;
}
}
/////\brief 清屏
void LCD1602_Clear(void)
{
LCD1602_WriteCommand(LCD_CLEAR);
}//
|