/*
*************************************************************************************************************
* 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 30 //单位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;
}
}
}
}
上位机发送指令给单片机 单片机完成相应指令动作
3星 · 超过75%的资源 需积分: 35 35 浏览量
2013-05-08
11:45:55
上传
评论 3
收藏 113KB ZIP 举报
u010598063
- 粉丝: 0
- 资源: 2
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈