微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PIC 单片机软件异步串行口实现技巧

PIC 单片机软件异步串行口实现技巧

时间:09-08 来源:互联网 点击:

;串行通信的波特率不能太高,4 MHz工作的PIC单片机一般能实现2400bps的全双工通信。当然,可以通过提高MCU的振荡频率来实现高波特率通信,当PIC单片机工作在20 MHz时,实现9600b/s绰绰有余。

  2 起始位中断捕捉、定时采样法

实现此法的硬件条件是PIC单片机有外部脉冲下降沿中断触发功能,在中档以上PIC单片机中有RB0/INT外部中断脚,CCP1/CCP2脉 冲沿捕捉脚,PORTB的第4/5/6/7电平变化中断脚等都可以满足。另外需配备一个定时器,以定时中断方式对接收码元正确采样,或发送串行数据流。其 关键的异步接收工作原理简介如图4所示。

  图4

设串行数据位宽度为td。起始位到来时刻(图4 A点)的下降沿触发一个中断并立即响应该中断。在此中断服务中立即关闭本中断使能位(后续的数据流变化无需触发中断),开启定时器,使其在 1.5td后产生定时中断,用于采样第一个数据位(确保S0采样点落在数据位的中心位置处);在处理下降沿中断服务的最后,再检测接收端是否还是0电平, 以区分窄脉冲干扰。在S0点采样到第一个数据位后的所有采样间隔都是1td,直到收到停止位后,关闭定时器中断,重新开放下降沿捕捉中断,准备接收下一个 字节。

异步数据接收和发送的状态机控制流程,除了起始位判断和定时时间参数设置与前述方式不同外,其它几乎一样,此处不再重复。

此法的好处是可以实现较高的通信波特率。对于通信不是很频繁的系统,此软件UART几乎不耗MCU运行带宽,9600b/s接收或发送在4 MHz运行的PIC单片机上即可轻松实现;另外,由于下降沿中断可以唤醒处于睡眠的单片机,故极易实现通信唤醒的功能。缺点是不能全双工通信(除非另外单 独用一个定时器实现发送定时),异步接收的引脚必须有下降沿触发中断的能力。

上面介绍的两种方法在实际产品设计中都得到了很好的验证,最典型的是红外线自动抄表系统。该系统要求收发均为38 kHz红外调制,串行数据1 200bps半双工通讯。用软件实现此UART,并充分利用PIC单片机CCP模块的脉宽调制PWM输出38 kHz载波时,在单片机外除了一个一体化红外接收头和一个红外发射二极管,无需其它任何外围器件,即可完成所有设计要求,最大程度地减化了硬件设计,降低 了成本,提高了系统的可靠性和性能价格比。

以上的侧重点是基本原理的介绍,希望对大家有所帮助。在接收数据的可靠性处理方面没有太多涉及。有兴趣者可以在采样时刻到来时对数据做多次采 样,以消除干扰误码;或有其它处理技巧,欢迎和笔者作进一步交流。

简单的C语言参源程序如下:

#i nclude //PIC单片机通用头文件,实际型号为16F84

__CONFIG(XT | PROTECT | PWRTEN | WDTEN);//程序中设定配置信息

//===========================

//定义软件UART发送/接收引脚

//===========================

#define RX_PIN RB0 //串行接收脚

#define TX_PIN RB1 //串行发送脚

//===========================

//定义软件UART状态机控制字

//===========================

#define RS_IDLE 0 //空闲

#define RS_DATA_BIT 1 //数据位

#define RS_STOP_BIT 2 //停止位

#define RS_STOP_END 3 //停止位结束

//===========================

//定义软件UART采样频率

//===========================

#define OSC_FREQ 4000 //单片机工作频率(单位:KHz)

#define BAUDRATE 1200 //通讯波特率

#define TMR0PRE 2 //TMR0预分频比1:2

#define TMR0CONST 117 //256 - OSC_FREQ*1000/TMR0PRE/4/(BAUDRATE*3)

//===================================================================

// 定义函数类型

void UART_Out(void);

void UART_In(void);

//===================================================================

// 定义位变量

bit rsTxBusy; //串行发送忙标志

//定义串行发送的数据结构

struct {

unsigned char state; //发送状态机控制单元

unsigned char sliceCount; //波特率控制

unsigned char shiftBuff; //字节数据发送移位寄存器

unsigned char shiftCount; //字节数据发送移位计数器

} rsTx;

//定义串行接收的数据结构

struct {

unsigned char state; //接收状态机控制单元

unsigned char sliceCount; //波特率(采样点)控制

unsigned char shiftBuff; //字节数据接收移位寄存器

unsigned char shiftCount; //字节数据接收移位计数器

unsigned char dataBuff[8]; //接收数据FIFO缓冲队列

unsigned char putPtr, getPtr;//FIFO队列存放/读取指针

} rsRx;

//用于串行发送的变量定义

unsigned char outBuff[10]; /

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top