Ви не увійшли.
Решено.
В одном прерывании обрабатываются все запросы и даются ответы Masterу.
Механизм потери значений переменными при выходе из обработчика не исследован.
Тема закрыта.
Добрый день.
Суть проблемы:
Arduino Mega 2560 с четырьмя подключенными датчиками температуры.
Программа запущенная на компьютере (Master) с интервалом в 1 минуту через USART запрашивает поочередно температуры измеренные 4-мя датчиками.
По приходу первого байта запроса срабатывает обработчик прерывания ISR(USART0_RX_vect).
При некорректном принятии запрос игнорируется, при корректном -
в обработчике формируется массив символов запроса, определяется условный адрес запрашиваемого датчика,
формируеся ответ Masterу, отправляеся, и здесь выход из прерывания. Идет 4 запроса-ответа подряд, естественно еще минимум три раза вызывается прерывание.
Первый ответ содержит действительную температуру датчика, поледующие три ответа (2, 3 и 4 датчики) содержат ноль по температуре.
Причина: обнуляются переменные температур 2, 3 и 4 при первом выходе из прерывания по USART.
Переменные температур обьявлены как volatile.
Где ошибка? Подскажите способ решения?
#include <avr/interrupt.h> //библиотека прерываний
#include <OneWire.h>
#include <DallasTemperature.h>
...
переменные задействованные в void loop() и в обработчике
прерывания ISR(USART0_RX_vect) определены как volatile float
volatile float val_T1; температура 1-го датчика
volatile float val_T2; температура 1-го датчика
volatile float val_T3; температура 1-го датчика
volatile float val_T4; температура 1-го датчика
volatile unsigned char Symb;
volatile unsigned char s[16];
...
функция инициализации прерывания по приходу байта ч/з USART
void USART_Init(int baudrate )
{
UBRR0H = baudrate>>8;
UBRR0L = baudrate;
UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
sei();
}
...
void setup()
{
USART_Init(103);
...
}
...
void USART_Transmit( unsigned char data )//Функция отправки данных
{...}
unsigned char USART_Receive( void )//Функция приема данных
{...}
...
void loop()
{
* * * * *
...
sensors_1.requestTemperatures();
val_T1 = sensors_1.getTempC(add_K1T1);
val_T2 = sensors_1.getTempC(add_K1T2);
val_T3 = sensors_1.getTempC(add_K1T3);
sensors_2.requestTemperatures();
val_T4 = sensors_2.getTempC(add_K1T4);
}
...
//Обрабатываем прерывание по поступлению байта
ISR(USART0_RX_vect)
{
// UDR0; //прининятый байт
s[14] = 0;
if (UDR0 == 35)
{
for (byte ii=2; ii<=14; ii++) {s[ii] = USART_Receive();}
if (s[14] == 13)
{
ArrReq[0] = s[2];
ArrReq[1] = s[3];
...
определяется условный адрес опрашиваемого датчика
Sens_addres = 128*ArrOut[1] + 64*ArrOut[2] + ... + ArrOut[8];
...
переменной Temp присваивается значение температуры измеренное датчиком
if (Sens_addres == 120) {Temp = val_T1;} 1-й датчик
if (Sens_addres == 121) {Temp = val_T2;} 2-й датчик
if (Sens_addres == 122) {Temp = val_T3;} 3-й датчик
if (Sens_addres == 123) {Temp = val_T4;} 4-й датчик
...
// отправка строки символов, (ответ на запрос Master'a):
delay(2); // требуется по протоколу обмена с Master'ом
for (byte i=1; i<=27; i++) {USART_Transmit(ArrPac[i]);}
}
}
}