文章目录
显示屏LCD介绍
- 液晶显示器(LCD)的主要原理是以电流刺激液晶分子产生点,线,面并配合背部灯管构成画面。
- 各种型号的液晶通常按照显示字符的行数或液晶点阵的行,列数来命名。液晶有字符型液晶,图形型液晶。
- 液晶是介于液体与晶体之间的一种物质状态。它既有液体的流动性,又有晶体的各向异性。在电场作用下,偶极子会按电场方向取向,导致分子原有的排列方式发生变化,从而液晶的光学性质也随之发生改变,这种因外电场引起的液晶光学性质的改变称为液晶的电光效应。
- 液晶的体积小,功耗低,显示操作简单,但是其使用的温度范围很窄,通用型液晶正常工作温度0~+55℃。
LCD1602的使用
1602的接口说明
1602的主要技术参数
- 显示容量:16×2个字符
- 芯片工作电压:4.5—5.5V
- 工作电流:2.0mA(5.0V)
- 模块最佳工作电压:5.0V
- 字符尺寸:2.95×4.35(W×H)mm
1602内部系统结构图
- DDRAM(Display Data RAM)就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下:
- LCD1602模块上固化了字模存储器,就是CGROM和CGRAM:
- HD44780内置了192个常用字符的字模,存于字符产生器CGROM(Character Generator ROM)中;
- 另外还有8个允许用户自定义的字符产生RAM,称为CGRAM(Character Generator RAM)。
1602基本操作时序
写操作时序图
1602的命令指令码
忙检测函数
bit LCD_Check_Busy(void) {
DataPort= 0xFF;
RS=0;
RW=1;
EN=0;
_nop_();
EN=1;
return (bit)(DataPort & 0x80);
}
相关代码
/*******************************************************************************
* 函 数 名 : Lcd1602_Delay1ms
* 函数功能 : 延时函数,延时1ms
* 输 入 : c
* 输 出 : 无
* 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/
void Lcd1602_Delay1ms(uint c) //误差 0us
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/*******************************************************************************
* 函 数 名 : LcdWriteCom
* 函数功能 : 向LCD写入一个字节的命令
* 输 入 : com
* 输 出 : 无
*******************************************************************************/
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
Lcd1602_Delay1ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名 : LcdWriteData
* 函数功能 : 向LCD写入一个字节的数据
* 输 入 : dat
* 输 出 : 无
*******************************************************************************/
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //写入数据
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名 : LcdInit()
* 函数功能 : 初始化LCD屏
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起点
}
串口中断配置
计算机串行通信基础
- 随着多微机系统的广泛应用和计算机网络技术的普及,计算机的通信功能愈来愈显得重要。计算机通信是指计算机与外部设备或计算机与计算机之间的信息交换。
- 通信有并行通信和串行通信两种方式。在多微机系统以及现代测控系统中信息的交换多采用串行通信方式。
- 计算机通信是将计算机技术和通信技术的相结合,完成计算机与外部设备或计算机与计算机之间的信息交换 。可以分为两大类:并行通信与串行通信。
并行通信
- 并行通信通常是将数据字节的各位用多条数据线同时进行传送 。
- 并行通信控制简单、传输速度快;由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难,干扰较大。
串行通信
- 串行通信是将数据字节分成一位一位的形式在一条传输线上逐个地传送。
- 串行通信的特点:传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂。
串行通信的基本概念
异步通信
- 异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。
- 异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符内的各位之间的距离均为“位间隔”的整数倍。
- 异步通信的数据格式:
- 异步通信的特点:不要求收发双方时钟的严格一致,实现容易,设备开销较小,但每个字符要附加2~3位用于起止位,各帧之间还有间隔,因此传输效率不高。
同步通信
- 同步通信时要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。发送方对接收方的同步可以通过两种方法实现。
串行通信的传输方向
- 单工是指数据传输仅能沿一个方向,不能实现反向传输。
- 半双工是指数据传输可以沿两个方向,但需要分时进行。
- 全双工是指数据可以同时进行双向传输。
串行通信常见的错误校验
- 奇偶校验
在发送数据时,数据位尾随的1位为奇偶校验位(1或0)。奇校验时,数据中“1”的个数与校验位“1”的个数之和应为奇数;偶校验时,数据中“1”的个数与校验位“1”的个数之和应为偶数。接收字符时,对“1”的个数进行校验,若发现不一致,则说明传输数据过程中出现了差错。 - 代码和校验
代码和校验是发送方将所发数据块求和(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块末尾。接收方接收数据同时对数据块(除校验字节外)求和(或各字节异或),将所得的结果与发送方的“校验和”进行比较,相符则无差错,否则即认为传送过程中出现了差错。 - 循环冗余校验
这种校验是通过某种数学运算实现有效信息与校验位之间的循环校验,常用于对磁盘信息的传输、存储区的完整性校验等。这种校验方法纠错能力强,广泛应用于同步通信中。
传输速率
- 比特率是每秒钟传输二进制代码的位数
- 单位是:位/秒(bps)。
- 如每秒钟传送240个字符,而每个字符格式包含 10位(1个起始位、1个停止位、8个数据位),这时的比特率为:10位×240个/秒 = 2400 bps
80C51的串行口
80C51串行口的结构
- 有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H ;接收器是双缓冲结构 ;发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误。
80C51串行口的控制寄存器
SCON
- SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:
- SM0和SM1为工作方式选择位,可选择四种工作方式:
- SM2,多机通信控制位,主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。 - REN,允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。
- TB8,在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。
在方式0和方式1中,该位未用。 - RB8,在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位。在方式1时,若SM2=0,则RB8是接收到的停止位。
- TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。
- RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。
PCON
- PCON中只有一位SMOD与串行口工作有关 :
- SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。
波特率的计算
-
在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。
-
串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。
方式0的波特率 = fosc/12
方式2的波特率 =(2SMOD/64)· fosc
方式1的波特率 =(2SMOD/32)·(T1溢出率)
方式3的波特率 =(2SMOD/32)·(T1溢出率)
- 当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。
- T1 溢出率 = fosc /{12×[256 -(TH1)]}
- 在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。
串口如何使用
串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。
步骤如下:
确定T1的工作方式(编程TMOD寄存器);
计算T1的初值,装载TH1、TL1;
启动T1(编程TCON中的TR1位);
确定串行口控制(编程SCON寄存器);
串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
相关代码
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned char uchar; //对数据类型进行声明定义
/*******************************************************************************
* 函数名 :UsartInit()
* 函数功能 :设置串口
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void UsartInit()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2 自动重装的8为计数器
PCON=0X80; //波特率加倍
//晶体频率不能满足要求,而你需要更高速率时使用可以提高一倍的通讯速率
TH1=0XF3; //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
UsartInit(); // 串口初始化
while(1);
}
/*******************************************************************************
* 函数名 : Usart() interrupt 4
* 函数功能 : 串口通信中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Usart() interrupt 4
{
uchar receiveData;
receiveData=SBUF;//出去接收到的数据
RI = 0;//清除接收中断标志位
SBUF=receiveData;//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}
SPI通信协议简介
SPI总线概念
- SPI接口的全称是“Serial Peripheral Interface”,意为串行外围接口
- SPI接口主要应用在
EEPROM
,FLASH
,实时时钟
,AD转换器
,还有数字信号处理器
和数字信号解码器
之间 - SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,为
全双工通信
, 数据传输速度总体来说比I2C总线要快,速度可达到几Mbps
SPI接口是以主从方式工作的,这种模式通常有一个主器件和一个或多个从器件,其接口包括以下四种信号:
- MOSI
主器件数据输出,从器件数据输入
- MISO
主器件数据输入,从器件数据输出
- SCLK
时钟信号,由主器件产生
- /CS
从器件使能信号,由主器件控制,低电平有效
(图中NSS)
模拟SPI编程规则
模拟SPI就是按照SPI标准的时序,采用单片机发出时钟信号,发出或接受信息的过程
模拟SPI写函数
根据以上时序图我们可以写出以下函数
void SPI_Write(uchar dat)//dat为需要写入的指令
{
uchar i;
CLK = 0;
for(i=0; i<8; i++)//dat为8位所以循环8次
{
DIN = dat >> 7; //放置最高位 DIN为数据管脚可自行定义
dat <<= 1;//SPI自高向低位传输所以每一次向右移动一位
CLK = 0; //模拟时钟信号,上升沿放置数据
CLK = 1;
}
}
模拟SPI读函数
uint SPI_Read(void) //返回dat值,此函数返回了12位,所以uchar会溢出
{
uint i, dat=0;
CLK = 0;
for(i=0; i<12; i++) //接收12位数据
{ //i表示接收位数
dat <<= 1;
CLK = 1; //模拟时钟信号
CLK = 0;
dat |= DOUT; //接收数据的管脚
}
return dat;
}