2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报
本文章已收录于:

 
分类:
深入C语言(20)

作者同类文章X

 #include "reg52.h"
#include "intrins.h"
#include "math.h"
#include "stdio.h"
sbit BT_SND =P1^;
sbit BT_REC =P1^;
sbit LED =P1^;
bit LED_flage=;
//IO 口模拟232通讯程序
//使用两种方式的C程序 占用定时器0
#define MODE_QUICK
#define F_TM F0
#define TIMER0_ENABLE TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;
sbit ACC0= ACC^;
sbit ACC1= ACC^;
sbit ACC2= ACC^;
sbit ACC3= ACC^;
sbit ACC4= ACC^;
sbit ACC5= ACC^;
sbit ACC6= ACC^;
sbit ACC7= ACC^; void IntTimer0() interrupt
{
F_TM=;
}
//发送一个字符
void PSendChar(unsigned char inch)
{
#ifdef MODE_QUICK
ACC=inch;
F_TM=;
BT_SND=; //start bit
TIMER0_ENABLE; //启动
while(!F_TM);
BT_SND=ACC0; //先送出低位
F_TM=;
while(!F_TM);
BT_SND=ACC1;
F_TM=;
while(!F_TM);
BT_SND=ACC2;
F_TM=;
while(!F_TM);
BT_SND=ACC3;
F_TM=;
while(!F_TM);
BT_SND=ACC4;
F_TM=;
while(!F_TM);
BT_SND=ACC5;
F_TM=;
while(!F_TM);
BT_SND=ACC6;
F_TM=;
while(!F_TM);
BT_SND=ACC7;
F_TM=;
while(!F_TM);
BT_SND=;
F_TM=;
while(!F_TM);
TIMER0_DISABLE; //停止timer
#else
unsigned char ii;
ii=;
F_TM=;
BT_SND=; //start bit
TIMER0_ENABLE; //启动
while(!F_TM);
while(ii<)
{
if(inch&)
{
BT_SND=;
}
else
{
BT_SND=;
}
F_TM=;
while(!F_TM);
ii++;
inch>>=;
}
BT_SND=;
F_TM=;
while(!F_TM);
#endif
TIMER0_DISABLE; //停止timer
}
//接收一个字符
unsigned char PGetChar()
{
#ifdef MODE_QUICK
TIMER0_ENABLE;
F_TM=;
while(!F_TM); //等过起始位
ACC0=BT_REC;
TL0=TH0;
F_TM=;
while(!F_TM);
ACC1=BT_REC;
F_TM=;
while(!F_TM);
ACC2=BT_REC;
F_TM=;
while(!F_TM);
ACC3=BT_REC;
F_TM=;
while(!F_TM);
ACC4=BT_REC;
F_TM=;
while(!F_TM);
ACC5=BT_REC;
F_TM=;
while(!F_TM);
ACC6=BT_REC;
F_TM=;
while(!F_TM);
ACC7=BT_REC;
F_TM=;
while(!F_TM)
{
if(BT_REC)
{
break;
}
}
TIMER0_DISABLE; //停止timer
return ACC;
#else
unsigned char rch,ii;
TIMER0_ENABLE;
F_TM=;
ii=;
rch=;
while(!F_TM); //等过起始位
while(ii<)
{
rch>>=;
if(BT_REC)
{
rch|=0x80;
}
ii++;
F_TM=;
while(!F_TM);
}
F_TM=;
while(!F_TM)
{
if(BT_REC)
{
break;
}
}
TIMER0_DISABLE; //停止timer
return rch;
#endif
}
//检查是不是有起始位
bit StartBitOn()
{
return (BT_REC==);
}
//定时器1初始化
void Time1_Init(void)
{
TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装)
PCON=;
TR0=; //在发送或接收才开始使用
TF0=;
TH0=(-); //9600bps 就是 1000000/9600=104.167微秒 执行的timer//104.167*11.0592/12= 96
TL0=TH0;
ET0=;
EA=;
}
//发送字符串
void Send_Char(char *byte)
{
int i=;
for(i=;*(byte+i)!='\0';i++)
{
PSendChar(*(byte+i));
}
}
//void delay(int x)
//{
// int a,b;
// for(a=x;a>0;a--)
// for(b=10;b>0;b--);
//}
//void main()
//{
// unsigned char gch;
// Time1_Init();
// LED=0;
// // Send_Char("S00.0C00.0%E00.0C00.0%L00000lx");
// while(1)
// {
//
// PSendChar('1');
// delay(1000);
//// if(StartBitOn())
//// {
//// gch=PGetChar();
//// if(gch=='1')
//// {
//// LED=LED_flage;
//// delay(1000);
//// LED_flage=~LED_flage;
//// }
////
//// }
//
// }
//
//}

版权声明:本文为博主原创文章,未经博主允许不得转载。

        随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。

本文所说的模拟串口, 就是利用51的两个输入输出引脚P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。

以11.0592MHz的晶振为例,通过定时计数器0产生中断信号来模拟串口电平,下面附上具体源代码。

51单片机GPIO口模拟串口通信的更多相关文章

  1. stm32 普通IO口模拟串口通信

    普通IO口模拟串口通信 串口通信协议 串口传输 默认 波特率9600 1起始位 1停止位 其他0 数据位是8位(注意图上的给错了). 传输时,从起始位开始,从一个数据的低位(LSB)开始发送,如图从左 ...

  2. 关于51单片机P0口的结构及上拉问题

    1.P0作为地址数据总线时,V1和V2是一起工作的,构成推挽结构.高电平时,V1打开,V2截止:低电平时,V1截止,V2打开.这种情况下不用外接上拉电阻.而且,当V1打开,V2截止,输出高电平的时候, ...

  3. [51单片机] nRF24L01 无线模块 串口法命令 通过无线控制另一个的灯

    >_<!概述: 这是在上一个的基础上通过按键发送4种不同命令来控制接收端的LED灯亮的改进版(上一个:http://www.cnblogs.com/zjutlitao/p/3840013. ...

  4. 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】

    关键词:Android  linux hrtimer 蜂鸣器  等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418  作 ...

  5. 如何检测 51单片机IO口的下降沿

    下降沿检测,说白了就是满足这样一个逻辑,上次检测是1,这次检测是0,就是下降沿. 从这个条件可知,要确保能够正确检测到一个下降沿,负脉冲的宽度,必须大于一个检测周期,当负脉冲宽度小于一个检测周期,就有 ...

  6. Arduino和C51之串口通信

    技术:51单片机.Arduino.串口通信   概述 本文主要讲解串口通信技术的使用方法,并通过串口点灯实验介绍了51单片机和Arduino串口的使用,为初学者学习串口知识提供帮助 详细 代码下载:h ...

  7. STM32GPIO口8种模式细致分析(类比51单片机)

    关于STM32GPIO口的8种工作模式,我们先引出一些问题? STM32GPIO口如果既要输入又要输出怎么办? 1.浮空输入模式 上图红色的表示便是浮空输入的过程,外部输入时0读出的就是0,外部输入时 ...

  8. Linux 虚拟串口及 Qt 串口通信实例

    Linux 虚拟串口及 Qt 串口通信实例 2011-06-22 17:49 佚名 互联网 字号:T | T Linux 虚拟串口及 Qt 串口通信实例是本文所要介绍的内容,在实现过程中,打开了两个伪 ...

  9. STM32之模拟串口设计

    一.设计用途: 公司PCB制成板降成本,选择的MCU比项目需求少一个串口,为满足制成板成本和项目对串口需求,选择模拟一路串口. 二.硬件电路: 三.设计实现: 工具&软件:STM32F030R ...

随机推荐

  1. python select.select模块通信全过程详解

    要理解select.select模块其实主要就是要理解它的参数, 以及其三个返回值.select()方法接收并监控3个通信列表, 第一个是所有的输入的data,就是指外部发过来的数据,第2个是监控和接 ...

  2. GitHub上整理的一些资料

    技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...

  3. 2T以上的盘怎么分区, 利用parted创建 linuxTB硬盘GPT分区

    parted创建GPT分区(fdisk不支持创建GPT分区,GPT支持大于2TB分区,MBR不支持) 介绍2种分区表: MBR分区表:(MBR含义:主引导记录) 所支持的最大卷:2T (T; tera ...

  4. Day24 中间件 自定义分页 ModelForm 序列化 缓存 信号

    在views里边,怎么导入局部配置和全局配置 from s18day24 import settings #这样导入的是仅仅用户自定义的配置 from django.conf import setti ...

  5. 【转】火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法

    关于 GCJ-02 和 BD-09 ,请参考 http://developer.baidu.com/map/question.htm#qa0043 . 算法代码如下,其中 bd_encrypt 将 G ...

  6. svn path already exists的解决办法

    这种问题的一般原因是这个path所指的目录在服务器端是一个空目录,对客户端不可见,客户端如果新建了这个目录,而且向服务器端commit的时候就会报错,服务器端此目录已存在,这个时候就会存在一个问题:就 ...

  7. bootstrap响应式设计简单实践。

    首先需要熟悉Boostrap提供的响应式设施:http://getbootstrap.com/css/#responsive-utilities,BootStrap的响应式设施主要是利用媒体查询对元素 ...

  8. Ocelot中文文档-中间件注入和重写

    警告!请谨慎使用. 如果您在中间件管道中看到任何异常或奇怪的行为,并且正在使用以下任何一种行为.删除它们,然后重试! 当在Startup.cs中配置Ocelot的时候,可以添加或覆盖中间件.如下所示: ...

  9. DDGScreenShot —图片加各种滤镜高逼格操作

    写在前面 图片加各种滤镜操作,当然苹果给开发者提供了相关的api和封装, 大部分开发者感觉这是这是晦涩难懂的,接下来就让我们来了解一下, 其实也没有那么深不可测. 代码如下(每一步已经解释的很详细) ...

  10. java文件传输之文件编码和File类的使用

    ---恢复内容开始--- 我们知道,在用户端和服务端之间存在一个数据传输的问题,例如下载个电影.上传个照片.发一条讯息.在这里我们 就说一下文件的传输. 1.文件编码 相信大家小时候玩过积木(没玩过也 ...