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

📄 rs485.c

📁 485通讯的底层驱动,完成485网络数据收发功能
💻 C
字号:
//ICC-AVR application builder : 2006-5-14 20:37:14
// Target : M16
// Crystal: 16.000Mhz

#include <iom16v.h>
#include <macros.h>

#define unchar unsigned char
#define unint unsigned int
#define CONH    PORTD|=0X04
#define CONL    PORTD&=0XFB

static unchar COMID;
static unchar ip=0;
unchar CY;

static unchar *s;
rechar(void);

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
}

//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x01;
 UCSRC = BIT(URSEL) | 0x06;
 UBRRL = 0x67; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x98;
}

#pragma interrupt_handler uart0_rx_isr:12           
void uart0_rx_isr(void)                             //中断桢接收函数
{ unchar CS=0X00;
  unchar temp;
  char i,j;
  CLI();                                            //关闭中断
  temp=UDR ;                                        //中断接收第一个字节
  if(temp!=0xfe)                                    //判断是否为前导字
     CY=0X00;                                       //不是前导字 标志字置0
  else 
   {do
       temp=rechar();                               //继续接收
	while(temp==0xfe)                               //是否为前导字
	           ;
	   if(temp!=0x68)                               //是否为桢头
	      CY=0X00;                                  //不是  标志字置0;
	   else                                         //是 继续接收
	      {
		  CS+=0X68;                                 //CRC垒加
		  *s=rechar();                              //ID接收
		  CS+=*s;
		  if(rechar()!=0x68)                        //是否为数据段桢头
		    CY=0X00;                                //不是  CY=0
		  else                                      //继续接收
		     {
			  CS+=0X68;
			  CS+=(*(s+1)=rechar());                //接收命令字节
			  *(s+2)=rechar();                      //接收数据长度
			  j=*(s+2);
			  CS+=j;
			  for(i=0;i<(j-1);i++)
			     CS+=(*(s+i+3)=rechar());           //数据区接收
			  if(CS!=rechar())	 
                       CY=0X00;	                    //CRC校验
			  else 
			     {
				 if(rechar()!=0x16)	                //桢尾判断
                           CY=0X00;	                //不是 CY=0;
				  else 
				      {
					  if(*s!=COMID)                //地址匹配校验
				           CY=0X00; 	
						else 
						     CY=0XFF;               //接收成功,地址匹配成功
						              }				//置命令处理标志CY			        
						   }
				    }	
		       }	  
	    }
		SEI();                                      //打开中断
}


//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void COM_ID(void)                                  //读取拨码开关的值
{
  DDRB|=0X04;
  PORTB|=0X04;
  COMID=PORTA;
}

void COM_inint(void)                               //485的初始化程序
{
  uart0_init();                                    //串口初始化
  CONL;                                            //初始设置为接收模式
}
rechar(void)
{
 while(!(UCSRA&0x80))
 ;
 return UDR;
}


void sendchar(unsigned char m)                     //字节发送
{
 while(!(UCSRA&(1<<UDRE)))
 ;
 UDR=m;
}

void data_send(unchar *s)                         //数据桢发送函数   
{
 unchar CS=0X68;
 char i,j;
 CONH;                                            //切换为发送模式
 delay();                  
 sendchar(0xfe);                                  //发送前导字
 sendchar(0xfe);                                  //发送前导字
 sendchar(0x68);                                  //发送桢头
 CS+=*s;                                          //接收方地址
 sendchar(*s);
 CS+=0x68;                                        //数据段开始标志
 CS+=*(s+1);
 sendchar(*(s+1));                                //命令字发送
 CS+=*(s+2);
 sendchar(*(s+2));                                //数据段长度发送
 j=*(s+2);
 for(i=0;i<(j-1);i++)                             //数据发送
 { 
  sendchar(*(s+3+i));
  CS+=*(s+i+3);
  }
 sendchar(CS);                                    //CRC发送
 sendchar(0x16);                                  //桢尾发送
 delay();
 CONL;                                            //切换为接收状态
}

void delay(void)
{}

main()
{
}

⌨️ 快捷键说明

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