📄 lcd1602._c
字号:
/****************************************Copyright (c)**************************************************
** ADEmbed Development Co.,LTD.
** http://www.adembed.com
**--------------File Info-------------------------------------------------------------------------------
** File name: lcd1602.c
** Last modified Date: 2008-10-13
** Last Version: 1.0
** Descriptions: lcd1602 test.
**
**------------------------------------------------------------------------------------------------------
** Created by: zhoufeng
** Created date: 2008-10-13
** Version: 1.0
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by: junbolu
** Modified date: 2008-12-13
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
**ICC-AVR application builder : 2008-12-13
**Target : M16
**Crystal: 7.3728Mhz
**
**
**描述:这是一个Lcd1602的测试程序。LCD1602型号为JHD162A 使用8位并口数据传输.
**
**
**涉及知识点:
**
**
**
*******************************************************************************************************/
/*注意:
本例使用M16,内部RC 7.3728MHz测试通过,
编译平台为ICCAVR 6.31
*/
#include <iom16v.h>
#include <macros.h>
#include"lcd1602.h"
//时钟频率:内部RC振荡8MHz
void delay_1us(void) //延时1us
{//ret:4t+call:4t=8t,8MHz时1t为125ns,8t为1000ns=1us
}
void delay_nus(unsigned int n) //延时n us
{//(8+(4+4)*(n-1)+3)t=(8+8n-8+3)t=(8n+3)t=n us+0.375us,所以约等于1us,特别n越大越精确
while(--n)
{
asm("nop"); //nop需1t
asm("nop");
asm("nop");
asm("nop");
}
}
void delay_1ms(void) //延时1ms
{//函数调用本身有8t=1us
delay_nus(999); //为999us
}
void delay_nms(unsigned int n) //延时nms
{//(8+4*(n-1)+3)t+delay_nus=(7+4n)t+delay_nus
for(;n>0;n--)
{
asm("nop"); //再补尝,变成了(7+5n)t+delay_nus
delay_nus(999); /*delay_nus(m)为(8m+3)t所以delay_nus的参数只要999就可以了
(7+5n)t+((8m+3)*n)t=(7+8n+8mn)t=7t+n us+mn us
=7t+(m+1)n us,代入m=999约等于1000n us=n ms,误差仅为7t,不到1us
*/
}
}
void lcd_wait_enable(void) //LCD等待可写
{
Data_in(); //置为输入
clr_rs();
set_rw();
delay_nus(1);
set_en();
delay_nus(2);
while((Data_PIN&0x80)>>7);
clr_en();
Data_out();
}
void lcd_write_cmd(char cmd,char attrib) //写命令,attrib为0不检查忙状态,否则检查忙状态
{
if(attrib) lcd_wait_enable();
clr_rs();
clr_rw();
delay_nus(1);
Data_PORT=cmd;
delay_nus(1);
set_en();
delay_nus(2);
clr_en();
}
void lcd_set_xy(int x,int y) //设置显示的起始地址,x行,y列
{
int tmp;
tmp=y&0x0F;
x&=0x01;
if(x) //第二行
tmp|=0x40;
tmp|=0x80;
lcd_write_cmd(tmp,0);
}
void lcd_write_byte(char byte) //写字节
{
lcd_wait_enable();
set_rs();
clr_rw();
delay_nus(1);
Data_PORT=byte;
set_en();
delay_nus(2);
clr_en();
}
void lcd_disp_char(int x,int y,char ch) //写字串
{
lcd_set_xy(x,y);
lcd_write_byte(ch);
}
void lcd_disp_string(int x,int y,char *s) //写字串,支持换行
{
unsigned char i=0;
while (*s)
{
if(y+i<16)
{
lcd_disp_char(x,y+i,*s);
s++;
i++;
}
else
{
delay_nus(50); //换行至少延时20us,否则会造成显示不正常
lcd_disp_char(x^1,y+i-16,*s);
s++;
i++;
}
}
}
void lcd_init(void) //初始化液晶
{
Open_Ctrl();
Data_out();
lcd_write_cmd(0x38,0); //显示模式设置(不测试忙信号)共三次
delay_nms(5);
lcd_write_cmd(0x38,0);
delay_nms(5);
lcd_write_cmd(0x38,0);
delay_nms(5);
lcd_write_cmd(0x38,1); //8位数据口,2行显示,5*7点阵
lcd_write_cmd(0x08,1); //显示关
lcd_write_cmd(0x01,1); //清屏
lcd_write_cmd(0x06,1); //数据读,写后AC自增1,画面不动
lcd_write_cmd(0x0C,1); //显示开
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -