Witam forumowiczów,
Sytuacja wygląda tak, że z jednostki nadrzędnej słane są ramki danych,
Po każdej ramce jest szczelina czasowa tak aby nasza ATmega zdążyła odpowiedzieć,
Mamy Atmega16 kwarc 16MHz i transmisje 57600 (w przybliżeniu),
Gadamy przez RS485 tak, że między ramkami jeszcze przełączam linie bufora,
Steruje równocześnie buforem wejścia i wyjścia tak, że kiedy nadajemy to nic nie wraca z powrotem,
Z grubsza działa to tak, że przy inicjacji włączam w UCSRB bity RXCIE, TXEN, RXEN,
No i z każdym odebranym bajtem zgłasza się przerwanie od RX,
Kiedy przyjdzie cała ramka, zgodzą się znaczki początku i końca oraz suma kontrolna to przechodzę na odbiór,
Przełączam linie bufora oraz włączam UDRIE w UCSRB,
W tym momencie kiedy rejestr wyjściowy UDR będzie pusty (czyli od razu) program skacze do przerwania SIG_UART_DATA,
Wysyłam sobie całą ramkę a po ostatnim bajcie wyłączam UDRIE oraz włączam TXCIE,
Kiedy przychodzi przerwanie SIG_UART_TRANS ustawiam linie RS na odbiór i wyłączam TXCIE,
Wszystko działa dobrze ale krótko,
Po kilkuset ramkach program się zachowuje tak jak by po kolejnym wysłanym bajcie nie przychodziło przerwanie i nie ma co popędzać programu do przodu,
Przepełnienie stosu? niby jak?
Reszta programu działa bez zarzutów mimo, że komunikacja stoi,
Procedury odbioru i zapisu osobno też działają bez zarzutu,
Program wygląda tak:
inicjacja USARTA:
Jeśli ktoś ma pomysł to z góry dziękuję.
Sytuacja wygląda tak, że z jednostki nadrzędnej słane są ramki danych,
Po każdej ramce jest szczelina czasowa tak aby nasza ATmega zdążyła odpowiedzieć,
Mamy Atmega16 kwarc 16MHz i transmisje 57600 (w przybliżeniu),
Gadamy przez RS485 tak, że między ramkami jeszcze przełączam linie bufora,
Steruje równocześnie buforem wejścia i wyjścia tak, że kiedy nadajemy to nic nie wraca z powrotem,
Z grubsza działa to tak, że przy inicjacji włączam w UCSRB bity RXCIE, TXEN, RXEN,
No i z każdym odebranym bajtem zgłasza się przerwanie od RX,
Kiedy przyjdzie cała ramka, zgodzą się znaczki początku i końca oraz suma kontrolna to przechodzę na odbiór,
Przełączam linie bufora oraz włączam UDRIE w UCSRB,
W tym momencie kiedy rejestr wyjściowy UDR będzie pusty (czyli od razu) program skacze do przerwania SIG_UART_DATA,
Wysyłam sobie całą ramkę a po ostatnim bajcie wyłączam UDRIE oraz włączam TXCIE,
Kiedy przychodzi przerwanie SIG_UART_TRANS ustawiam linie RS na odbiór i wyłączam TXCIE,
Wszystko działa dobrze ale krótko,
Po kilkuset ramkach program się zachowuje tak jak by po kolejnym wysłanym bajcie nie przychodziło przerwanie i nie ma co popędzać programu do przodu,
Przepełnienie stosu? niby jak?
Reszta programu działa bez zarzutów mimo, że komunikacja stoi,
Procedury odbioru i zapisu osobno też działają bez zarzutu,
Program wygląda tak:
SIGNAL(SIG_UART_RECV){
char data,cs;
unsigned char a;
data=UDR;
if (rx_pos){
rx_buffer[rx_pos]=data;
rx_pos++;
if (rx_pos==3){
rx_len=data;
if ((rx_len+5)>rs_buffer_len){
rx_len=0;
rx_pos=0;
sbi(rs_status, reciving_error);
}
}
}else{
if (data==master_frame_begin_sign){
rx_buffer[0]=data;
rx_pos=1;
}
}
if ((rx_pos>4) && (rx_pos>=rx_len+5)){
rx_pos=0;
if (rx_buffer[rx_len+4]==frame_end_sign){
cs=cs_base_sign;
for (a=0; a<rx_len+3; a++){
cs^=rx_buffer[a];
}
if (cs==rx_buffer[rx_len+3]){
if ( (rx_buffer[1]==0) && (rx_buffer[2]==2) ){
sbi(rs_status, recived_valid_frame);
if ( (output_prv[0]==rx_buffer[3]) && (output_prv[1]==rx_buffer[4]) ){
output[0]=rx_buffer[3];
output[1]=rx_buffer[4];
}
output_prv[0]=rx_buffer[3];
output_prv[1]=rx_buffer[4];
DIR_W; //------------------------------------ PRZECHODZIMY NA TRANSMISJE
sbi(UCSRB, UDRIE); // int empty buffer enable
}
}else{
sbi(rs_status, reciving_error);
}
}else{
sbi(rs_status, reciving_error);
}
}
}
SIGNAL(SIG_UART_DATA){
unsigned char a,cs;
if (tx_pos){
UDR=tx_buffer[tx_pos];
if (tx_pos>=6){ // last byte in frame --> go to transmiting
cbi(UCSRB, UDRIE); // int tx ready disable
sbi(UCSRA, TXC); // clear transmit int flag
sbi(UCSRB, TXCIE); // int tx finish enabled
// while(!(UCSRA&(1<<TXC)));
// sbi(UCSRA, TXC); // clear transmit int flag
// DIR_R;
tx_pos=0;
}else{
tx_pos++;
}
}else{
UDR=slave_frame_begin_sign;
tx_pos=1;
tx_buffer[1]=0;
tx_buffer[2]=2;
tx_buffer[3]=input[0];
tx_buffer[4]=input[1];
cs=cs_base_sign^slave_frame_begin_sign;
for (a=1; a<5; a++){
cs^=tx_buffer[a];
}
tx_buffer[5]=cs;
tx_buffer[6]=frame_end_sign;
}
}
SIGNAL(SIG_UART_TRANS){
DIR_R;
cbi(UCSRB, TXCIE);
}
inicjacja USARTA:
UBRRH=0;
UBRRL=34; // 57.143bps (57.600)
UCSRA=0b00000010; // double speed
UCSRB=0b10011000; // int Rx enabled
UCSRC=0b10001110; // 8bit 2 stop
Jeśli ktoś ma pomysł to z góry dziękuję.