roboforum.ru

Технический форум по робототехнике.
Текущее время: 30 ноя 2024, 05:02

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 144 ]  На страницу Пред.  1 ... 6, 7, 8, 9, 10
Автор Сообщение
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 24 июн 2013, 03:51 
Не в сети
Аватара пользователя

Зарегистрирован: 10 ноя 2011, 12:02
Сообщения: 5691
Откуда: Turku, Finland
Skype: elmot73
прог. языки: Java и все-все=все
ФИО: Илья
Коллизия будет. Так что аккуратнее со множественным доступом. гуглить "запрет прерываний", "критическая секция", "volatile".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 24 июн 2013, 05:33 
Не в сети

Зарегистрирован: 04 май 2013, 10:35
Сообщения: 203
Откуда: Тюмень
Korbofos писал(а):
Ещё небольшой вопрос. Что будет если в основном цикле изменяем значение переменной или регистра, и в этот момент попытаемся изменить значение этой переменной в прерывании?
в таких ситуациях нужно использовать следующий подход:
1) если "ширина" переменной не превышает ширину шины данных (для AVR - 8 бит, т.е. один байт), то достаточно при объявлении переменной сказать компилятору, что переменная ненадёжна (может изменить своё состояние незаметно для компилятора), с помощью ключевого свойства volatile:
Код:
char regularVar; // рядовая переменная типа char
volatile char interruptableVar; // переменная типа char, которая "ненадёжна" для компилятора


2) если "ширина" переменной превышает ширину шины данных, то такая переменная читается АЛУ в несколько заходов, сначала одна часть (один байт для AVR), затем вторая часть, ... Такую переменную, кроме пометки по пункту 1 требуется защитить от прерываний запрещая/разрешая их (например глобально):
Код:
volatile int interruptableVar; // переменная типа int

// не защищённый вариант
interruptableVar = 24;

// защищённый вариант
cli(); // запрет прерываний
interruptableVar = 24;
sei(); // разрешение прерываний


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 24 июн 2013, 13:29 
Не в сети
Аватара пользователя

Зарегистрирован: 15 янв 2011, 11:27
Сообщения: 317
Откуда: Челябинск
прог. языки: C/C++
ФИО: Александр
А если речь идёт о кольцевом буфере достаточно объявить переменную rx_count volatile?
Или надо отменить ещё прерывания? Когда читаю данные из буфера?
Код:
interrupt [USART1_RXC] void usart1_rx_isr(void)
{
if(rx_count < SIZE_BUF)
  {                                 
   rx_buf[rx_in++] = UDR1;       
   if(rx_in == SIZE_BUF)rx_in = 0; 
   rx_count++;                                 
  }
}

unsigned char read (void)
{
unsigned char data;
while(!rx_count);bin
data=rx_buf[rx_out++];
rx_count--;
if(rx_out == SIZE_BUF) rx_out=0;
//------Debag----------
Led(rx,ON);
led_rx_count=1;
//---------------------
return data;
}

Уже замучился, не на все запросы отвечает контроллер по уарту. Вещал диод на переполнение буфера, срабатывания не было.

Добавлено спустя 35 минут 18 секунд:
Вот проект, кому не лень посмотрите пожалуйста, какие косяки в коде есть. Проблема в потере данных по уарту :cry:


Вложения:
ADC_Debag.rar [155.66 КиБ]
Скачиваний: 0

_________________
РАБОТА, РАБОТА перейди на Федота, с Федота на его брата, а ко мне их зарплата.
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 24 июн 2013, 17:54 
Не в сети

Зарегистрирован: 04 май 2013, 10:35
Сообщения: 203
Откуда: Тюмень
Korbofos писал(а):
Или надо отменить ещё прерывания? Когда читаю данные из буфера?

Да, надо. Т.к. буфер - это массив данных он не может читаться/писаться за один присест

Добавлено спустя 24 минуты 59 секунд:
Я уже давно подобный код не пишу. Я бы сделал так:
в прерывании по приёму байта с UART-а, помещаю байт в приёмный буфер (так же как и ты), но сразу анализируя протокольную часть (детектирование флагового байта, кол-ва байт и т.п.). В прерывании, как только обнаружил конец передачи, выставил флаг завершения (который видно из главного цикла) и запретил прерывания по приёму. А в главном цикле только проверяю этот флаг. Если флаг выставлен, то читаю буфер без необходимости защищать чтение от прерываний (т.к. единственные прерывания, которые изменяют буфер уже запрещены).
А у тебя я вижу, что ты "умертвляешь" главный цикл в функции read() (while(!rx_count);)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 25 июн 2013, 10:23 
Не в сети
Аватара пользователя

Зарегистрирован: 15 сен 2007, 13:03
Сообщения: 6338
Откуда: Красноярск
прог. языки: ASM(МК), C(PC)
ФИО: Гагарский Андрей Александрович
а два буфера с поочередным использованием не круче ?

_________________
«Как сердцу выразить себя? … Мысль изреченная есть ложь!»
В этом мире меня подводит доброта и порядочность...
"двое смотрят в лужу, один видит лужу, другой отраженные в ней звезды"


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 25 июн 2013, 21:23 
Не в сети
Аватара пользователя

Зарегистрирован: 15 янв 2011, 11:27
Сообщения: 317
Откуда: Челябинск
прог. языки: C/C++
ФИО: Александр
Извиняюсь за навязчивость :( Стоит ли отключать прерывания, когда присваивается значение переменной wait в основном цикле?
Код:
volatile unsigned char wait=0;

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(wait)wait--;       // таймер ожидания прихода байта
if(!wait)TCCR0=0x00;     
}

bool read_byte(unsigned char byte)
{
unsigned char i=0;
if(!TCCR0)TCCR0=0x04;
wait = wait_time * byte;  //Добавить сюда запрет прерывания?
while(rx_count < byte)       // ожидание прихода нужного количества байт
     {
      if(!wait)
        {
         Led(lost_byte,ON);
         led_wait_count=250;
         #asm("cli")
         rx_count=0;  //очищаем буфер если пришло нужное количество байт
         #asm("sei")
         return 0;
        }
     }
for(;byte>1;byte--)data[i++]=read();
wait=0;     
if(read()==checksum)return 1;   //проверка контрольной суммы в конце пакета
return 0;         
}

_________________
РАБОТА, РАБОТА перейди на Федота, с Федота на его брата, а ко мне их зарплата.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 25 июн 2013, 23:09 
Не в сети

Зарегистрирован: 04 май 2013, 10:35
Сообщения: 203
Откуда: Тюмень
Korbofos писал(а):
Стоит ли отключать прерывания, когда присваивается значение переменной wait в основном цикле?
Код:
volatile unsigned char wait=0;

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(wait)wait--;       // таймер ожидания прихода байта
if(!wait)TCCR0=0x00;     
}
...
Нет, т.к. char - один байт, доступ в AVR-ке к одному байту происходит "за один присест".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 26 июн 2013, 01:37 
Не в сети
Аватара пользователя

Зарегистрирован: 15 янв 2011, 11:27
Сообщения: 317
Откуда: Челябинск
прог. языки: C/C++
ФИО: Александр
RoboHobbyRu Спасибо вам :)

Добавлено спустя 21 минуту 7 секунд:
Сейчас залил прошивку в мк. стоило добавить volatile и все глюки ушли :)

Добавлено спустя 7 минут 54 секунды:
Я над этим косяком столько тупил жесть, поменял несколько передатчиков, поменял мк на плате. Ладно заканчиваю свой монолог.

_________________
РАБОТА, РАБОТА перейди на Федота, с Федота на его брата, а ко мне их зарплата.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: CodeVisionAVR - версия 2!
СообщениеДобавлено: 26 июн 2013, 01:42 
Не в сети

Зарегистрирован: 04 май 2013, 10:35
Сообщения: 203
Откуда: Тюмень
Для начального ознакомления с языком Си можно купить книгу Герберта Шилдта - Полный справочник по С (она сравнительно легко читается)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 144 ]  На страницу Пред.  1 ... 6, 7, 8, 9, 10

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO