模拟UART通信只能简单地进行数据的发送和接收, 而不具有增强型UART的许多功能, 也没有中断,
只能简单地进行数据的发送和接收。具体思路是这样的:以 9600bps 的波特率为例,当采用模式1进行通
信时,每一帧为10位(1个起始位,1个停止位和8个数据位) ,每一位的宽度为1/9600=104uS。发送一
个字节的时候先把TXD(TXD任意定义在哪个引脚)置低,延时104uS,这就完成了起始位的发送。接下
来是8个数据位,高位在前,发送每一位时根据数据位的值,把TXD 脚置1或清0,然后延时104uS,如
此一直到8个数据位发送完毕。最后把TXD脚置1,延时104uS,完成停止位的发送。这时就可以进行下
一个字节的发送了。模拟接收时同样使用延时的方法去接收每一位。
I/O口模拟UART演示程序(只经过了软件仿真)
HotPower 发表于 2004-7-7 22:59 侃单片机 ←返回版面 举报该贴
/*------------------------------------------------
I/O口模拟UART演示程序
--------------------------------------------------*/
#include <AT89X52.h>
#include <intrins.h>
/*------------------------------------------------
AT89S5X
--------------------------------------------------*/
sfr AUXR = 0x8e;
sfr WDTRST = 0xa6;
sfr16 TIMEER2 = 0xcc;
sfr16 RCAP = 0xca;
sbit TX = P1^0;
sbit RX = P1^1;
/*------------------------------------------------
74HC164串行显示数据
--------------------------------------------------*/
#define LedSegA 0x40
#define LedSegB 0x20
#define LedSegC 0x10
#define LedSegD 0x08
#define LedSegE 0x04
#define LedSegF 0x02
#define LedSegG 0x01
#define LedSegH 0x80
#define LedSegNul 0x00
#define LedChar0 LedSegA + LedSegB + LedSegC + LedSegD + LedSegE + LedSegF
#define LedChar1 LedSegB + LedSegC
#define LedChar2 LedSegA + LedSegB + LedSegD + LedSegE +
LedSegG
#define LedChar3 LedSegA + LedSegB + LedSegC + LedSegD +
LedSegG
#define LedChar4 LedSegB + LedSegC + LedSegF +
LedSegG
#define LedChar5 LedSegA + LedSegC + LedSegD + LedSegF +
LedSegG
#define LedChar6 LedSegA + LedSegC + LedSegD + LedSegE + LedSegF +
LedSegG
#define LedChar7 LedSegA + LedSegB + LedSegC
#define LedChar8 LedSegA + LedSegB + LedSegC + LedSegD + LedSegE + LedSegF +
LedSegG
#define LedChar9 LedSegA + LedSegB + LedSegC + LedSegD + LedSegF +
LedSegG
#define LedCharA LedSegA + LedSegB + LedSegC + LedSegE + LedSegF +
LedSegG
#define LedCharB LedSegC + LedSegD + LedSegE + LedSegF +
LedSegG
#define LedCharC LedSegA + LedSegD + LedSegE + LedSegF
#define LedCharD LedSegB + LedSegC + LedSegD + LedSegE +
LedSegG
#define LedCharE LedSegA + LedSegD + LedSegE + LedSegF +
LedSegG
#define LedCharF LedSegA + LedSegE + LedSegF +
LedSegG
void MainInit(void);//系统初始化
void SystemInit(void);//系统初始化
void SystemIoInit(void);//系统接口初始化
void SystemSetup(void);//系统设置
void UserSetup(void);//用户运行环境设置
void TimeInit(void);//定时器初始化
void ClrWdt(void);//喂狗
//全局变量定义
typedef struct Systemstruct{//系统数据结构声明
unsigned char T0Count;//串行接收计数器
unsigned char Count;//串行数据接收个数
unsigned int RamTest;//内存测试寄存器
unsigned char SBUF;//串行接收数据
unsigned char RXBUF[16];//串行数据接收缓冲区
}SystemData;
SystemData SystemBuffers;//申请系统数据结构
void main(void)
{
MainInit();//系统初始化
while (1) {//主循环
IE |= 0x81;//保证中断可靠
PCON |= 0x01;//进入空闲状态
_nop_();
_nop_();
}
}
/*------------------------------------
定时器T0中断服务程序
------------------------------------*/
void T0_VECTOR() interrupt TF0_VECTOR using 1
{
if (SystemBuffers.T0Count < 2) {
if (RX) SystemBuffers.T0Count = 0;//有干扰或不为起始位
else {
SystemBuffers.T0Count ++;//可能是起始位
if (SystemBuffers.T0Count == 2) {//捕捉到起始位
TH0 = 0xc0;//4800bps(我搞不清具体的数值)
TL0 = 0xc0;
}
}
}
else {
if (SystemBuffers.T0Count >= 10) {//停止位
TH0 = 0;//1200bps(我搞不清具体的数值)
TL0 = 0;
SystemBuffers.T0Count = 0;//下次再找起始位
if (RX) {//是停止位
if (SystemBuffers.Count < 16) {//缓冲区数据未满可继续存入数据
SystemBuffers.RXBUF[SystemBuffers.Count] = SystemBuffers.SBUF;//存入一
个字节
SystemBuffers.Count ++;
}
}
}
else {//SystemBuffers.T0Count=2..9为8位串行数据
SystemBuffers.SBUF >>= 1;
if (RX) SystemBuffers.SBUF |= 0x80;
SystemBuffers.T0Count ++;
}
}
}
void MainInit(void)//系统初始化
{
SystemIoInit();//系统接口初始化
ClrWdt();//清除看门狗计数器
if (SystemBuffers.RamTest != 0x55aa) {//内存测试
SystemInit();//系统上电初始化
}
SystemSetup();//系统运行环境设置
UserSetup();//用户运行环境设置
}
void SystemIoInit(void)
{
IE = 0x00;//关闭中断
P0 = 0xff;//P0口初始化
P1 = 0xff;//P1口初始化
P2 = 0xff;//P2口初始化
P3 = 0xff;//P3口初始化
}
void SystemInit(void)//系统初始化
{
unsigned char i;
SystemBuffers.RamTest = 0x55aa;//内存初始化
SystemBuffers.T0Count = 0;
SystemBuffers.Count = 0;
for (i = 0; i < 16; i ++)
SystemBuffers.RXBUF[i] = 0;
}
void SystemSetup(void)//系统设置
{
AUXR = 0x01;//关闭EMI
}
void UserSetup(void)//用户运行环境设置
{
TimeInit();
SCON = 0x50;//UART的工作方式为方式2,且允许接收数据
TMOD = 0x22;//定时器1工作在方式2下,定时器0也工作在方式2
TCON = 0x50;//启动定时器0、1并设定外部中断0的中断方式
IP = 0x10; //设定终端优先级,UART的中断优先级比T0的中断优先级要高
IE = 0x92; //开总中断并允许定时器0和串行口中断
}
/*----------------------------------
定时器定时参数设置
----------------------------------*/
void TimeInit()
{
/*----------------------------------
定时器0定时参数设置
----------------------------------*/
TL0 = 0;
TH0 = 0;//当波特率为1200bps时,要求定时器0每过278uS就中断一次
TR0 = 1;//启动定时器0
/*----------------------------------
定时器1定时参数设置
----------------------------------*/
TL1 = 0xfa;
TH1 = 0xfa;//设置波特率为4800bps
TR1 = 1;//启动定时器1
/*----------------------------------
定时器2定时参数设置
----------------------------------*/
// TIMEER2 = 0x900;//2.5mS
// RCAP = 0x900;
// TR2 = 1;//启动定时器2
}
void ClrWdt(void)//喂狗
{
WDTRST = 0x1e;//清89s52内狗
WDTRST = 0xe1;//清89s52内狗
}
- 作者:ziqintian | 发布:2013年10月25日
- 分类:IT类别
- 标签:IO口,UART思路
- 转载文章请注明:IO口模拟UART思路 | 太极博弈原理官方站|紫欽天|融通百科为我所用|生活全智慧|生活智慧之书
文章是怎么写出来的?
好吧,我承认我想多了
大师受教了,缘来如此。。。
...也许网络安全产业以后会是
此法确实可靠吗?
hello!,I like y
I was suggested
Thanks , I've j