STC89C52_51单片机_串口配置_UART串口通信

发布者:二进制游侠最新更新时间:2020-06-27 来源: eefocus关键字:STC89C52  51单片机  串口配置  UART 手机看文章 扫描二维码
随时随地手机看文章

寄存器配置

PCON电源管理寄存器

位序号 D7 D6 D5 D4 D3 D2 D1 D0

位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI

– 模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0

//不能位寻址


SCON串口控制寄存器

位序号 D7 D6 D5 D4 D3 D2 D1 D0

位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI

– 模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0

/*  SCON  */

sbit SM0   = SCON^7;

sbit SM1   = SCON^6;

sbit SM2   = SCON^5;

sbit REN   = SCON^4;

sbit TB8   = SCON^3;

sbit RB8   = SCON^2;

sbit TI    = SCON^1;

sbit RI    = SCON^0;


模式&波特率(宋雪松P183)

SCON主要用模式1,的波特率

对应的,要用定时器T1&T2的模式2


TH1 = TL1 = 256 - 晶振值/12/2/16/波特率

(256是TL1的溢出值,12指12个时钟周期,16是硬件因素)


SBUF

两个SBUF寄存器,分别负责接收和发送缓冲


流程

配置串口为模式1

配置定时器T1为模式2

根据波特率计算TH0&TL0的值

配置PCON&SCON寄存器

打开定时器


IO口模拟UART串口通信

UART串口传送数据示意图

在这里插入图片描述

挖坑:波特率&TH0是怎么算的?



#include


sbit PIN_RXD = P3^0;

sbit PIN_TXD = P3^1;


bit RxdOrTxd = 0;

bit RxdEnd = 0;

bit TxdEnd = 0;

unsigned char RxdBuf = 0;

unsigned char TxdBuf = 0;


void configUART(unsigned long baud);

void startRXD(void);

void startTXD(unsigned char dat);


void main(void)

{

EA = 1;

configUART(9600);


while(1)

{

while(PIN_RXD);

startRXD();

while(!RxdEnd);

startTXD(RxdBuf+1);

while(!TxdEnd);

}

}


void configUART(unsigned long baud)

{

TMOD &= ~(0xF<<0);

TMOD |= 0x1<<1;

TH0 = 256 - (11059200 / 12) / baud;

}


void startRXD(void)

{

TL0 = 256 - ((256 - TH0) >> 1);


ET0 = 1;

TR0 = 1;


RxdEnd = 0;

RxdOrTxd = 0;

}


void startTXD(unsigned char dat)

{

TxdBuf = dat;


TL0 = TH0;


ET0 = 1;

TR0 = 1;


PIN_TXD = 0;

RxdEnd = 0;

RxdOrTxd = 1;

}


void timer0(void) interrupt 1

{

static unsigned char cnt = 0;


if(RxdOrTxd)

{

cnt++;

if(cnt<=8)

{

PIN_TXD = TxdBuf & 0x01;

TxdBuf >>= 1;

}

else if(cnt==9)

{

PIN_TXD = 1;

}

else 

{

cnt = 0;

TR0 = 0;

TxdEnd = 1;

}

}


else

{

if(cnt==0)

{

if(!PIN_RXD)

{

RxdBuf = 0;

cnt++;

}

else

{

TR0 = 0;

}

}

else if(cnt<=8)

{

RxdBuf >>= 1;

if(PIN_RXD)

{

RxdBuf |= 0x80;

}

cnt++;

}

else

{

cnt = 0;

TR0 = 0;

if(PIN_RXD)

{

RxdEnd = 1;

}

}

}

}


UART串口通信

教学版


#include


void configUART(unsigned long baud);


void main(void)

{

configUART(9600);

while(!RI);

RI = 0;

SBUF = SBUF + 1;

while(!TI);

TI = 0;

}


void configUART(unsigned long baud)

{

SCON = 0x50;


TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;

TL1 = TH1;

TMOD &= ~(0xF<<4);

TMOD |= 0x2<<4;

ET1 = 0;

TR1 = 1;

}


工业版


#include


void configUART(unsigned long baud);


void main(void)

{

EA = 1;

configUART(9600);

while(1);

}


void configUART(unsigned long baud)

{

SCON = 0x50;


TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;

TL1 = TH0;

TMOD &= ~(0xF<<4);

TMOD |= 0x2<<4;

ET1 = 0;

ES = 1;

TR1 = 1;

}


void UART(void) interrupt 4

{

if(RI)

{

RI = 0;

SBUF = SBUF + 1;

}

if(TI)

{

TI = 0;

}

}


计算机发送数据,在数码管中显示


#include


sbit wei = P2^7;

sbit duan = P2^6;


unsigned char code weitable[6] = 

{

~0x20,~0x10,~0x08,~0x04,~0x02,~0x01

};


unsigned char code duantable[16] = 

{

0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,

0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71

};


unsigned char ledbuff[6] = 

{

0x00,0x00,0x00,0x00,0x00,0x00

};


unsigned char T0RH = 0,T0RL = 0;

unsigned char RxdByte = 0;


void configtimer0(unsigned char ms);

void configUART(unsigned long baud);


void main(void)

{

EA = 1;

configtimer0(1);

configUART(9600);

while(1)

{

ledbuff[0] = duantable[RxdByte & 0x0F];

ledbuff[1] = duantable[RxdByte >> 4];

}

}


void configtimer0(unsigned char ms)

{

unsigned long tmp;


tmp = 11059200 / 12;

tmp = (tmp * ms) / 1000;

tmp = 65536 - tmp;

tmp = tmp + 12;


T0RH = (unsigned char)(tmp>>8);

T0RL = (unsigned char)tmp;


TH0 = T0RH;

TL0 = T0RL;

TMOD &= ~(0xF<<0);

TMOD |= 0x1<<0;

ET0 = 1;

TR0 = 1;

}


void configUART(unsigned long baud)

{

TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;

TL1 = TH0;

SCON = 0x50;

TMOD &= ~(0xF<<4);

TMOD |= 0x2<<4;

ET1 = 0;

ES = 1;

TR1 = 1;

}


void ledscan(void)

{

static unsigned char i = 0;


P0 = 0x00;

duan = 1;

duan = 0;


P0 = weitable[i];

wei = 1;

wei = 0;

P0 = ledbuff[i];   

duan = 1;

duan = 0;


if(i<5)

i++;

else

i = 0;

}


void timer0(void) interrupt 1

{

TH0 = T0RH;

TL0 = T0RL;


ledscan();

}


void UART(void) interrupt 4

{

if(RI)

{

RI = 0;

RxdByte = SBUF;

SBUF = RxdByte;

}

if(TI)

{

TI = 0;

}

}

关键字:STC89C52  51单片机  串口配置  UART 引用地址:STC89C52_51单片机_串口配置_UART串口通信

上一篇:51单片机简单的串口通讯-1
下一篇:51单片机 | 串口通信实验(模拟串口通信/多机通信实例)

推荐阅读最新更新时间:2024-11-05 12:36

51单片机心形灯实现每次点亮两个灯编程
心形灯原理图 编译软件:Keil uVision5 (如有需要可点此链接下载:https://download.csdn.net/download/qq_36931762/11343174) 单片机程序下载软件:STC-ISP (如有需要可点此链接下载:https://download.csdn.net/download/qq_36931762/11343157) 程序代码: 灯状态处于0亮1灭 #include reg52.h sbit LED8=P2^0;//D8 sbit LED7=P2^1;//D7 sbit LED6=P2^2;//D6 sbit LED5=P2^3;//D5 sbit LED4=P2^4;/
[单片机]
<font color='red'>51单片机</font>心形灯实现每次点亮两个灯编程
51单片机温度报警DS18B20系统程序
51单片机温度报警DS18B20系统程序: #include AT89X52.h #include stdio.h #define uint unsigned int #define uchar unsigned char //宏定义 #define SET P3_1 //定义调整键 #define DEC P3_2 //定义减少键 #define ADD P3_3 //定义增加键 #define BEEP P3_7 //定义蜂鸣器 #define DQ P3_6 //定义DS18B20总线I/O bit shanshuo_st; //闪烁间隔标志 bit beep_st; //蜂鸣器间隔标志 sbit
[单片机]
【自学51单片机】5 --- 定时器、数码管、逻辑运算、
定时器介绍、数码管静态显示、逻辑运算符和逻辑电路符号 1、逻辑运算和逻辑电路 引入逻辑概念:在生活中,逻辑存在 ‘真’ 和 ‘假’ 两个逻辑值,而逻辑对应到C语言和数字电路中, ‘真’ 对应C语言或数字电路中的一切 ‘非0值’,而 ’假‘ 对应为 ’0值‘。 1.1 C语言逻辑运算符 假定两个字节变量A和B,两者进行某种逻辑运算后结果为F。 以下为逻辑运算符(按变量整体值进行运算) && 逻辑与:F = A && B,当 A、B 的值都为真(即非 0 值,下同)时,其运算结果 F 为真(具体数值为 1,下同);当 A、B 值任意一个为假(即 0,下同)时,结果 F 为假(具体数值为 0,下同)。 || 逻辑或:F
[单片机]
【自学<font color='red'>51单片机</font>】5 --- 定时器、数码管、逻辑运算、
AT89C51单片机应用于数控车床切削力测量
 AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。   本文就介绍了应用AT89C51单片机测量数控车床切削力的新方法,重点阐述了单片机实现连续自动采样、A/D转换、标度变换及数据处理的方法。   1 问题的提出   在数控车床的加工中,切削力的测量甚为重要。通过对切削力的测量可以分析与研究数控车床各零部件、机构或结构的受力情况和工作状态,验证设计和计算结果
[单片机]
AT89C<font color='red'>51单片机</font>应用于数控车床切削力测量
51单片机——静态数码管流动显示
共阴极数码管码表: 0x3f , 0x06 , 0x5b , 0x4f ,0x66 , 0x6d , 0 1 2 3 4 5 0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c , 6 7 8 9 A B 0x39 , 0x5e , 0x79 , 0x71 , 0x00 C D E F 无显示 实际应用中,定义一个数组即可: ​unsigned char code DIG_CODE ={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D,
[单片机]
用Proteus学习51单片机之AD转换
现实中的很多量,都是模拟量,如温度,压力等,单片机要去了解它们,首先就要把这些量进行数字化,AD转换即把模拟量转变为数字量。这次书上介绍的AD芯片为ADC0804,8位并行AD转换芯片。关于AD转换的详细原理,我就不抄了,网上有的是。 ADC0804的使用,比前面用过的锁存器74LS573难用得多,主要是读写数据都要根据时序图,进行电位的变化,而且芯片的接法也相对麻烦一点。下面记录一下引脚定义: VIN(+),VIN(-):待测量的模拟信号输入 DB0~DB7:测量结果输出 AGND:模拟信号地 DGND:数字信号地 CLK:时钟信号输入端 CLKR:内部时钟发生器的外接电阻端,与CLK端配合可由芯片自身产生时钟脉冲,其频率为1/
[单片机]
用Proteus学习<font color='red'>51单片机</font>之AD转换
51单片机实现流水灯操作
一、用移位操作 用左移指令和取反运算实现从第一个二极管到最后一个二极管的流水灯 #include reg52.h //间隔200毫秒的流水灯 void delayms(unsigned int xms)//带参数函数 { unsigned int i,j;//局部变量,需要时随时分配,不用时立即销毁 for(i=xms;i 0;i--) for(j=110;j 0;j--); } unsigned char k;//全局变量,占据固定RAM void main() { while(1) { for(k=0;k 8;k++) { P1=~(1 k);/*1即为0000 0001,
[单片机]
<font color='red'>51单片机</font>实现流水灯操作
实验五 定时器(80C51单片机汇编语言编程)
P1.0、P1.1接两个发光管,INT0接一启动按键,启动后两个发光管一亮一灭,亮灭时间为1s,再按按键停止发光管。 实验箱晶振:6M ORG 0000H AJMP MAIN ORG 0003H AJMP INT0 ORG 000BH AJMP T0 ORG 0030H MAIN:MOV TMOD,#01H MOV TH0,#3CH MOV TL0,#0B0H SETB EA SETB EX0 SETB ET0 SETB IT0 CLR TR0 CLR P1.0 CLR P1.1 MOV R7,#0AH SJM
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved