serial.c
来自「一个分选系统的软件:用SmallRtos操作系统」· C语言 代码 · 共 387 行
C
387 行
/*********************************************************************************************************
** Small RTOS(51)
** The Real-Time Kernel(For Keil c51)
**
** (c) Copyright 2002-2002, chenmingji
** All Rights Reserved
**
** V1.20.0
**
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: serial.c
**创 建 人: 陈明计
**最后修改日期: 2003年8月31日
**描 述: 在DP-51上实现闹钟的例子的串行口驱动程序
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 陈明计
** 版 本: V1.00
** 日 期: 2003年3月25日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 版 本: V1.20.0
** 日 期: 2003年8月31日
** 描 述: 根据新版本要求修改
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_SERIAL
#include "config.h"
/* 声明使用的外部变量 */
extern uint8 OS_Q_MEM_SEL NotUse _at_ 0x0100;
extern uint8 OS_Q_MEM_SEL SerialInData[20]; /*给读串囗消息队列分配的队列空间*/
extern uint8 OS_Q_MEM_SEL SerialOutData[20];/*给写串囗消息队列分配的队列空间*/
//extern uint8 OS_Q_MEM_SEL Alarm[];
void PutChar(uint8 Data);
bit SerialCanSend = 1; /* 正在发送标志,0:正在发送 */
/*********************************************************************************************************
** 函数名称: SerialInit
** 功能描述: 初始化串行口
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 曾银玲
** 日 期: 2004年11月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SerialInit(void)
{
TMOD=0x21;// 16 bit timer and bound = mode 2
PCON=0x00;//0x80 bound double
SCON=0xd0;//50 8,n,1 parity:odd or even
TH1=0xfd;//tab[0];
TL1=0xfd;//tab[0];
TR1 = 1;
ES = 1;
}
/*********************************************************************************************************
** 函数名称: Send
** 功能描述: 发送一个数据包
** 输 入: Data:指向要发送的数据指针
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年3月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/* void Send(uint8 OS_Q_MEM_SEL *Data)
{
uint8 Sem;
PutChar(STARTBYTE1);
PutChar(STARTBYTE2);
Sem = STARTBYTE1 + STARTBYTE2;
PutChar(*Data);
Sem += *Data++;
PutChar(*Data);
Sem += *Data++;
PutChar(*Data);
Sem += *Data++;
PutChar(*Data);
Sem += *Data++;
PutChar(*Data);
Sem += *Data++;
PutChar(-Sem);
}
*/
/*********************************************************************************************************
** 函数名称: PutChar
** 功能描述: 发送一个字节
** 输 入: Data:发送的数据
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年3月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void PutChar(uint8 Data)
{
OS_ENTER_CRITICAL();
if (SerialCanSend == 1)
{
SerialCanSend = 0;
SBUF = Data; /* 串口空闲,直接发送 */
}
else
{
OSQIntPost(SerialOutData,Data); /* 数据入队 */
}
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** 函数名称: TaskReceive
** 功能描述: 串口接收处理任务
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 曾银玲
** 日 期: 2004年11月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TaskReceive(void)
{
//uint8 temp,temp1;
uint8 k;
/* 建立所需要的消息队列 */
// OSQCreate(CommandData, 16);
OSQCreate(SerialInData, 16);
OSQCreate(SerialOutData, 16);
SerialInit(); /* 初始化串行口 */
while (1)
{
if(rcv_inf01==0x07){rcv_inf01=0;rcv_flag=1;
out_6k();}
if((rcv_inf11==1)||(rcv_inf01==1)){//修改时间
write_12887();rcv_inf11=0;rcv_inf01=0;}
if((rcv_inf10==0x02)||(rcv_inf00==0x02)){//发送时间
send_y_h();re_start=1;}//rcv_inf10=0;
if((rcv_inf11==0x02)||(rcv_inf01==0x02)){//发送信息
send_inf();}//rcv_inf11=0;
if(rcv_inf01==0x03){ //修改页码
rcv_inf01=0;
mon=date[0];
pa=mon;
*(&pa+1)=mon>>8;
sp=&pa;
buffer1write(2,260);
delay(400);
buffer1topageprogerase(0); //pageaddr
delay(400);
}
if(rcv_inf00==0x05){ //发送页码
while(!trans_over){}
SBUF=0xfc;trans_over=0;
while(!trans_over){}
SBUF=0x05;trans_over=0;
while(!trans_over){}
SBUF=mon;trans_over=0;
// while((UARTLSR&0x60)==0){}
//UARTTHR=0xfc;
// while((UARTLSR&0x60)==0){}
// UARTTHR=0x05;
// while((UARTLSR&0x60)==0){}
// UARTTHR=mon;
rcv_inf00=0;
}
if(rcv_inf00==0x06){//清零第0页
rcv_inf00=0;
// pa=&lose; //刘宝贵修 本条有语法错误 是不是这个样子:pa&=lose
for(k=0;k<0x108;k++){
*(&pa+k)=0;}
sp=&pa;
buffer1write(0x108,0);
delay(400);
buffer1topageprogerase(0); //pageaddr
delay(400);
}
}
}
/*********************************************************************************************************
** 函数名称: comm
** 功能描述: 串口中断处理程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 曾银玲
** 日 期: 2004年11月25日
**-------------------------------------------------------------------------------------------------------
** 修改人: 曾银玲
** 日 期: 2004年11月31日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#pragma disable /* 除非最高优先级中断,否则,必须加上这一句 */
/* void comm(void) interrupt 4
{
uint8 data temp;
if (RI == 1)
{
OS_INT_ENTER();
RI = 0;
OSQIntPost(SerialInData,SBUF);
OSIntExit();
return;
}
if (TI == 1)
{
TI = 0;
if (OSQAccept(&temp,SerialOutData) == OS_Q_OK)
{
SBUF = temp;
}
else
{
SerialCanSend = 1;
}
}
}
*/
void serial_INT(void) interrupt 4 using 2
{
uint8 i;
if(TI){trans_over=1;TI=0;}
if(RI){
i=SBUF;
if(!head00_over){
if(i==0xfc){ head00_over=1;}}
//else if(!head01_over){if(i==0xfc){head01_over=1;}}
else if(!head02_over){ //re0_c=0;
if(i==0x33){rcv_inf00=7;head02_over=1;}
else if(i==0x01){head02_over=1;rcv_inf00=1;}
else if(i==0x02){rcv_inf00=2;head00_over=0;head01_over=0;head02_over=0;}
else if(i==0x03){head02_over=1;rcv_inf00=3;}
else if(i==0x04){head02_over=1;rcv_inf00=4;}
else if(i==0x05){rcv_inf00=5;head00_over=0;head01_over=0;head02_over=0;}
else{ if(i==0x06){rcv_inf00=6;head00_over=0;head01_over=0;head02_over=0;}}}
else{
if(rcv_inf00==0x07){
rx[re0_c]=i;re0_c++;rcv_flag=0;noinf_4s=0;
if(re0_c>=5){rcv_inf01=7;re0_c=0;
head00_over=0;head01_over=0;head02_over=0;}}
else if(rcv_inf00==0x01){date[re0_c]=i;re0_c++;
if(re0_c==6){head00_over=0;head01_over=0;head02_over=0;
rcv_inf01=1;re0_c=0;}}
else if(rcv_inf00==0x03){lenth[re0_c]=i;re0_c++;
if(re0_c>=4){rcv_inf01=2;re0_c=0;
head00_over=0;head01_over=0;head02_over=0;}}
else if(rcv_inf00==0x04){date[0]=i;rcv_inf01=3;head00_over=0;head01_over=0;head02_over=0;}}
RI=0;
}
}
/*********************************************************************************************************
** 函数名称: send_y_h
** 功能描述: 串口发送时间程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 曾银玲
** 日 期: 2004年11月25日
************************************************************************************************************/
void send_y_h(void)
{uint8 i;
read_date();read_time();
if(rcv_inf00==0x02){
rcv_inf00=0;
while(!trans_over){}
SBUF=0xfc;trans_over=0;
while(!trans_over){}
SBUF=0x02;trans_over=0;
for(i=0;i<6;i++){
while(!trans_over){}
SBUF=date[i];
trans_over=0;}}
if(rcv_inf10==0x02){
rcv_inf10=0;
while((UARTLSR&0x60)==0){}
UARTTHR=0xfc;
while((UARTLSR&0x60)==0){}
UARTTHR=0xfc;
for(i=0;i<6;i++){
while((UARTLSR&0x60)==0){}
UARTTHR=date[i];}}
}
/*********************************************************************************************************
** 函数名称: send_y_h
** 功能描述: 串口发送信息程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 曾银玲
** 日 期: 2004年11月25日
************************************************************************************************************/
void send_inf(void)
{
uint16 i,j,start_octet,end_octet;
lenth[2]=BCD_D(lenth[2]);
lenth[3]=BCD_D(lenth[3]);
start_octet=(lenth[0]<<8)+lenth[1];
end_octet=start_octet+(lenth[2]<<8)+lenth[3];
if(rcv_inf01==0x02){
rcv_inf01=0;
while(!trans_over){}
SBUF=0xfc;trans_over=0;
while(!trans_over){}
SBUF=0x03;trans_over=0;
for(i=start_octet;i<end_octet;i++){
page_buffer2_trans(i);
delay(400);
buffer2_read(0x107,0);
delay(400);//可修改
for(j=0;j<0x107;j++){
while(!trans_over){}
SBUF=*(sp0+j);trans_over=0;
}}
}
if(rcv_inf11==0x02){
rcv_inf11=0;
while((UARTLSR&0x60)==0){}
UARTTHR=0xfc;
while((UARTLSR&0x60)==0){}
UARTTHR=0x03;
for(i=start_octet;i<end_octet;i++){
page_buffer2_trans(i);
delay(400);
buffer2_read(0x107,0);
delay(400);//可修改
for(j=0;j<0x107;j++){
while((UARTLSR&0x60)==0){}
UARTTHR=*(sp0+j);
}}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?