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

📄 mega16软件模拟2个串口程序.c

📁 基于ICCAVR平台的
💻 C
📖 第 1 页 / 共 2 页
字号:
                    cnt = 0; 
                    number = 0; 
                    status = SDATA; 
                } 
                break; 
            case SDATA: 
                if(vmRS232SBUF & 0x01) 
                { 
                    SET_VM232_TX(); 
                } 
                else 
                { 
                    CLR_VM232_TX(); 
                } 
                if(++cnt > 3) 
                { 
                    cnt = 0; 
                    if(++number < 8) 
                    { 
                        vmRS232SBUF >>= 1; 
                    } 
                    else 
                    { 
                        //number = 0; 
                        status = STOP; 
                    } 
                }                 
                break; 
            case STOP: 
                SET_VM232_TX(); 
                if(++cnt > 3) 
                { 
                    cnt = 0; 
                    status = START; 
                    flgVmRs232tx = 0; 
                    // 在这模拟的发送中断,不太实用 
                } 
                break; 
            default: 
                SET_VM232_TX(); 
                cnt = 0; 
                status = START; 
                flgVmRs232tx = 0; 
                break; 
        } 
    } 
} 

void vm_rs485_tx(void) // 模拟485发送函数 
{ 
    static U8 status = START; 
    static U8 cnt = 0; 
    static U8 number = 0; 
    if(flgVmRs485tx) 
    { 
        switch(status) 
        { 
            case START: 
                CLR_VM485_TX(); 
                if(++cnt > 3) 
                { 
                    cnt = 0; 
                    number = 0; 
                    status = SDATA; 
                } 
                break; 
            case SDATA: 
                if(vmRS485SBUF & 0x01) 
                { 
                    SET_VM485_TX(); 
                } 
                else 
                { 
                    CLR_VM485_TX(); 
                } 
                if(++cnt > 3) 
                { 
                    cnt = 0; 
                    if(++number < 8) 
                    { 
                        vmRS485SBUF >>= 1; 
                    } 
                    else 
                    { 
                        //number = 0; 
                        status = STOP; 
                    } 
                }                 
                break; 
            case STOP: 
                SET_VM485_TX(); 
                if(++cnt > 3) 
                { 
                    cnt = 0; 
                    status = START; 
                    flgVmRs485tx = 0; 
                    // 在这模拟的发送中断,不太实用 
                } 
                break; 
            default: 
                SET_VM485_TX(); 
                cnt = 0; 
                status = START; 
                flgVmRs485tx = 0; 
                break; 
        } 
    } 
} 

// 波特率都是2400BIT/S ,416US/BIT     
// 5中取3 ,每104US抽样(也可以3中取2)
// 52US中断交替采样2个模拟串口         

//TIMER2 initialize - prescale:8       
// WGM: Normal                         
// desired value: 52uSec               
// actual value: 52.000uSec (0.0%)     
void timer2_init(void) 
{ 
    TCCR2 = 0x00; //stop           
    ASSR  = 0x00; //set async mode 
    TCNT2 = 0xd3; //setup          
    OCR2  = 0x34; 
    TCCR2 = 0x02; //start          
} 

#pragma interrupt_handler timer2_ovf_isr:5 
void timer2_ovf_isr(void) // 最高优先级中断 在中断里面接收、发送数据   
{ 
    static bool sw = 0;   // 模拟串口交替使用定时器开关,实现104US采样 
    volatile U8 vmRS232, vmRS485; // 记录2模拟串口接收脚的高低电平     
     
    TCNT2 = 0xd3; //reload counter value 
    // 在这采样接收脚保证不漂移 
    vmRS232 = GET_VM232_RX(); //宏定义,获取PD0电平值
    vmRS485 = GET_VM485_RX(); //宏定义,获取PD2电平值
    // 在这增加串口接收检测 
     
    if(sw) // 乒乓操作 2个串口交替发送
    { 
        vm_rs232_tx(); 
        vm_rs232_rx(vmRS232);         
        // 在这增加串口 
        sw = 0; 
    } 
    else 
    { 
        vm_rs485_tx(); 
        vm_rs485_rx(vmRS485); 
        // 在这增加串口 
        sw = 1; 
    } 
} 

/*+++++++++++++++++++++++++++++++++= MAIN =+++++++++++++++++++++++++++++++++++*/ 
void port_init(void) 
{ 
    PORTA = 0xFF; 
    DDRA  = 0xFF; 
    PORTB = 0xFF; 
    DDRB  = 0xFF; 
    PORTC = 0xFF; 
    DDRC  = 0xFF; 
    PORTD = 0xFF; 
    DDRD  = 0B11111010; //PD0 PD2 输入,PD1 PD3 输出 
} 

void init_devices(void) 
{ 
    //stop errant interrupts until set up 
    CLI(); //disable all interrupts       
    port_init(); 
    timer2_init(); 
     
    MCUCR = 0x00; 
    GICR  = 0x00; 
    TIMSK = 0x40; //timer interrupt sources
    SEI(); //re-enable interrupts         
    //all peripherals are now initialized 
} 

void main(void) 
{ 
    init_devices(); 
	
	while(1)
	 {
	  if(outRS232!=inRS232)                 //如果有新的数据输入          
        {              
         while(flgVmRs232tx);               //判断是否处于发送状态        
         vmRS232SBUF=vmRS232Buf[outRS232++];//将新接收到的数据存入发送缓冲
		 if(vmRS232SBUF=='1')               //如果接收到的数据是需要的数据
		  {vmRS232SBUF='K';}
		 else vmRS232SBUF='0';
         flgVmRs232tx=1;                    //发送标志位置1,准备发送     
         if(outRS232>=20)                   //接收、发送都是环型缓冲区    
          { 
           outRS232=0; 
          } 
		}
	 }
	/*
    // 收到什么就回发什么 
    while(1) 
    { 
        if(outRS232 != inRS232) 
        {             
            while(flgVmRs232tx); 
            vmRS232SBUF = vmRS232Buf[outRS232++]; 
            flgVmRs232tx = 1; 
            if(outRS232 >= 20) // 接收、发送都是环型缓冲区 
            { 
                outRS232 = 0; 
            } 
        } 
        if(outRS485 != inRS485) 
        {             
            while(flgVmRs485tx); 
            vmRS485SBUF = vmRS485Buf[outRS485++]; 
            flgVmRs485tx = 1; 
            if(outRS485 >= 20) // 接收、发送都是环型缓冲区 
            { 
                outRS485 = 0; 
            } 
        }     
    } */
} 

/*++++++++++++++++++++++++++++++++++=end=+++++++++++++++++++++++++++++++++++++*/ 
/*  以上是我开始做的2个模拟串口测试全部程序,大家可以按照自己的需要修改使用     
                                                                                
   而在我的工程中我改成了模拟接收完一帧(MAX 30BYTES)数据才请求处理。发送      
   则是用了一个50BYTES环型缓冲区实现随意的发送数据,使用起来非常方便。          
                                                                                
   以上调试中,请大家务必设置好定时器的准确定时。因为实现US级的定时,ICCAVR     
   的‘应用生成’设置不准!另外,单片机的工作频率尽可能高些!!!               
                                                                                
   以上只是一个实现的思想,不足之处请大家指点,我不用3中取2,只是想模拟100%     
   的正确率,在这请大家调试后有什么心得也写出来让大家分享!!                 */ 

⌨️ 快捷键说明

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