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. rubygem若干常用选项参数

    可以用gem help commands看所有支持的参数,这个比gem -h显示的全: wisy@wisy-ThinkPad-X61:~/src/ruby_src$ gem help commands ...

  2. JavaScript设计模式之一封装

    对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,今天我想讲讲如何在Javascript中利用封装这个特性,开讲! 我们会把现实中的一些事物抽象成一个Class并且把 ...

  3. Oracle数据库date类型与Java中Date的联系与转化

    以下是对Java中的日期对象与Oracle中的日期之间的区别与联系做点说明,以期对大家有所帮助.new Date():分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),就是系统当前 ...

  4. JavaScript中对象数组 根据某个属性值 然后push到新的数组

    原文链接 https://segmentfault.com/q/1010000010075035 将下列对象数组中,工资大于1w的员工,增加到对象数组 WanSalary中 var BaiduUser ...

  5. VirtualBox虚拟机网络设置(四种方式)

    原文地址: https://www.douban.com/group/topic/15558388/ VirtualBox的提供了四种网络接入模式,它们分别是: 1.NAT 网络地址转换模式(NAT, ...

  6. JeeSite中Excel导入导出

    在各种管理系统中,数据的导入导出是经常用到的功能,通常导入导出以Excel.CSV格式居多.如果是学习的过程中,最好是自己实现数据导入与导出的功能,然而在项目中,还是调用现成的功能比较好.近期一直使用 ...

  7. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

  8. 四年级--python函数基础用法

    一.函数的定义,调用和返回值 1.1 语法 def 函数(参数一,参数二...): ''' 文档注释 ''' 代码逻辑一 代码逻辑二 .... return 返回值 1.2 定义函数的三种形式 说明: ...

  9. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (一)

    我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI. 什么是FairyGUI 这里照搬FaiyGUI官网的介绍: 重新定义 UI 制作 ...

  10. JavaScript高级程序设计(一)

    一.三种常见的著名的命名规则: 1.Camel(驼峰式命名):首字母是小写的,接下来的单词都以大写字母开头.例如:var  myTestValue=0; 2.Pascal(帕斯卡命名):首字母是大写的 ...