在研究串口前,我们需要看一下所有的寄存器
首先是SCON,主要是用来设置串口的工作方式
详细参数其实不需要知道的非常非常清楚,因为我们一般都是有默认情况的
文档写着麻烦,直接上例程
/***
串口控制发送函数
***/
#include "reg51.h"
#include "intrins.h"
#include "send.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 11059200L //系统频率
#define BAUD 9600 //串口波特率
sfr AUXR = 0x8e; //辅助寄存器
sfr P_SW1 = 0xA2; //外设功能切换寄存器1
#define S1_S0 0x40 //P_SW1.6
#define S1_S1 0x80 //P_SW1.7
bit busy;
/*串口初始化*/
void uInit()
{
//ACC 是一个累加器,主要用来存放数据
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
//P_SW1是一个特殊功能的寄存器,用来将串口1进行切换
P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)
// 串行控制器SCON为01010000
//SM0为0 SM1为1 说明工作方式为方式1 8位UART,波特率可变
//SM2为0 说明不是多机通信
//REN为1 允许串行接收
//TB8为0 在方式2或3中表示发送的第9位数据,我们用的是方式1不管
//RB8为0 在方式2或3中表示接收的第9位数据,我们也不管
//TI为0 主要用于发送中断请求的标志位
//RI为0 用于接收中断的标志位
SCON = 0x50; //8位可变波特率
//AUXR是辅助寄存器用来控制定时器的分频
//01000000 T1x12为1表示定时器1的速度是传统8051的12倍
AUXR = 0x40; //定时器1为1T模式
//TMOD是定时器/计数器的工作模式寄存器,用来控制定时器的操作模式,我们设置的是模式0
TMOD = 0x00; //定时器1为模式0(16位自动重载)
//TL1是定时器的低8位,TH1是定时器的高8位,这个定时器主要是用来控制波特率的
TL1 = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
TH1 = (65536 - (FOSC/4/BAUD))>>8;
//TR1为1表示定时器1的控制为,如果为1就表示开始启动定时器
TR1 = 1; //定时器1开始启动
//ES主要是串口中断控制为,如果为1表示允许串口中断
ES = 1; //使能串口中断
//EA表示CPU总的中断允许位,如果为1,那么就表示开放CPU中断
EA = 1;
// SendString("STC15F2K60S2\r\nUart Test !\r\n");
}
/*----------------------------
UART 中断服务程序
interrupt 4表示串口中断
//对于51来说
中断bai0 外部中断0
中断du1 定时器zhi1中断
中断2 外部中断1
中断3 定时器2中断
中断4 串口中断
using解释
用来选择80c51单片机中不同的寄存器组,你也知道R0-R7总共有4组,那么using 后面的数字也就是0-3范围里的一个数了。如果不需要using的话,编译器会自动选择一组寄存器作为绝对寄存器访问的。
using对代码是有一定的影响的。
给你说个简单的例子,你可以想下,
如果定义
void time0() interrupt 1 using 1
假设,我们又在中断里调用了一个delay();这个delay是起延时作用。
那么,我们就需要确保我们使用的寄存器组是同一组,否则,就会出现混乱。
-----------------------------*/
void Uart() interrupt 4 using 1
{
// 在串口发生中断的时候RI为1表示有数据接收,我们把这位清零用于下次判断
if (RI)
{
RI = 0; //清除RI位
P0 = SBUF; //P0显示串口数据
}
// TI为0表示发送中断,我们主要用来判断当前是否可以发送数据
if (TI)
{
TI = 0; //清除TI位
busy = 0; //清忙标志
}
}
/*----------------------------
发送串口数据
这个函数用来向串口发送数据
----------------------------*/
void SendData(BYTE dat)
{
// busy判断数据是否发送完毕
while (busy); //等待前面的数据发送完成
// 我们用ACC来存放发送的数据
ACC = dat; //获取校验位P (PSW.0)
//P表示奇偶的标志位(当ACC1的个数为奇数的时候P为1反之)。TB8是发送的第9位数据,所以这个是用来校验的
if (P) //根据P来设置校验位
{
TB8 = 0; //设置校验位为0
}
else
{
TB8 = 1; //设置校验位为1
}
// busy表示需要发送数据,当发送完毕时,会清0
busy = 1;
// 发需要发送的数据放到寄存器中去
SBUF = ACC; //写数据到UART数据寄存器
}
/*----------------------------
发送字符串,因为字符串是一个字符数组,所以我们这里是通过指针来发送数据
----------------------------*/
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
}
}
主函数调用
//****************************************
// Update to MPU6050 by shinetop
// MCU: STC89C52
// 2012.3.1
// 功能: 显示加速度计和陀螺仪的10位原始数据
//****************************************
// 使用单片机STC89C52
// 晶振:11.0592M
// 显示:串口
// 编译环境 Keil uVision2
//****************************************
#include "reg51.h"
#include "send.h"
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
void Delay1000ms();
//*******************************************************************************************************
//主程序
//*******************************************************************************************************
void main()
{
//初始化串口
uInit();
while(1){
Delay1000ms();
SendString("hello,word");
}
}
// 延时1秒
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}