⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soft_rs232.c

📁 51系列单片机的软件串口模拟程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    soft_receive_init();               //监测起始位, RXD 下降沿触发接收字节过程.     
}

void soft_send_enable (void)	       //允许发送  
{
    TCON_ENABLE_TIMER = 0;             //停止定时器  
    rs_f_TI_enable = 1;                //允许发送  
    rs_f_RI_enable = 0;                //禁止接收  

    rs_shift_count = 0;                //清移位计数器  
    rs_f_TI   = 1;                     //发送一个字符完毕标志  
    TCON_ENABLE_TIMER = 1;             //启动定时器
}

void soft_rs232_interrupt( void )
{
    /************************ 接收 ****************************/
    if (rs_f_RI_enable == 1)
    {
        if (rs_shift_count == 0)        //移位计数器==0, 表示检测到起始位的起点   
        {
            if ( rs_RXD == 1 )
            {
                soft_receive_enable (); //起始位错, 从新开始   
            }
            else
            {
                //下次中断在数据位或停止位中的某时刻发生    
                rs_timerL += rs_FULL_BIT_L + 0x10; 
                rs_timerH = rs_FULL_BIT_H;
                rs_shift_count++;              
                rs_BUF = 0;             //清移位缓冲变量   
            }
        }
        else
        {
            rs_timerL += rs_FULL_BIT_L; //下次中断在数据位或停止位中发生    
            rs_timerH = rs_FULL_BIT_H;
                                       
            rs_shift_count++;           //2--9:数据位 10:停止位 
                                       
            if ( rs_shift_count == 9)
            {
                rs_BUF = rs_BUF >> 1;   //接收第8位   
                rs_BUF_bit7 = rs_RXD;
//                if( ReceivePoint < rs_RECEIVE_MAX)
//                {                       //保存收到的字节    
                    rs232buffer[ReceivePoint++] = rs_BUF;
//                }
//                else
//                {
//                    rs_f_RI_enable = 0; //缓冲区满, 禁止接收   
//                }
            }
            else
            {
                if (rs_shift_count < 9 ) //收到的是数据位 1 -- 7  
                {
                    rs_BUF = rs_BUF >> 1;
                    rs_BUF_bit7 = rs_RXD;
                }
                else
                {   //收到停止位,继续检测 PC 机发出的下一个起始位    
                    soft_receive_init(); 
                }
            }
        }
        TCON_TFx = 0;                  //清定时器中断标志   
    }
    else
    {
        /************************ 发送 ****************************/  
        if (rs_f_TI_enable == 1)
        {
            rs_timerL += rs_FULL_BIT_L;//下次中断在数据位的末尾时刻   
            rs_timerH = rs_FULL_BIT_H;

            rs_shift_count--;          //0:停止位末尾时刻到  
                                       //1:发送停止位  
                                       //2--9:发送数据位  
            if (rs_shift_count > 9)    //错误状态  
            {
                rs_shift_count = 9;
                rs_BUF = 0xFF;
            }

            if (rs_shift_count > 1)    //2--9:发送数据位  
            {
                ACC = rs_BUF;
                ACC = ACC >> 1;
                rs_TXD = CY;
                rs_BUF = ACC;
            }
            else
            {
                if (rs_shift_count == 0) //0:停止位末尾时刻到  
                {
                    rs_TXD = 1;
                    rs_f_TI = 1;       //已发送完毕一个字节  
                }
                else
                {
                    rs_TXD = 1;        //1:发送停止位  
                }
            }
        }
    }
}

//由收转到发时,要先调用 soft_send_enable ()  
void rs_send_byte(INT8U SendByte)      //发送一个字节  
{
    while ( rs_f_TI == 0);             //等待发送完毕前一个字节  
    rs_TXD = 1;
    rs_timerL = rs_START_BIT_L;        //下次中断在起始位的末尾时刻   
    rs_timerH = rs_START_BIT_H;
    rs_BUF = SendByte;
    rs_shift_count = 10;
    rs_TXD = 0;                        //发送起始位  
    rs_f_TI = 0;                       //清已发送完毕一个字节的标志   
}

void initiate_MCU (void)               //系统初始化  
{
    soft_rs232_init();                 //串口初始化  
    EA = 1;                            //开中断  
}

void delay (INT16U useconds)
{
	for(;useconds>0;useconds--);
}

void send(uint8_t *temp,char j)
{
   	char i=0;
	for (i=0;i<=j-1;i++)          //按发送数据的长度来发送数据
	{
		ACC=*(temp+i);
  	  	SBUF=ACC;                 //发送数据
  	  	while(TI==0);            //发送数据完毕时,TI会自动置高
   	  	TI=0;                  //发送数据完毕,将TI清零,准备下一次发送
	}
}


GsmSend(char * CmdTmp)
{
	char i;
	for(i=0;i<strlen(CmdTmp);i++)
		send(&CmdTmp[i],1);
}

void initial()
{
	PCON= PCON & 0X7F;
	TR1=0;
 	TMOD=TMOD | 0x20;                    //定时器1为自动装入方式 模式2、自动再装入8位计数器
   	ET1 = 0;
 	SCON=0x40;                  //串行口工作方式1:10位URAT,数据传输率可变
 	TH1=0xFD;       
 	TL1=0xFD;         
	//设置数据格式
	//低位在前
	SM0=0;
	SM1=1;
	RI=0;
	TI=0;
	REN=1;
	ES=1;
	TR1=1;
}



void main (void)
{
//首先发送 128 个字节 00H--7FH, 然后等待 PC 机发送的数据。当收到 128
//个字节后,立刻将收到的 128 个数据回发送给 PC 机,然后继续等待下一个
//数据块。
  
    word i;
	initial();
//  	initiate_MCU();                    //系统初始化:定时器模式1、  

    while(1)
    {/*
	   	soft_send_enable ();               //允许发送,禁止接收  
	    rs_send_byte('P');
	    while ( rs_f_TI == 0)  ;           // 等待最后一个字节发送完毕   

        soft_receive_enable ();        //启动并开始接收,禁止发送 
 	    for(i=0;i<4000;i++)
		{
        	if (rs_BUF==0x0D) break ; 
			delay(10);
		}
		rs_f_RI_enable = 0;
		ReceivePoint = 0;
		if(i>=4000) 
		{
			rs232buffer[0]='\0';
			strcpy(rs232buffer,"ERROR!");
		}
*/
		rs232buffer[0]='\0';
		strcat(rs232buffer,"ERROR!");
		rs232buffer[sizeof(rs232buffer)]='\0';
		EA=0;
		GsmSend(rs232buffer);
		EA=1;
		delay(60000);

    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -