单片机串口通信

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机串口通信

关键词:单片机,串口通信

单片机应用中,串口通信是不可缺少的部分。如何编写有效的串口通信程序对程序的结构、可靠性都有很大的影响。串口控制程序一般分为查询和中断两者方式。查询方式适用于简单的应用,简单可靠,但是缺点是需要占用处理器资源,在发送或者接收数据的时候不能做其它的事情,处理器利用率低。中断方式下,在发送或者接受数据的时候处理器还可以做其它的工作,效率较高。

对于稍微复杂的系统来说,中断方式管理串口程序将会更加有效。中断处理方式也可分为几种,其中采用循环缓冲区的方式比较高效。循环缓冲区为定义的一定长度的RAM区间,对于接受数据来说,中断中收到的数据将存入RAM中,然后等待主程序来读取。其中会涉及到数据见的协调问题,写数据的时候不能把还没有读取的数据覆盖掉,读数据的时候应该读取的是缓冲区中最老的数据。当缓冲区已满的时候,写入的新数据应该覆盖掉最老的数据。这些问题的处理可以使用两个指针来实现。

初始化时两个指针均指向RAM区间的底部,如图1所示。当中断中接收到一个数据的时候,将这个数据写入写指针WPTR指向的存储单元,然后调整写指针指向下一个空余的RAM区间,程序上处理就是把写指针加一,如图2所示。同理,写入N个数据后写指针同步更新,如图3所示。

当读数据的时候,首先判断缓冲区中是否有数据,方法是判断读指针和写指针是否相等,如果相等表明没有数据,如图5所示。如果读指针和写指针不等,那么读取缓冲区中的数据,然后调整读指针,当写指针和读指针相等的时候,表明缓冲区中的有效数据已经读取完,此时读指针和写指针相等。

当有数据再次写入的时候,继续紧接着上次写入的地址后写入新的数据,如果数据长度超过缓冲区的长度,写指针重新返回缓冲区的底部重新开始(这是循环缓冲的由来),如图6所示。此时如果有数据读出,读指针做同样的更新。如果没有数据读出,一直有数据写入,可能会出现缓冲区写满的情况,如图7所示。此时如果仍然没有数据读取,继续有数据写入的时候,为了保留新的数据,必须丢弃老的数据,即写指针可能超过读指针,此时,读指针必须和谐指针同步更新,这样才能保证读取的是没有被覆盖的最老的数据,如图8所示。

需要注意的是,读指针在中断过程中也可能被更改,因此,读数据的子程序需要对读指针的更改进行保护,方法是在读数据的时候关闭串行口中断。下面是循环缓冲区接收数据的程序实例。

FT, 尽然连文本都不能上传,代码只好贴出来吧。

/*

* FileName: uart.h

* Description: header file for SerialPort

* Author: SangWei, HUST-CEEE-2004

* Contact: swkyer@, swkyer@

* Date: 2005-09-22

*

* Platform: P89C6102(Philips), KeilC51(ver: 7.20)

*

* (C)All Rights Reserved.

*/

#ifndef __UART_H__

#define __UART_H__

#define UARTBUFFLEN 64 /* 串口缓冲区64个字节*/

void UartInit(void);

void SendChar(unsigned char ch);

unsigned char IsUartReceived(void);

unsigned char ReadChar(unsigned char idata *buf);

#endif /* __UART_H__ */

/*

* FileName: uart.c

* Description: Implementation of SerialPort

* Author: SangWei, HUST-CEEE-2004

* Contact: swkyer@, swkyer@ * Date: 2005-09-22

*

* Platform: P89C6102(Philips), KeilC51(ver: 7.20) *

* (C)All Rights Reserved.

*/

#include

#include "hardware.h"

#include "uart.h"

unsigned char data ramuse;

static unsigned char idata uartbuf;

static unsigned char idata bufwptr, bufrptr;

extern unsigned char xdata uartbuff[UARTBUFFLEN];

/*

* 初始化串口, 波特率9600

*/

void UartInit(void)

{

CLR_DOG;

status = 0;

bufwptr = 0; // 写指针

bufrptr = 0; // 读指针

MAX485CTL = 0; // 接收数据

PCON = 0x00; // 设置串口波特率, 时钟频率30MHZ

T2CON = 0x30; // 定时器2作为波特率发生器

SCON = 0x50; // 模式1

// n = 65536 - [fosc/baud*32]

// n = 65536 - 30000000/(19200*32) = 65536 - 49 = 654 90 = 0xffd2

// n = 65536 - 22118400/(19200*32) = 65536 - 36 = 655 00 = 0xffdc

#ifdef _DEBUG_AT_HOME

RCAP2H = 0xff;

RCAP2L = 0xb8; // baud rate 9600

TH2 = 0xff;

TL2 = 0xb8;

#else

RCAP2H = 0xff;

RCAP2L = 0x9e; // baud rate 9600

TH2 = 0xff;

相关文档
最新文档