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 + -
显示快捷键?