?? uartcom.c
字號:
/*
*************************************************************************************************************
* Kingst-51
* Development board samples
*
* (c) Copyright 2009-2012, Kingst Studio
* All Rights Reserved
*
* http://www.kingst.org
* 文件名:UartCom.c
* 描 述:串口通信驅動文件
* 版本號:1.0.0
* 備 注:本驅動提供可按數據塊操作的串口寫入和讀取功能函數,
* 并按照設定的超時時間,自動判斷是否接收完一幀數據,在接收完時設置狀態標志
*************************************************************************************************************
*/
#define _UART_COM_C
#include "config.h"
#include "main.h"
#include "UartCom.h"
/*
********************************************************************************
* ----------------------- Local defines ---------------------------------------
********************************************************************************
*/
/* 接收、發送緩沖區容量設置(最大不能超過126) */
#define RX_BUFF_SIZE 50
#define TX_BUFF_SIZE 30
/* 幀間隔設定,即超過此時間時認定為一幀數據傳輸結束 */
#define FRAME_SPACE_TIME 50 //單位ms
/*
********************************************************************************
* ----------------------- Local variables -------------------------------------
********************************************************************************
*/
/* 通信狀態控制 */
typedef struct {
int8 rxbtm;
int8 rxcnt;
int8 txbtm;
int8 txtop;
} sComSta;
static sComSta ComSta;
static uint8 xdata RxBuff[RX_BUFF_SIZE];
static uint8 xdata TxBuff[TX_BUFF_SIZE];
/*
********************************************************************************
* ----------------------- Globle variables ------------------------------------
********************************************************************************
*/
eUartRxSta UartRxSta = RX_NONE; //串口接收狀態
/*
***************************************************************************************************
* ---------------------------------- Source codes ------------------------------------------------
***************************************************************************************************
*/
/*
* 函數名:UartComInit
* 描 述:初始化串口通信配置
*/
void UartComInit(void)
{
/* 配置T1為波特率發生器 */
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 244; //波特率2400,計算公式如下:
TL1 = 244; //256 - 時鐘頻率/(12*32*波特率)
ET1 = 0;
/* 配置串口工作模式 */
SCON = 0x50;
TR1 = 1;
ES = 1;
}
/*
* 函數名:UartWrite
* 描 述:UART發送函數,向緩沖區寫入指定長度的數據,并啟動發送
* 輸 入:buff - 待寫入數據塊的指針
* len - 待寫入數據塊的長度
* 輸 出:返回值 - 實際寫入的數據長度
*/
int8 UartWrite(const void *buff, int8 len)
{
int8 i, end;
const uint8 *src;
/* 獲取實際可寫入長度 */
EA = 0;
i = ComSta.txtop - ComSta.txbtm;
EA = 1;
if (i < 0) {
i += TX_BUFF_SIZE;
}
i = TX_BUFF_SIZE - i;
if (len > i) {
return 0;
}
/* 拷貝數據到緩沖區中 */
src = (const uint8 *)buff;
i = ComSta.txtop;
end = i + len;
if (end < TX_BUFF_SIZE) {
for (; i<end; i++) {
TxBuff[i] = *src++;
}
}
else {
for (; i<TX_BUFF_SIZE; i++) {
TxBuff[i] = *src++;
}
end -= TX_BUFF_SIZE;
for (i=0; i<end; i++) {
TxBuff[i] = *src++;
}
}
/* 修改緩沖區指向信息 */
EA = 0;
if (ComSta.txbtm == ComSta.txtop) {
TI = 1;
}
ComSta.txtop = end;
EA = 1;
return len;
}
/*
* 函數名:UartRead
* 描 述:UART接收緩沖區讀取函數,讀取指定長度的數據
* 輸 出:在指針上輸出數據,返回實際讀到的數據長度,錯誤時返回-1
* 輸 入:buff - 數據讀取的接收指針
* len - 讀取的數據塊長度(-1為全部讀出)
* 輸 出:buff - 在此指針上輸出讀到的數據
* 返回值 - 實際讀到的數據長度
*/
int8 UartRead(void *buff, int8 len)
{
int8 i, end;
uint8 *dest;
/* 獲取實際可讀取長度 */
EA = 0;
if ((len>ComSta.rxcnt) || (len<0)) {
len = ComSta.rxcnt;
}
EA = 1;
/* 從緩沖區拷貝數據 */
dest = (uint8 *)buff;
i = ComSta.rxbtm;
end = i + len;
if (end < RX_BUFF_SIZE) {
for (; i<end; i++) {
*dest++ = RxBuff[i];
}
}
else {
for (; i<RX_BUFF_SIZE; i++) {
*dest++ = RxBuff[i];
}
end -= RX_BUFF_SIZE;
for (i=0; i<end; i++) {
*dest++ = RxBuff[i];
}
}
/* 修改緩沖區指向信息 */
EA = 0;
ComSta.rxbtm = end;
ComSta.rxcnt -= len;
EA = 1;
return len;
}
/*
* 函數名:UartRxMonitor
* 描 述:UART通信接收的監控函數,用于判定一幀數據的接收完成
* 輸 入:ms - 本函數調用的間隔時間,單位ms
* 輸 出:無
*/
void UartRxMonitor(uint8 ms)
{
uint8 cnt;
static uint8 cntbkp;
static uint8 idletmr;
static uint8 sigpost;
cnt = ComSta.rxcnt;
if (cnt == 0) {
cntbkp = 0;
return;
}
if (cnt != cntbkp) {
idletmr = 0;
sigpost = 0;
cntbkp = cnt;
return;
}
if (sigpost != 0) { //保證接收完成標志只推送一次
return;
}
idletmr += ms;
if (idletmr >= FRAME_SPACE_TIME) {
sigpost = 1;
UartRxSta = RX_FINISH;
}
}
/*
* 函數名:Serial_ISR
* 描 述:串口中斷服務函數
*/
void Serial_ISR() interrupt 4
{
uint8 chr;
int8 top;
/* 接收字符,保存到接收緩沖區中 */
if (RI == 1) {
RI = 0;
chr = SBUF;
if (ComSta.rxcnt < RX_BUFF_SIZE) {
top = ComSta.rxbtm + ComSta.rxcnt;
if (top >= RX_BUFF_SIZE) {
top -= RX_BUFF_SIZE;
}
RxBuff[top] = chr;
ComSta.rxcnt++;
}
}
/* 由發送緩沖區中提取字符,并發送 */
if (TI == 1) {
TI = 0;
if (ComSta.txbtm != ComSta.txtop) {
SBUF = TxBuff[ComSta.txbtm];
ComSta.txbtm++;
if (ComSta.txbtm >= TX_BUFF_SIZE) {
ComSta.txbtm = 0;
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -