|
AVR四线法驱动1602,但是,只要一硬件复位,就出现异常。
烧写完程序还是正常的。
但是只要一复位,LCD上就多了“π, t”。再次复位,“π, t”消失,再次复位,“π, t”又消失。周而复始。
用的是ICC编译器。
下面贴出程序。
主函数:
#include <iom16v.h>
#include <macros.h>
#include"lcd1602.h"
void main(void)
{
// Port_init();
lcd_init();
//lcd_clear();
lcd_locate(1,4);
lcd_string("xGL");
}
LCD1602的C文件
#include "lcd1602.h"
void delay_lcd_us(unsigned int xus)/*us延时函数 8*0.125=1us*/
{
int i,j;
for(j=0;j<8;j++)
{
for (i=0;i<xus;i++)
NOP();
}
}
void delay_lcd_ms(unsigned int xms)/*ms延时函数*/
{
while(xms--)
{
unsigned int j;
for(j=1;j<=1332;j++);
}
}
void lcd_init(void) //显示屏初始化函数
{
//EN_CLR;
//lcd_clear();
DDRB = 0xFF; //I/O口方向设置
//LCD_DATA_DDR|=LCD_DATA|LCD_RS|LCD_EN; //数据口方向为输出
delay_lcd_ms(5); //上电延时,以使供电稳定
lcd_write_com(0x28); //4bit interface,2line,5*7dots
lcd_write_com(0x08); //关显示,不显光标,光标不闪烁
lcd_write_com(0x04); //写一字符,整屏显示不移动
lcd_clear(); //清屏
delay_lcd_ms(5);
lcd_write_com(0x0c); //开显示,光标、闪烁都关闭
//lcd_write_com(0x05); //写一字符,整屏右移
//lcd_write_com(0x06); //写一字符,整屏显示不移动
//lcd_write_com(0x07); //写一字符,整屏左移
//lcd_write_com(0x0B); 关闭显示(不显示字符,只有背光亮)
//lcd_write_com(0x0D); //开显示,不显示光标,但光标闪烁
//lcd_write_com(0x0E); //开显示,显示光标,但光标不闪烁
//lcd_write_com(0x0F); //开显示,光标、闪烁均显示
}
void lcd_en_write(void) //LCD写时序控制EN端产生一个高电平脉冲,控制LCD写时序
{
EN_SET;
delay_lcd_us(5);
EN_CLR;
}
void lcd_clear(void)//清屏函数
{
lcd_write_com(0x01);
delay_lcd_ms(5);
}
void lcd_write_com(unsigned char lcd_com)//写指令函数
{
delay_lcd_us(35);
RS_CLR;
RW_CLR;
lcd_data_port&=0X0f; //清高四位
lcd_data_port|=(lcd_com&0Xf0); //写高四位
lcd_en_write(); //写入指令数据
delay_lcd_us(35);
lcd_com=lcd_com<<4; //低四位移到高四位
lcd_data_port&=0X0f; //清高四位
lcd_data_port|=(lcd_com&0Xf0); //写低四位
lcd_en_write(); //写入指令数据
}
void lcd_write_data(unsigned char lcd_data)//写数据函数
{
delay_lcd_us(35);
RS_SET;
RW_CLR;
lcd_data_port&=0X0f;//清高四位
lcd_data_port|=(lcd_data&0Xf0);//写高四位
lcd_en_write();//写入数据
delay_lcd_us(35);
lcd_data=lcd_data<<4;//低四位移到高四位
lcd_data_port&=0X0f;//清高四位
lcd_data_port|=(lcd_data&0Xf0);//写低四位
lcd_en_write();//写入指数据
}
//----------------- LCD显示定位函数,行、列定位----------------------------
void lcd_locate(unsigned char x,unsigned char y)
{ unsigned char aa;
if (x==1) aa=0x80;
if (x==2) aa=0x80+0x40;
lcd_write_com(aa+y-1);
}
void lcd_string(unsigned char const *DData ) //在1602LCD上显示一一串字符
{ unsigned char aa;
aa=0;
while(DData[aa]!='\0') //取字符串是否结束?
{ lcd_write_data(DData[aa]); //显示单个字符
aa++;
}
}
void lcd_1_char(unsigned char data_1_char) //在1602LCD上显示一个1位的整数
{ unsigned char lcd_table[2];
lcd_table[1]=data_1_char%10; //获得个位的数字
lcd_write_data(lcd_table[1]+0x30); //显示个位
}
//-------------------------------------------------------------------------
void lcd_2_char(unsigned char data_2_char) //在1602LCD上显示一个2位的整数
{ unsigned char lcd_table[3];
lcd_table[1]=data_2_char/10; //获得十位的数字
lcd_table[2]=data_2_char%10; //获得个位的数字
lcd_write_data(lcd_table[1]+0x30); //显示十位
lcd_write_data(lcd_table[2]+0x30); //显示个位
}
//------------------------------------------------------------------------
void lcd_3_char(unsigned char data_3_char) //在1602LCD上显示一个3位的整数
{ unsigned char lcd_table[4];
lcd_table[1]=data_3_char/100; //获得百位的数字
lcd_table[2]=data_3_char%100/10; //获得十位的数字
lcd_table[3]=data_3_char%10; //获得个位的数字
lcd_write_data(lcd_table[1]+0x30); //显示百位
lcd_write_data(lcd_table[2]+0x30); //显示十位
lcd_write_data(lcd_table[3]+0x30); //显示个位
}
//------------------------------------------------------------------------
void lcd_4_char(unsigned char data_4_char) //在1602LCD上显示一个4位的整数
{ unsigned char lcd_table[5];
lcd_table[1]=data_4_char/1000; //获得千位的数字
lcd_table[2]=data_4_char%1000/100; //获得百位的数字
lcd_table[3]=data_4_char%100/10; //获得十位的数字
lcd_table[4]=data_4_char%10; //获得个位的数字
lcd_write_data(lcd_table[1]+0x30); //显示千位
lcd_write_data(lcd_table[2]+0x30); //显示百位
lcd_write_data(lcd_table[3]+0x30); //显示十位
lcd_write_data(lcd_table[4]+0x30); //显示个位
}
//----------------------------------------------------------------------------------
void lcd_5_char(unsigned int data_char) //在1602LCD上显示一个5位的整数
{ unsigned char lcd_table[9];
lcd_table[1]=data_char%100000/10000; //获得万位的数字
lcd_table[2]=data_char%10000/1000; //获得千位的数字
lcd_table[3]=data_char%1000/100; //获得百位的数字
lcd_table[4]=data_char%100/10; //获得十位的数字
lcd_table[5]=data_char%10; //获得个位的数字
lcd_write_data(lcd_table[1]+0x30); //显示万位
lcd_write_data(lcd_table[2]+0x30); //显示千位
lcd_write_data(lcd_table[3]+0x30); //显示百位
lcd_write_data(lcd_table[4]+0x30); //显示十位
lcd_write_data(lcd_table[5]+0x30); //显示个位
}
//-------------------------------------------------------
void lcd_char(unsigned int data_char)
{ unsigned int n;
if(data_char>9999) n=1;
else if(data_char>999) n=2;
else if(data_char>99) n=3;
else if(data_char>9) n=4;
else n=5;
switch(n)
{
case 1:lcd_5_char(data_char); break;
case 2:lcd_4_char(data_char); break;
case 3:lcd_3_char(data_char); break;
case 4:lcd_2_char(data_char); break;
case 5:lcd_1_char(data_char); break;
default : break;
}
}
void lcd_float(float f_data) //在1602LCD上显示一个小于100、保留3位小数的浮点数
{ unsigned char lcd_table[5];
unsigned long aa;
aa=f_data*1000; //保留3位小数
lcd_table[0]= aa/10000 ; //分别获取各位上的数
lcd_table[1]= aa%10000/1000 ;
lcd_table[2]= aa%1000/100 ;
lcd_table[3]= aa%100/10 ;
lcd_table[4]= aa%10 ;
if (lcd_table[0]==0) lcd_write_data(' '); //如果整数部分的十位数是0则不显示(显示空格)
else lcd_write_data(lcd_table[0]+0x30); //显示整数部分的十位数,加上0x30以便直接得到相应的ASCII码去显示
lcd_write_data(lcd_table[1]+0x30); //显示整数部分的个位数
lcd_write_data('.'); //显示小数点"."
lcd_write_data(lcd_table[2]+0x30); //显示小数部分的十分位
lcd_write_data(lcd_table[3]+0x30); //显示小数部分的百分位
lcd_write_data(lcd_table[4]+0x30); //显示小数部分的千分位
}
。h文件
#ifndef __LCD1602_H__
#define __LCD1602_H__
#include <iom16v.h>
#include <macros.h>
#define lcd_data_port PORTB
//一定要用高4位
#define LCD_DATA_DDR DDRB
#define LCD_DATA ((1<<PB4)|(1<<PB5)|(1<<PB6)|(1<<PB7))
#define RS_CLR lcd_data_port&= ~(1 << PB1)
#define RS_SET lcd_data_port|= (1 << PB1)
#define EN_CLR lcd_data_port&= ~(1 << PB3)
#define EN_SET lcd_data_port|= (1 << PB3)
#define LCD_RS (1<<PB1)
#define LCD_EN (1<<PB3)
#define RW_CLR lcd_data_port&= ~(1 << PB2)
#define RW_SET lcd_data_port|= (1 << PB2)
void delay_lcd_us(unsigned int xus);
void delay_lcd_ms(unsigned int xms);
void lcd_init(void);
void lcd_en_write(void);
void lcd_clear(void);
void lcd_write_com(unsigned char lcd_com); //LCD送命令子函数
void lcd_write_data(unsigned char lcd_data); //LCD送显示数据子函数
void lcd_locate(unsigned char x,unsigned char y); //显示定位 x是行,y是列
void lcd_string(unsigned char const *DData);//显示字符串
void lcd_1_char(unsigned char data_1_char);//显示一位整数:
void lcd_2_char(unsigned char data_2_char);//显示二位整数:
void lcd_3_char(unsigned char data_3_char); //显示三位整数:
void lcd_4_char(unsigned char data_4_char); //显示四位整数:
void lcd_4_char(unsigned char data_5_char); //显示五位整数:
void lcd_char(unsigned int data_char); //显示任意位的整数
void lcd_float(float f_data); //在1602LCD上显示一个小于100、保留3位小数的浮点数
#endif /* LCD1602_H_ */ |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|