目录
一、串口
1、串口基本认知
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(全双工),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢,约20kb/s,发送数据是低位先发,接收数据是高位先接收
异步串行是指 UART ( Universal Asynchronous Receiver/Transmitter ),通用异步接收 / 发送。UART 包含 TTL 电平的 串口 和 RS232 电平的串口
2、串口通信
STC89C52设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入,因而两个缓冲器可以共用一个地址码( 99H),都 是两个独立的8 位寄存器。两个缓冲器统称 串行通信特殊功能寄存器SBUF。
代码体现为: 接收数据 char data = SBUF 发送数据 SBUF = data
波特率:UART是异步串行接口,通信双方使用时钟不同,因为双方硬件配置不同,但是需要约定通信速度,叫做波特率
串行通信设有4种工作方式,其中两种方式的波特率是可变的,另两种是固定的,以供不同应用场合选用。波特率由内部定时器/计数器产生,用软件设置不同的波特率和选择不同的工作方式。主机可通过查询或中断方式对接收/发送进行程序处理,使用十分灵活。
3、串口编程寄存器
-
3.1串行口相关寄存器
-
3.2串行口控制寄存器SCON和PCON
- 其中SM0、SM1按下列组合确定串行口的工作方式:
PCON :电源控制寄存器(不可位寻址):
二、串口中断
2.1中断的触发
三、字符串型指令控制LED代码
3.1static关键字:
静态全局变量有以下特点:
1.静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的,即使用extern声明也不能使用。
2.静态局部变量有以下特点:
3.静态局部变量在程序执行到该对象的声明处时只执行一次初始化;
4.静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
3.2 AUXR
#include "reg52.h"
#include <intrins.h>
#include <string.h>
#define SIZE 12
sbit led1 = P2^0;
sfr AUXR = 0x8E;
char dat_bak[SIZE];
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();//就是通过nop指令的填充(nop指令一个字节),使指令按字对齐,从而减少取指令时的内存访问次数。
_nop_();//指令的延迟时间为 1us。可以较为精确得控制延迟时间。
i = 23;
j = 3;
k =100;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void UartInit(void) //9600bps@11.0592MHz
{
//PCON = 0x00;//可以不配置,因为PCON默认就是不加倍
SCON = 0x50;//配置串口工作方式1工作,REN:1:使单片机能接收 0101 0000
TMOD &= 0x0F;
TMOD |= 0x20;//定时器配成8位自动重载
TH1 = 0xFD;//公式计算:9600 = (2的SMOD次方/32)*定时器1的溢出率(11059200/12(256-TH1));
TL1 = 0xFD;
TR1 = 1;//启动定时器
AUXR = 0x00;//减少时钟电磁辐射,最低位为0,允许串口收发数据,设置为12分频
ES = 1;//开启串口中断
EA = 1;//开启总中断
}
void sendbyte(char dat_msg)
{
SBUF = dat_msg;
while(!TI);//当串口传输结束后,TI自动置1,在这里我们把TI当最标志位来使用,目的是为了等待移位寄存器移位
TI = 0;//手动清零
}
void sendstar(char *ptr)
{
while(*ptr != '\0'){
sendbyte(*ptr);
ptr++;
}
}
void main()
{
char* dat = "woaichenhao\r\n";//串口中\r\n才能换行并对齐打印
UartInit();
while(1){
Delay1000ms();
sendstar(dat);
}
}
void UART_server() interrupt 4
{
static int i = 0;//每次中断都会重新声明i,用static可以只声明一次,i放置在静态区不会被反复声明
if(RI){
RI = 0;//接收到串口信息后RI自动置1,必须要手动清0,最好放到前面,放到程序最后可能导致close不运行
dat_bak[i]= SBUF;//移位寄存器,移位一位的传
i++;//光标往后移
if(i == SIZE){//如果超过数组大小,光标返回
i = 0;
}
if(!strcmp("open",dat_bak)){//比较open和dat_bak,如果完全一样返回0
led1 = 0;
i = 0;
memset(dat_bak,'\0',SIZE);
}
if(!strcmp("close",dat_bak)){//比较close和dat_bak,如果完全一样返回0
led1 = 1;
i = 0;//光标返回
memset(dat_bak,'\0',SIZE);//数组初始化清0
}
}
if(TI);
}