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

📄 m8sp01.c

📁 AVR MEGA8双机串行口通讯程序,单工485方式,用于单片机组网,有PROTEUS仿真电路,可以立刻验证
💻 C
字号:
//////////从机

#include <iom8v.h>
#include <macros.h>
//ISARM pro
#define OUTLED1OFF PORTB|=0x01       //for 
#define OUTLED1ON PORTB&=~0x01
#define OUTLED2OFF PORTB|=0x02       //For 
#define OUTLED2ON PORTB&=~0x02
#define OUTLED2Pulse PORTB^=0x02

#define OUTLED3OFF PORTB|=0x04      //For 
#define OUTLED3ON PORTB&=~0x04
#define OUTLED3Pulse PORTB^=0x04
#define OUTLED4OFF PORTB|=0x08      //For 
#define OUTLED4ON PORTB&=~0x08
#define OUTLED4Pulse PORTB^=0x08

#define OUTDEON PORTD|=0x10
#define OUTDEOFF PORTD&=~0x10

#define KB0 (PINC&0x01)
#define KB1 (PINC&0x02)


///UART///
#define TXENABLE UCSRB&=~(1<<RXEN);UCSRB|=(1<<TXEN); 
#define RXENABLE UCSRB&=~(1<<TXEN);UCSRB|=(1<<RXEN); 
#define RXADDRESS UCSRA|=(1<<MPCM);TRADFG=0;
#define RXDATA UCSRA&=~(1<<MPCM);TRADFG=1;
//
#define TRFG0 0xFE
#define TRFG1 0xFD
#define TRFG2 0xF1
#define TRFG3 0xF0
//子板编号
#define SlaveAdress 5
//////////////////////////////
unsigned char TRADFG=0;  //0收地址,1收数据
unsigned char RDHIS=0xff;

unsigned char SlaveCR=0;  //子板编号计数器,当作物理地址
unsigned char TXINTMAX=12;//下行发送中断次数控制值
//unsigned char TXINTCR=0;//下行发送中断次数计数器
unsigned char TXINTFG=0;//下行发送中断次数完成标志
unsigned char RXINTMAX=16;//下行发送中断次数控制值
unsigned char RXINTCR=0;//下行发送中断次数计数器
unsigned char RXINTFG=0;//下行发送中断次数完成标志

unsigned char TXBUF[16]; //发送缓冲区
unsigned char RXBUF[30];  //接收缓冲区
unsigned char TXbufP=0;  //发送缓冲区下标
unsigned char RXbufP=0;  //接收缓冲区下标
unsigned char RXbufPmax=11;//接收数据实际长度

unsigned char RXERROR=0;
/////Soft Timer
unsigned char WaitCR0=0;
unsigned char WaitCR1=0;

unsigned char SLSTEP=10;


void SoftTimer(void)
  {
    WaitCR0++;
	if(WaitCR0>254)
	 {
	  WaitCR0=0;
	  WaitCR1++;
	 }//if(WaitCR0>0)
  }
void SoftTimerStart(void)
  {
   WaitCR0=0;
   WaitCR1=0;
  }
  
void watchdog_init(void)
     {
	   WDR();
	   WDTCR=0x0F ;
	 }
	 
void Delay_1ms(void)
	{
	unsigned int i;

	for (i = 1; i<1140; i++)
		
			;
	}

void delayXms(unsigned int n)
     {
	   unsigned int i=0;
	   while(i<n)
	     {
		  Delay_1ms();
		  i++;
		 }
	 }
	 
	 
void port_init(void)
     {
	 
					 
	  PORTB=0xFF;    //PB set to 1
	  DDRB=0xFF;     
					 
	  PORTC=0xFF;    //PC set to 1
	  DDRC=0x00;     //
	      
	  PORTD=0xFF;    //PD set to 1
	  DDRD=0x12;     //PD0:RXD PD1:TXD PD2:DI0 PD3:DI1
	                 //PD4:DI2  PD5:DI3 
	  //OUTDEON;
	  
	SFIOR&=~(1<<PUD);  //OPEN UP LINK
	//MCUCR|=(1<<ISC11); //Down edge int1
	//GICR=(1<<INT1); //enable INT1
	  
	  delayXms(10); //delay 1s
	 }
//////////////////////////UART INIT
void uart_init(void) 
   {
    
    OUTDEOFF;
    UCSRB=0x00;
	//UBRRL=0x25;  //19.2kbps
	UBRRL=0x1;  //38.4kbps
	//TX EN ,9Bit ,Adress init
	RXADDRESS
	UCSRB=((1<<RXCIE)|(1<<TXCIE)|(1<<UCSZ2));
	//UCSRB=((1<<TXCIE)|(1<<TXCIE)|(1<<TXEN)|(1<<TXB8));
   }//void uart_init(void) 

///////////////Timer init	 
void timer_init(void)
     {
	  ;
	 }	 	 
	

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{	
	 ;  
	 
}//void timer1_ovf_isr(void)

//TR to SLAVE
#pragma interrupt_handler uart1_tx_isr:14
void uart1_tx_isr(void)
 {
    
	TXbufP++;
	
	   if(TXbufP==TXINTMAX) //发送完成
	    {	       
		 OUTDEOFF; 
		 SLSTEP=10;
		 
	    }//if(TXbufP>TXINTMAX)
	 else
	  {
	   UDR=TXBUF[TXbufP];  
	  }//else
	
 }//void uart1_tx_isr(void)

#pragma interrupt_handler uart1_rx_isr:12
void uart1_rx_isr(void)
 {	
    unsigned char TmpD=0;
	
	TmpD=UDR;
	
	if(TRADFG==0)
	 {
	  if((TmpD==SlaveAdress) && (RDHIS==SlaveAdress))
	   {
	    OUTLED2ON;
	    RXDATA	   
		RXbufP=0;
	   }//if(TmpD==SlaveAdress && RDHIS==SlaveAdress)
	  RDHIS=TmpD;
	 }//if(ADFG==0)
	else
	  {
	   
       if(RXbufP<RXINTMAX)
	     {
		 
	     RXbufP++;
	     }		
	     RXBUF[RXbufP]=TmpD;
	    
	  }//else
 }//void uart1_rx_isr(void)
void TXbufRDY(void)
{
 
 TXBUF[0]=TRFG0;
 TXBUF[1]=TRFG1;
 TXBUF[2]=SlaveAdress;
 TXBUF[10]=TRFG2;
 TXBUF[11]=TRFG3;
}//void TXbufRDY(void)
void RXBUFCLR(void)
{
  unsigned char i=0;
  for(i=0;i<RXINTMAX;i++)
      RXBUF[i]=0;
}//void RXBUFCLR(void)

void RX_INIT(void)
{
    OUTDEOFF; 
    RXbufP=0;
	RDHIS=0xff;
	RXADDRESS
	
	RXENABLE
}//void RX_INIT(void)

void RXRCK2(void)  //检查收到的数据是否有效
{

 if(RXbufP>RXbufPmax)
   {
    
	RXERROR=2;
	if(RXBUF[12]==TRFG3 & RXBUF[11]==TRFG2 & RXBUF[1]==TRFG0 & RXBUF[2]==TRFG1)
	 {
	   
		RXERROR=0;
	 }			   
		
	}//if(RXbufP>RXbufPmax)
  else
   {
	RXERROR=1;
   }//else
  
    // OUTLED1ON;
}//void RXRCK(void)

void RXRCK(void)  //检查收到的数据是否有效
{
 unsigned char tP=0;
 unsigned char i=0;
 if(RXbufP>RXbufPmax)
   {
   // OUTLED1ON;
	RXERROR=2;
	if(RXBUF[12]==TRFG3 & RXBUF[11]==TRFG2 & RXBUF[1]==TRFG0 & RXBUF[2]==TRFG1)
	 {
	  RXERROR=3;
	  if(RXBUF[3]==SlaveCR)
	   {
		RXERROR=0;
					   
		} //if(RXBUF[tP+2]==SlaveCR)
					
	  }//if(RXBUF[i]==TRFG3
	}//if(RXbufP>RXbufPmax)
  else
   {
	RXERROR=1;
   }//else
}//void RXRCK(void)


void main()
{
   unsigned char i=0;
   
	//delayXms(500); 
	port_init(); //IO初始化	
	uart_init();
	//timer_init();
	delayXms(10); 
	SEI();
	SLSTEP=10;
	
	while(1)
	 {
	  
	  switch(SLSTEP)
	   {
	    case 10:
		  RXBUFCLR();
	      RX_INIT();
		  SLSTEP=20;
		break;
	    case 20:
		 if(TRADFG==1)
	      {
		   SoftTimerStart();
		   SLSTEP=30;
		  }//if(ADFG==1)
		   
		break;
		case 30:
		  SoftTimer();
		  
		     
		  if((WaitCR1>20) | (RXbufP>RXbufPmax))
		    {
			 RXRCK2();
			 if(RXERROR==0)
			   {
			   OUTDEON;
			   TXbufRDY();
			   TXbufP=0;
			   TXENABLE
			   UDR=TXBUF[0];
			   SLSTEP=40;
			   OUTLED1ON;
			   }//if(RXERROR==0)
			 else
			   {			    		
			    SLSTEP=10;
			   }//else
			 
			}//if((WaitCR1>100) | (RXbufP>RXbufPmax))
		 
		break;
		case 40:
		break;
	   }//switch(SLSTEP)
	 
     }//while1
}//main

⌨️ 快捷键说明

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