Исходник я дам, не проблема, но в стуктуре данных будешь сама разбираться. CRC не считал, а использовал обычную контрольную сумму.
Передающую часть сама разберешь.
#define x_crc 1 #define x_ptr 2 #define x_use 3 #define x_cta 4 #define x_end 5 #define x_data 6 #define tx_ptr 0
#define Crc_Init FEND
#define MAX_Pack_sz MAX_FRAME_SIZE - 3 #define PreambulaTime 4
#define FESC 0xDB #define FEND 0xC0 #define TFESC 0xDD #define TFEND 0xDC #define tx_end 1 //FESC=> FESC+TFESC //FEND=> FESC+TFEND
typedef void (*LRead_CallBack) (signed char);
typedef struct { unsigned char Pre;//Предыдущий байт unsigned char Crc; unsigned char Ptr;//указатель текущего байта в буфере unsigned char Ready;//флаг готовности буфера unsigned char CTA;//флаг синхронизации со тсартовым байтом unsigned char End;//указатель на последний байт в буфере //unsigned char Length;//Длина пакета unsigned char Frame[MAX_Pack_sz]; } TFrameBuf;
//-****************************************-/ //-* interrupt handled uart reсеiver / //-****************************************
#pragma vector=RS485_RXC_VECTOR __interrupt void USART1_RXC_interrupt( void ) { register char Sdata,temp;
Sdata=RS485_PORT;
if (Sdata==FEND){ //получен старт, синхронизируемся
RX_driver_Errorlevel=Sinc_err; Frame_buf.CTA=1; Frame_buf.Ptr=x_end;//=6, последний байт заголовка перед буфером if(Frame_buf.Ready)RX_driver_Errorlevel=Buf_overrun;//Set ErrorLevel Frame_buf.Ready=0; Frame_buf.Crc=Crc_Init;//то есть =FEND Frame_buf.End=MAX_Pack_sz+x_end;//потом подрихтуется?????????????????
} else if (Frame_buf.CTA)//sinchronized {
temp=Frame_buf.Pre; Frame_buf.Pre=Sdata; if (temp==FESC){ if ((Sdata!=TFESC)|(Sdata!=TFEND)) {Frame_buf.CTA=0; RX_driver_Errorlevel=Sinc_err; //Set ErrorLevel
} ; if (Sdata==TFESC) {Sdata=FESC;}; if (Sdata==TFEND) {Sdata=FEND;}; } else {// No STuffing
if (Sdata!=FESC){//proceed byte if (Frame_buf.Ptr==x_end){//first simbol is length if(Sdata> MAX_Pack_sz)Frame_buf.End=MAX_Pack_sz+x_data; else Frame_buf.End=Sdata+x_data; };
Frame_buf.Frame[Frame_buf.Ptr-x_end]=Sdata; //Store Byte //в том числе и CRC!
Frame_buf.Ptr++; if (Frame_buf.Ptr >Frame_buf.End ){ //pack recd
if (Frame_buf.Crc==Sdata){// crc ok
RX_driver_Errorlevel= RX_OK; Frame_buf.Ready=1; Frame_buf.CTA=0; if ( LL_ReadCallback!=NULL)LL_ReadCallback(Frame_buf.Frame[0]); //В этом колбаке просто ставится флажок, что данные прибыли
} else {//bad crc Frame_buf.Ready=0; Frame_buf.CTA=0; RX_driver_Errorlevel=BadCrc;
}; } else {Frame_buf.Crc+=Sdata;};// pack rcd };//proceed }; //no stuffing }//Sinchronized };
|