Целый день мучаюсь, и нет результата ...
Суть проблемы:
Есть код на С из документации атмел (AVR323).
Я перенес только из ИАРа в аврстудию.
Все вроде замечательно, (был правда вопрос с прерыванием, но он тут уже решился). В железе не работает...
Вычислил после нескольких дней прогонов такое:
есть файл №1 (sms_com.c)
Код:
|
unsigned char rx_ack;
ISR (SIG_UART_RECV)
{
unsigned char data; //Local variable
data = UDR; //Always read something
rx_buffer[ rx_wr_i++ ] = data; //Store new data
.....
if( searchFor[rx_i] == data ) //Test response match
{
rx_i++;
if( !searchFor[rx_i] ) //End of new_message
{
rx_i = 0;
if( searchStr == CMTI_ ) //+CMTI:
{
searchFor = searchStrings[ CRLF_ ]; //Wait for
searchStr = CRLF_;
}
else //Normal acknowledgement
{
rx_ack = 1; //Set new message flag
UCSRB &= ~( 1 ‹‹ RXCIE ); // Disable RX interrupt
}
}
}
else
{
rx_i = 0; //Not valid search pattern...start again.
}
} |
Жирным выделено важное место!
Есть файл №2 (sms_api.c)
Код:
|
// Extern flag from SMS_com.c
extern unsigned char rx_ack;
char API_check_acknowledge( void )
{
uint16_t i;
uint8_t ii;
for( i = 0; ( rx_ack == 0 ) && ( i ‹ 65535 ); i++ ) //Wait loop
{
for( ii = 0; ii ‹ 10; ii++ )
{
;
}
}
if( rx_ack › 0 ) //Everything worked out fine...rx turned off
{
rx_ack = 0; //Reset flag
return 1;
}
else //A timeout could result from no acknowledge,
{
COM_rx_off( ); //Receiver off
COM_rx_reset( ); //Reset buffer and interrupt routine
return 0; //Timed out, or wrong acknowledge from phone
}
} |
Т.е в прерывании при приходе нужного байта меняется флаг, и при обращении ко 2й п/прогр-е ждем некоторое время появление флага.
Дизассемблер показывает, что компил-р отказывается проверять каждый цикл переменную с флагом. Т.е. копирует при входе в ПП значение флага в регистр и дальше проверяет только регистр...
================================================== ===
214: +0000056C: 2D95 MOV R25,R5 Copy register
224: if( rx_ack › 0 ) //Everything worked out fine...rx turned off
+0000057B: 2399 TST R25 Test for Zero or Minus
================================================== ===
Дальше я пробовал все возможные варианты компиляции (-О1, -О2, -О3,)
Переделывал цикл:
Код:
|
for( i = 0; i ‹ 65500; i++ ) //Wait loop
{
for( ii = 0; ii ‹ 200; ii++ )
{
if ( rx_ack == 0 ) break;
}
} |
В конце еще проэксперементировал с обьявлением переменной RX_ACK
Обьявлял ее в регистре, и в статике...
Результат - 0!!!
Как обмануть компи-р???? Или, вернее, правильно код написать?? Нервы на пределе уже...