目录
[1. 3.3功能函数](#1. 3.3功能函数)
[编辑 2.定时器](#编辑 2.定时器)
[编辑 2.1.4中断系统](#编辑 2.1.4中断系统)
[编辑 编辑](#编辑 编辑)
1.LCD1602液晶显示屏
1.1基本概念
1.1.1LCD的简介
-
LCD1602(Liquid Crystal Display)液晶显示屏是一种专门用来显示字母、数字、符号和字符型等的点阵型液晶模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符。
-
它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。该显示屏的优点是耗电量低、体积小、辐射低。
-
显示容量:16×2个字符,每个字符为5*7点阵,、
1.1.2LCD的显示原理
我们所用的LCD屏的命名,基本都是按照其分辨率来进行命名的比如lcd1602就是分辨率为16×2,lcd12864就是分辨率为128×64
-
LCD1602主要用来显示数字、字母、图形以及少量自定义字符。可以显示2行16个字符,拥有16个引脚,其中8位数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节V0和背光源AK。
-
LCD需要背光源才能亮
- 80个字节的显示缓冲区DDRAM,分两行,地址分别为00H27H,40H67H。
- LCD1602,总共显示为16行2列,对应着32个RAM地址,在使用的时候,需要在哪个位置显示,就写入对应的RAM地址,然后再写入需要的字符,对应就会显示该字符。
- 转义字符(\)
1.1.3LCD的硬件电路
|--------|-------------------------------------------------------------------------------------------------------------------|
| 引脚 | 功能 |
| VSS | 地 |
| VDD | 电源正极(4.5~5.5V) |
| VO | 对比度调节电压,即调节LCD的显示 |
| RS | 数据/指令选择,1为数据,0为指令 |
| RW | 读(read)/写(write)信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或显示地址;当RS为低电平,R/W为高电平时,可以读忙信号;当RS为高电平,R/W为低电平时,可以写入数据 |
| E | 使能,1为数据有效,下降沿执行命令 |
| D0~D7 | 8位并行数据口**,**数据输入/输出 |
| A | 背光灯电源正极 |
| K | 背光灯电源负极 |
1.1.4LCD的常见指令
ASCll码表
- 清屏指令(0x01)
(1)清除液晶显示器,即将DDRAM的内容全部填入"空白"的ASCII码20H;
(2)光标归位,将光标撤回液晶显示屏的左上方;
(3)将地址计数器(AC)的值设置为0;
- 光标复位,光标返回到地址00H
(1) 光标复位到地址00H位置
(2)LCD显示DDRAM的内容不变
- 进入模式设置指令
(1) 功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
(2)0=写入新数据后光标左移 ; 1=写入新数据后光标右移;
(3)S---0=写入新数据后显示屏不移动 ;1=写入新数据后显示屏整体右移1个字符
- 显示开关指令
(1)功能 : 控制显示器开/关、光标显示/关闭以及光标是否闪烁。
(2)D(Dispaly):控制整体的显示开与关,高电平表示开显示屏,低电平表示关显示屏
(3)C(Cursor):控制光标的开与关,高电平表示有光标,低电平表示无光标
(4)B(Blink):控制光标是否闪烁,高电平闪烁,低电平不闪烁
- 功能设定指令
(1) 功能 : 设定数据总线位数、显示的行数及字型
(2)DL ------ 0=数据总线为4位 ; 1=数据总线为8位;
(3)N ------ 0=显示1行 ; 1=显示2行;
(4)F ------ 0=5×7点阵/每字符 ; 1=5×10点阵/每字符;
- 光标和显示移位
(1) SC=0,RL=0 :光标左移
(2)SC=0,RL=1 : 光标右移
(3)SC=1,RL=0时,字符和光标都左移
(4)SC=1,RL=1时字符和光标都右移
1.1.5LCD的时序
- 写指令/数据
- 读指令/数据
1.2代码
1.2.1写命令和写数据操作
cpp
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
void writecommand(unsigned char command)
{
RS=0; //RS为低电平时此时为读数据
RW=0; //RW为低表示数据写入
E=0; //E=0表示在前半部分,此时数据没有传送无需置高
P2=command; //command为命令
Delay_ms(5);
E=1; //E此时表示传送数据有效
E=0; //E此时表示数据传送完成此时为空闲状态
}
void writedata(unsigned char dat)
{
RS=1; //RS为低电平时此时为读数据
RW=0; //RW为低表示数据写入
E=0; //E=0表示在前半部分,此时数据没有传送无需置高
P2=dat; //command为命令
Delay_ms(5);
E=1; //E此时表示传送数据有效
E=0; //E此时表示数据传送完成此时为空闲状态
}
1.2.2初始化和测试代码
cpp
void lcd_init()
{
writecommand(0x38);//设置16×2显示、5×7点阵和8位数据接口
writecommand(0x0C);//设置开启显示,不显示光标
writecommand(0x06);//显示地址地址加1,即写一个数据后,显示位置右移一位
writecommand(0x01);//显示清零,数据指针清零
}
void lcd_test()
{
writecommand(0x80); //LCD的第一行起始地址
Delay_ms(5);
writedata('A');
Delay_ms(5);
writecommand(0x80+0x40); //LCD的第二行起始地址
Delay_ms(5);
writedata('X');
Delay_ms(5);
}
1. 3.3功能函数
cpp
/**
* @brief 在LCD中显示一个字符
* @param Line:表示在第几行显示
* @param Column:表示在第几列显示
* @param Char:显示字符
* @retval
*/
void LCD_Showchar(unsigned char Line,unsigned char Column,unsigned char Char)
{
if(Line==1)
{
writecommand(0x80|(Column-1)); //此时在第一行显示
}
else
{
writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
writedata(Char);
}
}
/**
* @brief 在LCD中显示一个字符串
* @param Line:表示在第几行显示
* @param Column:表示在第几列显示
* @param Char:显示字符串
* @retval
*/
void LCD_Showstring(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
if(Line==1)
{
writecommand(0x80|(Column-1)); //此时在第一行显示
}
else
{
writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
}
for(i=0;String[i]!='\0';i++)
{
writedata(String[i]);
}
}
/**
* @brief 立方函数
* @param x为分子
* @param y为立方根
*/
int LCD_POW(int x,int y)
{
unsigned char i;
int result=1;
for(i=0;i<y;i++)
{
result*=x;
}
return result;
}
/**
* @brief 设置字符位置
* @param x为行
* @param y为列
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
unsigned char i;
if(Line==1)
{
writecommand(0x80|(Column-1)); //此时在第一行显示
}
else
{
writecommand (0x80|(Column-1)+0x40);//此时在第二行显示,
}
}
/**
* @brief 设置数字
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned char Num,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
writedata(Num/LCD_POW(10,i-1)%10+0x30);//得到数字的高位);
}
}
1.3proteus代码
1.3.1器件代码
1.3.2总体Proteus
2.定时器
2.1基本概念
2.1.1定时器的简介
(1)STC89C52系列单片机内部设置的两个16位定时器/计数器T0和T1都具有计数方式和定时方式两种工作方式。对每个定时器/计数器(T0和T1),在特殊功能寄存器TM0D中都有一控制位一C/T来选择T0或T1为定时器还是计数器。
(2)定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每6个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1。
(3)SYSclk:系统时钟,即晶振周期,晶振为12MHz
(4)当定时器/计数器工作在定时模式时,可在烧录用户程序时在STC-ISP编程器中设置(如下
图所示)是系统时钟÷12还是系统时钟÷6后让T0和T1进行计数。当定时器/计数器工作在计数模式时,对外部脉冲计数不分频。
(5)GATE:门控位,用于控制定时/计数器的启动是否受外部中断请求信号的影响。
2.1.2定时器的计数模式
- 模式1(16位定时器/计数器)及其测试程序
- 模式2(8位计数器模式)
- 16位定时器工作方式
(1)****计数值为N和初值X关系:X=65536-N(12/fosc),N的单位为us即定义的时间
(2) 上次计数完,计数器值为0,要重复计数需重置初值。
fosc为晶振频率,51单片机一般为12MHz或者11.0592MHz
- 16位计数器工作方式
**(1)**16位定时/计数器方式计数值为N和初值X关系:X=65536-N
**(2)**上次计数完,计数器值为0,要重复计数需重置初值。
2.1.3寄存器
- 定时器/计数器控制寄存器TCON
- 定时器/计数器工作模式寄存器TMOD
2.1.4中断系统
2.2代码
2.2.1定时器初始化代码
cpp
void timerinit()
{
TMOD=0x01; //定时器0工作在16位定时器模式下,TH0、TL0全用
TF0=0; //防止开始定时器溢出产生中断,因此将TF0定时器清零
TH0=(65536-50000)/256; //计时50000us,并且除以2^8相当于右移8位,取出了高八位
TH0=(65536-50000)%256; //取出低八位,
ET0=1; //开启定时器0的中断
EA=1; //开启总中断
TR0=1; //启动定时器0
PT0=0; //配置低优先级
}
2.2.2定时器中断代码
cpp
void timer_isr() interrupt 1 //0表示外部中断0:1表示定时器中断0:2表示外部中断1;3表示定时器中断1;4表示串口中断
{
TH0=(65536-50000)/256;
TH0=(65536-50000)%256;
count++;
if(count==10)count=0;
P2=s[count];
// Delay_ms(200);
}
2.2.3计数器函数
cpp
void timerinit()
{
TMOD=0x06; //定时器0工作在8位自动重载计数器模式下,TH0、TL0全用
TF0=0; //防止开始计数器溢出产生中断,因此将TF0计数器清零
TH0=256-3; //计数值为3,由于是8位所以不需要将数据取出
TH0=256-3; //计数器3
ET0=1; //开启定时器0的中断
EA=1; //开启总中断
TR0=1; //启动定时器0
PT0=0; //配置低优先级
}
void count_isr() interrupt 1 //0表示外部中断0:1表示定时器中断0:2表示外部中断1;3表示定时器中断1;4表示串口中断
{
num++; //每隔3次,进入计数器的中断函数使得Num的值加1
}