📄 serial.c
字号:
/*
名称:main.c
日期:2005.01.12
作者:廖志凯
功能:
说明:程序使用RTX51实时多任务系统,
*/
#pragma large
#include "serial.h"
/*------------------------------------------------------------------------------*/
//定义串口缓冲区
uchar xdata cRecvBuff[RECV_GRUOP][RECV_LENGTH]; //接收缓冲区
uchar xdata cRecvBuffNum; //已接收数据的字节数
uchar xdata cRecvBuffPtr; //接收缓冲区有效数据起始指针
uchar xdata cRecvBuffCnt; //接收缓冲区有效数据总数
uchar xdata cTranBuff[TRAN_GRUOP][TRAN_LENGTH]; //发送缓冲区
uchar xdata cTranBuffNum; //已发送数据的字节数
uchar xdata cTranBuffPtr; //发送缓冲区有效数据起始指针
uchar xdata cTranBuffCnt; //发送缓冲区有效数据总数
/*------------------------------------------------------------------------------*/
uchar xdata cRecvBuff2[RECV_LENGTH2]; //接收缓冲区
uchar xdata cRecvBuffNum2; //已接收数据的字节数
uchar xdata cTranBuff2[TRAN_GRUOP2][TRAN_LENGTH2]; //发送缓冲区
uchar xdata cTranBuffNum2; //已发送数据的字节数
uchar xdata cTranBuffPtr2; //发送缓冲区有效数据起始指针
uchar xdata cTranBuffCnt2; //发送缓冲区有效数据总数
/*===============================================================
功能:串口初始化
参数:
返回:
说明:
===============================================================*/
void Init_Serial(void)
{
//初始化串口寄存器
SCON = 0x50; //模式1,8位通讯,允许接收
SCON2 = 0x50; //模式1,8位通讯,允许接收
PCON = 0x00; //SMOD,SMOD1=0;
TMOD |= 0x20; //模式2,8位自载
TH1 = 0xFA;
TL1 = 0xFA; //波特率9600
TR1 = 1; //启动Timer1
ET1 = 0; //禁止Timer1中断
os_enable_isr(SIO_VECTOR);
os_enable_isr(SI1_VECTOR);
//os_disable_isr(SI1_VECTOR);
//初始化缓冲区
memset(cRecvBuff,0x00,RECV_GRUOP*RECV_LENGTH);
cRecvBuffNum = 0x00;
cRecvBuffPtr = 0x00;
cRecvBuffCnt = 0x00;
memset(cTranBuff,0x00,TRAN_GRUOP*TRAN_LENGTH);
cTranBuffNum = 0x00;
cTranBuffPtr = 0x00;
cTranBuffCnt = 0x00;
memset(cRecvBuff2, 0x00, RECV_LENGTH2);
cRecvBuffNum2 = 0x00;
memset(cTranBuff2, 0x00, TRAN_GRUOP2*TRAN_LENGTH2);
cTranBuffNum2 = 0x00;
cTranBuffPtr2 = 0x00;
cTranBuffCnt2 = 0x00;
}
/*===============================================================
功能:
参数:
返回:
说明:
===============================================================*/
void Write_serial_buff(uchar *buff, uchar len)
{
uchar _index;
if(cTranBuffCnt < TRAN_GRUOP)
{
_index = (cTranBuffPtr + cTranBuffCnt) % TRAN_GRUOP;
memcpy(cTranBuff[_index], buff, len);
cTranBuffCnt++;
//os_send_message(MBX_SERAIL_TRAN, 0x00, T10MS);
}
}
/*===============================================================
功能:串口0 中断程序
参数:无
返回:无
说明:只给相应任务发送信号
===============================================================*/
void Int_Serial0(void) interrupt SIO_VECTOR
{
uchar xdata _index;
uchar xdata _data;
if(RI)
{//接收中断
RI = 0;
_data = SBUF;
//isr_send_message(MBX_SERAIL_RECV, SBUF);
if(cRecvBuffCnt < RECV_GRUOP)
{//接收缓冲区未满
_index = (cRecvBuffPtr+cRecvBuffCnt) % RECV_GRUOP; //缓冲区的偏移地址
if(_data == 0xFF)
{//如果收到起始符
cRecvBuff[_index][0] = 0xFF;
cRecvBuffNum = 0x01;
}
else if( (cRecvBuffNum > 0x00) && (cRecvBuffNum < RECV_LENGTH) )
{//其他数据
cRecvBuff[_index][cRecvBuffNum] = _data;
cRecvBuffNum++;
if(cRecvBuffNum == (cRecvBuff[_index][1] + 3) )
{//接收完毕
cRecvBuffCnt++;
cRecvBuffNum = 0x00;
}
}
else if(cRecvBuffNum >= RECV_LENGTH)
{//接收的数据超过缓冲区容量清除当前接收的数据
cRecvBuffNum = 0x00;
memset(&cRecvBuff[_index][0],0x00,RECV_LENGTH);
}
}
}
if(TI)
{//发送中断
TI = 0;
isr_send_signal(STRAN_TASK_ID);
}
}
/*===============================================================
功能:串口1 中断程序
参数:无
返回:无
说明:只给相应任务发送信号
===============================================================*/
void Int_Serial1(void) interrupt SI1_VECTOR
{
if(SCON2&0x01)
{//接收中断
SCON2 &= 0xFE;
cRecvBuff2[cRecvBuffNum2] = SBUF2;
if( ((cRecvBuff2[cRecvBuffNum2] == 'D') || (cRecvBuff2[cRecvBuffNum2] == 'W'))
&& (cRecvBuff2[cRecvBuffNum2-1] == 'D') )
{//接收到数据头
cRecvBuff2[0] = 'D';
cRecvBuff2[1] = cRecvBuff2[cRecvBuffNum2];
cRecvBuffNum2 = 1;
}
else if( (cRecvBuff2[cRecvBuffNum2] == 0x0A) && (cRecvBuff2[cRecvBuffNum2-1] == 0x0D) )
{//接收完毕
isr_send_signal(CONFIG_TASK_ID);
}
cRecvBuffNum2++;
}
if(SCON2&0x02)
{//发送中断
SCON2 &= 0xFD;
isr_send_signal(DEBUG_TASK_ID);
}
}
/*===============================================================
功能:串口接收任务
参数:无
返回:无
说明:缓冲区采用先进先出的原则,当缓冲区已满则停止接收
邮件的参数是接收数据的长度。只有接收到数据头才开始接收数据
===============================================================*/
void Serial_RECV_Task(void) _task_ SRECV_TASK_ID
{
static uchar xdata _index;
static uint xdata _data;
while(1)
{
//os_wait(K_SIG,0x00,0x00); //等待串口接收数据
os_wait(K_MBX+MBX_SERAIL_RECV, 0x00, &_data);
if(cRecvBuffCnt < RECV_GRUOP)
{//接收缓冲区未满
_index = (cRecvBuffPtr+cRecvBuffCnt) % RECV_GRUOP; //缓冲区的偏移地址
if((uchar)_data == 0xFF)
{//如果收到起始符
cRecvBuff[_index][0] = 0xFF;
cRecvBuffNum = 0x01;
}
else if( (cRecvBuffNum > 0x00) && (cRecvBuffNum < RECV_LENGTH) )
{//其他数据
cRecvBuff[_index][cRecvBuffNum] = (uchar)_data;
cRecvBuffNum++;
if(cRecvBuffNum == (cRecvBuff[_index][1] + 3) )
{//接收完毕
cRecvBuffCnt++;
cRecvBuffNum = 0x00;
}
}
else if(cRecvBuffNum > RECV_LENGTH)
{//接收的数据超过缓冲区容量清除当前接收的数据
cRecvBuffNum = 0x00;
memset(&cRecvBuff[_index][0],0x00,RECV_LENGTH);
}
}
}
}
/*===============================================================
功能:串口发送任务
参数:无
返回:无
说明:发送
邮件的参数是要发送数据的长度
===============================================================*/
void Serial_Tran_Task(void) _task_ STRAN_TASK_ID
{
static uchar xdata _sendNum;
while(1)
{
if( (cTranBuffCnt != 0x00) && (cTranBuffPtr < TRAN_GRUOP) )
{//有数据要发送
_sendNum = 0x00;
while(_sendNum < cTranBuff[cTranBuffPtr][1]+3)
{//数据是否发送完毕
SBUF = cTranBuff[cTranBuffPtr][_sendNum];
os_wait(K_SIG,0x00,0x00); //等待数据发送完毕
_sendNum++;
}
//清除发送完毕的数据
memset(&cTranBuff[cTranBuffPtr][0], 0x00, TRAN_LENGTH);
cTranBuffPtr = (cTranBuffPtr+1) % TRAN_GRUOP;
cTranBuffCnt --;
}
os_wait(K_TMO, T10MS, 0x00);
}
}
/*===============================================================
功能:调试任务
参数:无
返回:无
说明:发送调试信息,第一个字节为发送长度,后面为协议
===============================================================*/
void Debug_Task(void) _task_ DEBUG_TASK_ID
{
while(1)
{
if( (cTranBuffPtr2<TRAN_GRUOP2) && (cTranBuffCnt2 != 0x00) )
{
cTranBuffNum2 = 0x01;
while(cTranBuffNum2 < cTranBuff2[cTranBuffPtr2][0])
{
SBUF2 = cTranBuff2[cTranBuffPtr2][cTranBuffNum2];
cTranBuffNum2++;
os_wait(K_SIG, 0x00, 0x00);
}
//清除发送完毕的数据
memset(&cTranBuff2[cTranBuffPtr2][0], 0x00, TRAN_LENGTH2);
cTranBuffPtr2 = (cTranBuffPtr2+1) % TRAN_GRUOP2;
cTranBuffCnt2 --;
}
else
os_wait(K_TMO, T10MS, 0x00);
}
}
/*===============================================================
功能:写入调试信息
参数:type-类型;buff-数据;
返回:无
说明:
===============================================================*/
void Write_Debug_Info(uchar* buff, uchar len)
{
uchar _tmp;
if( (cTranBuffCnt2 < TRAN_GRUOP2) && ((len+3) <TRAN_LENGTH2) )
{//缓冲区还有空间
_tmp = (cTranBuffPtr2+cTranBuffCnt2)%TRAN_GRUOP2; //计算偏移地址
memset(cTranBuff2[_tmp], 0x00, TRAN_LENGTH2);
cTranBuff2[_tmp][0] = len+3;
memcpy(&cTranBuff2[_tmp][1], buff, len);
cTranBuff2[_tmp][len+1] = 0x0D;
cTranBuff2[_tmp][len+2] = 0x0A;
cTranBuffCnt2++;
}
}
/*===============================================================
功能:设置任务,完成组号的设定和读取
参数:
返回:
说明:组号从地址0x8000开始放置,每个组号共五个汉字
总共16组
===============================================================*/
void Config_Task(void) _task_ CONFIG_TASK_ID
{
static uchar xdata _tmp;
static uchar xdata _buff[160];
while(1)
{
os_wait(K_SIG, 0x00, 0x00);
//去除回车符
cRecvBuff2[cRecvBuffNum2-1] = 0x00;
cRecvBuff2[cRecvBuffNum2-2] = 0x00;
_tmp = (cRecvBuff2[2]-'0')*10 +cRecvBuff2[3] - '0';
}
}
/*===============================================================
功能:
参数:
返回:
说明:
===============================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -