• PUDN用户
    了解作者
  • Visual C++
    开发工具
  • 2KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 4
    下载次数
  • 2012-03-26 18:38
    上传日期
atmega128编程时,用的Rs485通讯程序
RS485.rar
  • RS485.c
    7.2KB
内容介绍
#include <avr/io.h rel='nofollow' onclick='return false;'> #include <avr/interrupt.h rel='nofollow' onclick='return false;'> #include <avr/signal.h rel='nofollow' onclick='return false;'> #include <avr/delay.h rel='nofollow' onclick='return false;'> #include <stdio.h> #include <math.h> #include <avr/pgmspace.h rel='nofollow' onclick='return false;'> #include <avr/eeprom.h rel='nofollow' onclick='return false;'> #include <avr/wdt.h rel='nofollow' onclick='return false;'> #include "SERIAL.H" #include <avr/crc16.h rel='nofollow' onclick='return false;'> #include "DA7724.h" /*******************************************************************************************************************/ void TxChar(unsigned char data ) { while( !(UCSR0A & (1<<UDRE0)) ); UDR0=data; } unsigned short crc16_check (unsigned char *data , int size) //CRC校验函数 { int i; unsigned short crc=0xffff; for( i=0;i<size;i++) { crc=_crc16_update(crc,data[i]); //_crc16_update()为从crc16.h直接调用的CRC校验函数 } return crc; } void ModbusError() //错误帧处理函数 { int i; unsigned char uchCRCHi; unsigned char uchCRCLo; unsigned short crc_value; PORTE&=~_BV(PE2); if(Error_flag==1) //异常码 buf_serial[1] = buf_serial[1] + 0x80 ; if(Error_flag==2) buf_serial[1] = buf_serial[1] + 0x40 ; if(Error_flag==3) buf_serial[1] = buf_serial[1] + 0xA0 ; buf_serial[2] = 2 ; for(i=0;i<3;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, 3) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); PORTE|=_BV(PE2); Error_cnt++; PORTD ^= (1<<PD1); } void Function03() //读寄存器 { int crc_back; int i ; int act_add ; int send_length ; //发送数据长度 unsigned char uchCRCHi; unsigned char uchCRCLo; unsigned short crc_value; crc_back=(buf_serial[crc_len+1]<<8)|buf_serial[crc_len]; if (crc16_check(buf_serial,crc_len)==crc_back) { PORTE&=~_BV(PE2); //不同功能的上位机命令帧例子 add_data.chPara[0]=buf_serial[3] ; //01 10 00 00 00 04 04 12 34 56 78 42 35 66 77 d5 a0 add_data.chPara[1]=buf_serial[2] ; //01 03 00 00 00 01 84 0a size_data.chPara[0]=buf_serial[5] ; //01 10 00 00 00 02 04 12 34 56 78 88 9b size_data.chPara[1]=buf_serial[4] ; // 01 06 00 02 00 aa a8 75 act_add =add_data.ParaBuff -4; if(act_add<0) act_add=0; buf_serial[2] =size_data.ParaBuff* 2 ; //返回的AD采样数据的字节个数 for(i=0 ; i<size_data.ParaBuff; i++) { buf_serial[3+i*2] =Temper[(act_add+i)*2]; buf_serial[4+i*2] =Temper[(act_add+i)*2+1]; } send_length = 3 + size_data.ParaBuff *2 ; for(i=0 ;i<send_length ;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, send_length) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); _delay_ms(16); PORTE|=_BV(PE2); Error_flag=0; PORTD ^= (1<<PD2); } else { Error_flag=2; ModbusError() ; } data_finished=0 ; } void Function06() //写单个寄存器 { int crc_back; int act_add ; int i ; unsigned char uchCRCHi; unsigned char uchCRCLo; unsigned short crc_value; crc_back=(buf_serial[crc_len+1]<<8)|buf_serial[crc_len]; if (crc16_check(buf_serial,crc_len)==crc_back) { PORTE&=~_BV(PE2); add_data.chPara[0]=buf_serial[3] ; add_data.chPara[1]=buf_serial[2] ; act_add =add_data.ParaBuff -12; if(act_add<0) act_add=0; if(act_add<4&&act_add>=0) Write_Sign=1; else if(act_add>=4) Write_Sign=2; if(Write_Sign==1) { DA7724_add=act_add; DA[act_add*2+1]=buf_serial[5] ; DA[act_add*2]=buf_serial[4] ; OUT_Value_S=(DA[act_add*2]<<8)|DA[act_add*2+1]; for(i=0;i<6;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, 6) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); _delay_ms(16); PORTE|=_BV(PE2); Error_flag=0; Update_DA7724_Flag=1; } if(Write_Sign==2) { Switch_add=act_add-4; Switch_size=size_data.ParaBuff; Switch_Value_S=(buf_serial[4]<<8)|buf_serial[5]; for(i=0;i<6 ;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, 6) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); _delay_ms(16); PORTE|=_BV(PE2); Update_Switch_Flag=1; Error_flag=0; } } else { ModbusError() ; Error_flag=2; } data_finished=0 ; } void Function16() //写多个寄存器 { int crc_back; int i ; int act_add ; unsigned char uchCRCHi; unsigned char uchCRCLo; unsigned short crc_value; crc_back=(buf_serial[crc_len+1]<<8)|buf_serial[crc_len]; if (crc16_check(buf_serial,crc_len)==crc_back) { PORTE&=~_BV(PE2); add_data.chPara[0]=buf_serial[3] ; add_data.chPara[1]=buf_serial[2] ; size_data.chPara[0]=buf_serial[5] ; size_data.chPara[1]=buf_serial[4] ; act_add =add_data.ParaBuff -12; //首地址 if(act_add<0) act_add=0; if(act_add<4&&act_add>=0) Write_Sign=1; else if(act_add>=4) Write_Sign=2; if(Write_Sign==1) { DA7724_add=act_add; DA7724_size=size_data.ParaBuff; for(i=0 ; i< (size_data.ParaBuff) ;i++) { DA[(act_add+i)*2+1]=buf_serial[8+i*2]; DA[(act_add+i)*2]=buf_serial[7+i*2]; OUT_Value_M[act_add+i]=(DA[(act_add+i)*2]<<8)|DA[(act_add+i)*2+1]; } for(i=0;i<6 ;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, 6) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); _delay_ms(16); PORTE|=_BV(PE2); Error_flag=0; Update_DA7724_Flag=2; } if(Write_Sign==2) { Switch_add=act_add-4; Switch_size=size_data.ParaBuff; for(i=0 ; i< size_data.ParaBuff;i++)//() { Switch_Value[Switch_add+i]=(buf_serial[7+i*2]<<8)|buf_serial[8+i*2]; } for(i=0;i<6 ;i++) TxChar(buf_serial[i]) ; crc_value=crc16_check(buf_serial, 6) ; uchCRCLo=crc_value&0x00ff; uchCRCHi=crc_value>>8; TxChar(uchCRCLo); TxChar(uchCRCHi); _delay_ms(16); PORTE|=_BV(PE2); Update_Switch_Flag=2; Error_flag=0; } } else { ModbusError() ; Error_flag=2; } data_finished=0 ; } void Communication() //通信子函数 { if(data_finished) { if(buf_serial[0] ==0x02) { switch (buf_serial[1]) { case 0x03 : Function03() ; break ; case 0x06 : Function06() ; break ; case 0x10 : Function16(); break; default: Error_flag=1; data_finished=0 ; ModbusError() ; data_length= 0 ; break; } } else { // Error_flag=3; data_finished=0 ; // ModbusError() ; data_length= 0 ; } } }
评论
    相关推荐