📄 lcd1602._c
字号:
#include <iom8v.h>
#include <macros.h>
#include "LCD1602.h"
/**********************************************************
光标命令
lcd_write_command(0x0e,0);//光标开
lcd_write_command(0x0d,0);//光标所在字符闪烁
lcd_write_command(0x0c,0); //光标关
lcd_write_command(0x07,0); //屏幕左移
**********************************************************/
/*------------------------------------液晶驱动函数-------------------------------------*/
void lcd_init_portDB(void)
{
lcd_data_port=0xff;
lcd_data_ddr=0xff;
lcd_control_port=0x07;
lcd_control_ddr=0x07;
}
//液晶初始化
void lcd_init(void)
{
delay_nms(15);
lcd_write_command(0x38,0);//显示模式设置三次(此时不管lcd空闲与否)
delay_nms(5);
lcd_write_command(0x38,0);
delay_nms(5);
lcd_write_command(0x38,0);
delay_nms(5);
lcd_write_command(0x38,1);//显示模式设置(从此之后均需lcd空闲)
lcd_write_command(0x08,1);//显示关闭
lcd_write_command(0x01,1);//显示清屏
lcd_write_command(0x06,1);//显示光标移动设置
lcd_write_command(0x0c,1);//显示开及光标设置
}
//写指令函数: E=高脉冲 RS=0 RW=0
void lcd_write_command(unsigned char command,unsigned char wait_en)//command为指令,wait_en指定是否要检测LCD忙信号
{
if(wait_en)wait_enable();//若wait_en为1,则要检测LCD忙信号,等待其空闲
lcd_control_port&=~lcd_RS;//RS=0
lcd_control_port&=~lcd_RW;//RW=0
lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
NOP();
lcd_control_port|=lcd_EN;//E=1
lcd_data_port=command;
lcd_control_port&=~lcd_EN;//重设E=0
}
//写数据函数: E =高脉冲 RS=1 RW=0
void lcd_write_data(unsigned char char_data)
{
wait_enable();//等待LCD空闲
lcd_control_port|=lcd_RS;//RS=1
lcd_control_port&=~lcd_RW;//RW=0
lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
NOP();
lcd_control_port|=lcd_EN;//E=1
lcd_data_port=char_data;
lcd_control_port&=~lcd_EN;//重设E=0
}
//正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。
//检测忙信号,等待LCD空闲函数
void wait_enable(void)
{
lcd_busy_ddr&=~busy;//设置busy口为输入
lcd_control_port&=~lcd_RS;//RS=0
lcd_control_port|=lcd_RW;//RW=1
NOP();
lcd_control_port|=lcd_EN;//E=1
while(lcd_busy_pin&busy);//等待LCD_DB7为0
lcd_control_port&=~lcd_EN;//重设E=0
lcd_busy_ddr|=busy;//设置busy口为输出
}
/**LCD_set_xy:设置LCD显示的起始位置输入参数:x、y :
显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0X80-0X8F
LCD第一行显示寄存器地址:0XC0-0XCF ***/
void lcd_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0)
address = 0x80 + x;
else
address = 0xc0 + x;
lcd_write_command(address,1);//一定需要检查忙信号,所以为1
}
//显示一个字符函数
void display_a_char(unsigned char x,unsigned char y,unsigned char char_data)//char_data为要显示的字符
{
lcd_set_xy(x,y);
lcd_write_data(char_data);
}
//指定一行显示连续字符串:0显示在第一行,1显示在第二行,注字符串不能长于16个字符
//显示一行连续字符串函数
void display_a_string(unsigned char x,unsigned char y,unsigned char *ptr)
{
//ptr:指向无符号字符型变量的指针变量,指针也就是地址,指字符串数组的首指针
lcd_set_xy(x,y);
while(*ptr)//当ptr='\0'(空指针null)跳出循环
{
lcd_write_data(*ptr);//*ptr,指向该地址的内容
ptr++;
}
}
/*********************流动字幕***********************/
void display_a_fluid(unsigned char x,unsigned char y,unsigned char *ptr)
{ lcd_write_command(0x07,1);//流动字幕
lcd_set_xy(x,y);
while(*ptr)
{
lcd_write_data(*ptr);
delay_nms(200);
ptr++;
}
}
void delay_1ms(void ) //延时1ms
{
unsigned int i ;
unsigned char xtal;
xtal=4;
for (i=1;i<(xtal*143-2);i++)
{
;
}
}
void delay_nms(unsigned int n) //延时nms
{
unsigned int i=0 ;
for(i=0;i<n;i++)
{
delay_1ms();
}
}
void keyboard(void)
{
int i;
while (1)
{
i=~PIND;
i&=0xf0;
if(i==speedadd) {
if(setspeed==maxspeed)setspeed=minspeed;
else setspeed++;
conver_BCD(1000,str10);
lcd_write_command(0x01,0);
lcd_display_full();
}
if(i==speeddec){
if(setspeed==minspeed)setspeed=maxspeed;
else setspeed--;
lcd_write_command(0x01,0);
I++;
if (I>=3)I=0;
lcd_display_full();
}
if(i==speedok) {
break;
}
delay_nms(100);
}
}
///////////////////////////////////////////////////////////////
void display_a_fluid(unsigned char x,unsigned char y,unsigned char *ptr)
{ lcd_write_command(0x07,1);//流动字幕
lcd_set_xy(x,y);
while(*ptr)
{
lcd_write_data(*ptr);
delay_nms(200);
ptr++;
}
}
//------------------------------------------------------
void copy (unsigned char x[],unsigned char *y,unsigned char i)
{
while (*y){x[i]=*y; *y++; i++;}
}
//------------------------------------------------------------
void lcd_display_full(void)
{
if(I==0){lcd_display(str1,str10,str2,str20);}
if(I==1){lcd_display(str2,str20,str3,str30);}
if(I==2){lcd_display(str3,str30,str4,str40);}
if(I==3){lcd_display(str4,str40,str1,str10);}
}
//------------------------------------------------------------------------
void lcd_display(unsigned char x0[],unsigned char x1[],unsigned char y0[],unsigned char y1[])
{
display_a_string(0,0,x0);
display_a_string(7,0,x1);
display_a_string(0,1,y0);
display_a_string(7,1,y1);
}
void conver_BCD(int x,unsigned char string[])
{int i;
for(i=0;i<4;i++)
{string[i]=(char)x%10;x/=10;}
}
/***********这些是1602的流动字幕的一些程序
display_a_fluid(16,0,welcome);
lcd_write_command(0x01,1);//显示清屏
lcd_write_command(0x06,1);//显示光标移动设置 */
/*lcd_write_command(0x07,1); //屏幕右移,内容左移
lcd_set_xy(8,0);
for(i=0;welcome[i]!='\0';i++)
{
lcd_write_data(welcome[i]);
delay_nms(200);
}
lcd_write_command(0x01,1);//显示清屏
lcd_write_command(0x06,1);//显示光标移动设置 */
/* 键盘判断
DDRD&=0X0F;
PORTD|=0xf0;
testkey=PIND;
testkey=~testkey;
testkey&=0xf0; */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -