Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

COKPOWEHEU писал(а):не знаю чем вам так не нравятся прерывания и буферы
да почему не нравятся? каждому овощу своё время! нужно - я и буферы делаю, и автоматы и все прочее. только чаще всего это не нужно. мне не нужно. и я подозреваю, многим другим тоже.

любая непоследовательная обработка сложна в понимании. может ли кто снаскоку понять, как работает чужой автомат конечных состояний? не может. иной раз и после долгих размышлений не получается. а при моём подходе программа получается - читай идентификаторы, и инструкция не нужна. все последовательно, все просто, наглядно. откуда что берется - видно и без размышлений.
ну и к чему тогда так стремиться к этому автомату, тем более что никаких ценных преимуществ в большинстве случаев он не даёт?!

Добавлено after 8 minutes 39 seconds:
я вот вспоминаю один недоделанный мной проект... с GSM-модемом. поначалу я тоже озаботился кольцевыми буферами для обмена с ним... но потом внезапно (!) выяснилось, что модем этот имеет обыкновение отвечать на запросы спустя какое угодно время - может через 1 миллисекунду, а может и три секунды подождать перед ответом. и обмен с ним получается не очень-то логичным: нельзя в буфер выбрасывать следующую команду, не получив отчет о исполнении предыдущей. и сразу все кольца аннигилируются, т.е. все преимущества типа отправил и делай следующее превратились в тыкву. зато читать из кольцевого буфера тот еще геморрой: из линейного можно сразу обрабатывать при помощи всяких strcpy и тому подобных atoi, а с буфером будь добр сначала вычитать в отдельный буфер принятую строку... мало того, что СМС может прийти хрен знает какой длины и кольцевой буфер переполниться может, так еще и не прочитать никак быстро и удобно!

и как-то само собой получилось то, что я и говорил ранее: прием от GSM-модема по прерываниям (в линейный буфер!) с установкой флага принятых данных, а отправка в модем - при помощи блокирующего printf. и оно отлично работает! размер СМСки, правда, все равно острый нож, но остальное - спокойно и без напрягов.

Добавлено after 10 minutes 38 seconds:
из "многозадачной" темы лучшая моя находка - это массивы функций без явного описания массивов :) я писал как-то об этом - при помощи скрипта линкера появляется возможность в любом месте программы описать функцию/структуру, и она попадет в определенный массив, где может быть обработана среди прочих единожды написанным кодом. вот это мне реально помогает, упрощая программирование в разы! на этом же принципе и программные таймеры делаю.
удобство чисто в написании кода - но для меня оно важнее, чем "истинная" параллельность и высвобождение ресурсов МК
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
slav0n
Опытный кот
Сообщения: 882
Зарегистрирован: Ср дек 01, 2010 00:38:15
Откуда: Харьков
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение slav0n »

массив функций это же просто массив указателей
и одна и та же функция может иметь переменное число аргументов
так же? а то я уже подзабыл
ohmycode!
primuss3.com
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Dimon456 »

slav0n, ответ на твой вопрос написан здесь, читай страницу полностью, он подробно разжевал.

COKPOWEHEU, на счет кольцевых буферов, а где у него начало и где конец, как определять?
Допустим такие модули, как GPS NEO-Mx имеют только идентификатор начала сообщения, конца не имеют.
Не все МК имеют прерывание по определенному символу.
Хотелось бы увидеть реализацию на кольцевых буферах командной оболочки? Не просто a b c, а к примеру, asd fgh, да еще и с передаваемым параметром.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

COKPOWEHEU, на счет кольцевых буферов, а где у него начало и где конец, как определять?
Так ведь кольцевые буферы на то и кольцевые чтобы не иметь фиксированного начала. С одной стороны добавляем, с другой вынимаем.
Допустим такие модули, как GPS NEO-Mx имеют только идентификатор начала сообщения, конца не имеют.
Точно? Разве не по концу строки сообщения разделяются?
Не все МК имеют прерывание по определенному символу.
Из тех, с которыми я работал - ни один. Но, кстати, на AVR добавление флага обнаружения символа не сильно замедлит - все равно там каждый байт вручную считывать приходится.
Хотелось бы увидеть реализацию на кольцевых буферах командной оболочки? Не просто a b c, а к примеру, asd fgh, да еще и с передаваемым параметром.
Да, мне тоже. Есть у меня в планах реализовать кое-что именно с подобным функционалом, но пока других предварительных задач хватает.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Dimon456 »

COKPOWEHEU писал(а):Точно? Разве не по концу строки сообщения разделяются?
Возможно, не помню, надо смотреть, я парсер делал по началу сообщения, а там специальный символ шел.
COKPOWEHEU писал(а):Но, кстати, на AVR добавление флага обнаружения символа не сильно замедлит - все равно там каждый байт вручную считывать приходится.
Если рассматривать в моем примере:asd fgh, то мы можем только конец строки определить.
Примитивное редактирование строки.
+ куча лишних переменных на начало строки, на длину строки, на конец строки.
Больше возни, чем пользы. Как говорится, а лишь бы было.
COKPOWEHEU писал(а):Да, мне тоже.
Значит пока ни кому не удалось это реализовать.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

Значит пока ни кому не удалось это реализовать.
Не знаю, специально я не искал.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

уважаемые знатоки, помогите пожалуйста решить задачку, поскольку запутался я в разного рода кодировках и до конца не осознаю истину.
я патаюсь вывести на терминал через юарт спецсимволы, в данном случае знак градуса
как это сделать просто ?
вот мой код

Код: Выделить всё

   sprintf(buf, "\x80 \r\n ");
   uart_send_string(buf);

заранее благодарю !
Tell Me The Truth
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Reflector »

Уверен, что этот терминал спецсимволы в принципе умеет показывать?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

А почему вы тогда выводите 0x80? Гугл говорит, что знак градуса 0x00B0, и код printf("\u00B0 \r\n "); выводит его правильно.
Retrograd
Открыл глаза
Сообщения: 72
Зарегистрирован: Пн авг 01, 2022 19:06:25
Откуда: Россия

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Retrograd »

Столкнулся со странной ситуацией. Контроллер ATMega8. Тактование внутреннее. Всё собрано на макетке. На пинах вывода светодиоды через токоограничивающие резисторы, на пинах ввода кнопки с подтяжкой к минусу через резисторы 10 ком. В главном цикле вращалась функция моргания светодиодика и всё было нормально. Все работало сообразно ожиданиям. Но тут я удалил из главного цикла функцию моргания светодиодика и начались чудеса.
Кнопки перестали опрашиваться. Точнее я не знаю что именно перестало работать. Судя по светодиодику на PC5 прерывание по таймеру отрабатывает. Но на нажатие кнопок схема не реагирует. После возврата функции моргания светодиода реакция на кнопки восстановилась. Далее путем некоторого количества экспериментов выяснил что в главном цикле кроме if нужна еще хоть какая-то команда чтобы кнопки реагировали. Хватает даже _delay_ms(0); Просто лишней ";" мало. На ";" реакции нет. В общем вот код программы. Работоспособные участки, на функциональность которых ситуация не влияет я повырезал.

Спойлер

Код: Выделить всё

#define F_CPU 8000000UL  // Укажем компилятору частоту ЦПУ (8 MGHz)

#include <avr/io.h>         // Подключим файл io.h обработка ввода-вывода
#include <util/delay.h>      // Подключим файл delay.h обработка задержек по времени
#include <avr/interrupt.h>   // Подключим файл interrupt.h обработка прерываний


// -- установим параметры --
static uint8_t Cur_key_status = 0x00;
static uint8_t New_key_status = 0x00;
static uint8_t Key_change = 0x00;

ISR(TIMER0_OVF_vect)
{
// -- Прерывание для опроса кнопок --
   asm("wdr");   // Сбрасываем собаку.
// Опрашиваем кнопки;
   New_key_status &= 0x00;   // Обнуляем флаги кнопок
   if( PIND & (1 << PD7) ) New_key_status |= (1 << 0);   // Чтение состояния кнопки.
   if( PIND & (1 << PD6) ) New_key_status |= (1 << 1);   // Чтение состояния кнопки.
   if( PIND & (1 << PD5) ) New_key_status |= (1 << 2);   // Чтение состояния кнопки.
   if( PIND & (1 << PD4) ) New_key_status |= (1 << 3);   // Чтение состояния кнопки.
   if( PIND & (1 << PD1) ) New_key_status |= (1 << 4);   // Чтение состояния кнопки.
// Развешиваем флаги;
   New_key_status |= (1 << 7);   // Ставим статус кнопки прочитаны.
   PORTC ^= (1<<PC5);   // Пока просто мигаем светодиодом.
   TCNT0 = 61;   // Инициализируем таймер 0 для следующего опроса.
            // Установили счетчик таймера на 61 из 256. Должно получаться 25 миллисекунд. Точнее 24,96 мс.
}

void Set_LED (void){
//   PORTC ^= (1<<PC0);
   PORTC &= 0x00;
   if(Cur_key_status & (1 << 0)) PORTC |= (1 << PC0);
   if(Cur_key_status & (1 << 1)) PORTC |= (1 << PC1);
   if(Cur_key_status & (1 << 2)) PORTC |= (1 << PC2);
   if(Cur_key_status & (1 << 3)) PORTC |= (1 << PC3);
   }
void main(void) {   // начало программы
   WDTCR=0x1F;      // Инициализация Сторожевой Собаки.
   WDTCR=0x0F;      // Прескалер собаки ставим на максимум. Примерно 2,1 секунды.

   GICR |= 0x00;   // Разрешение на внешние прерывания int. (0x00 - запрет прерываний. 0xC0 - разрешение прерываний для int0 и int1)
   MCUCR |= 0x0a;   // Условия прерываний int. (Нисходящий фронт)

   TIMSK = 0x19;   // Таймеры. Разрешение прерываний. 0x01 - таймер0. 0x19 - оба таймера.
   
   TCCR0 = 0x05;   // Прескалер для таймера 0. (1:1024)
   TCNT0 = 0x9e;   // Счетный регистр таймера 0. (158 для 4 MHz)

   TCCR1A = 0x00;   // Настройки для таймера 1
   TCCR1B = 0x05;   // Прескалер для таймера 1 (1:1024)
   TCNT1 = 0x0000;   // Счетный регистр таймера 1.
   OCR1A = 0xffff;   // Регистр сравнения A таймера 1.
   OCR1B = 0xffff;   // Регистр сравнения B таймера 1.
   
    TIFR = 0x00;   // Сброс всех флагов прерываний таймера.
    asm("sei");      // Глобальное разрешаем прерывания.
// -- Конец блока инициализации контроллера --
   DDRC |= (1 << PC0);   // пин PC0 порта DDRC на вывод левый вверх
   DDRC |= (1 << PC1);   // пин PC1 порта DDRC на вывод левый вниз
   DDRC |= (1 << PC2);   // пин PC2 порта DDRC на вывод правый вверх
   DDRC |= (1 << PC3);   // пин PC3 порта DDRC на вывод правый вниз
   DDRD |= (0 << PD4);   // пин PD4 порта DDRD на вход левый вверх
   DDRD |= (0 << PD5);   // пин PD5 порта DDRD на вход левый вниз
   DDRD |= (0 << PD6);   // пин PD6 порта DDRD на вход правый вверх
   DDRD |= (0 << PD7);   // пин PD7 порта DDRD на вход правый вниз
   DDRD |= (0 << PD1);   // пин PD0 порта DDRD на вход дополнительная
   DDRD |= (0 << PD2);   // пин PD2 порта DDRD на вход.
   DDRD |= (0 << PD3);   // пин PD3 порта DDRD на вход.
   PORTD |= (1 << PD2);   // Включаем подтягивающий (Pull-UP) резистор для пина PD2.
   PORTD |= (1 << PD3);   // Включаем подтягивающий (Pull-UP) резистор для пина PD3.
 
   GICR |= (1<<INT0);  //разрешаем внешнее прерывание на int0 левая сторона.
   GICR |= (1<<INT1);  //разрешаем внешнее прерывание на int1 правая сторона.


// -- основной цикл программы --

   while (1) {   // реализация бесконечного цикла
      _delay_ms(0);
      if( New_key_status & (1 << 7) )   // Если кнопки не перечитаны нечего дальше делать.
         {
            New_key_status &= ~(1 << 7); // Скидываем флаг
            Key_change = Cur_key_status ^ New_key_status;
            Cur_key_status = New_key_status;
            if (Key_change) Set_LED ();
         }
 }


Если в главном цикле закомментировать строку с _delay_ms(0); реакция на кнопки пропадает. Объяснить такое поведения у меня не получилось. Стало просто интересно в чем причина такого поведения контроллера.

На всякий случай, пишу в МК через USBAsp вот команды компиляции и записи:
avr-gcc -mmcu=atmega8 -Os Example.c -o Example.o (в каталоге: /home/user/Projects/Example)
avr-objcopy -j .text -j .data -O ihex Example.o Example.hex (в каталоге: /home/user/Projects/Example)
avrdude -c usbasp -p m8 -P usb -U flash:w:Example.hex

Вывод avrdude:

Спойлерavrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9307 (probably m8)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "Example.hex"
avrdude: input file Example.hex auto detected as Intel Hex
avrdude: writing flash (904 bytes):

Writing | ################################################## | 100% 0.97s

avrdude: 904 bytes of flash written
avrdude: verifying flash memory against Example.hex:
avrdude: load data flash data from input file Example.hex:
avrdude: input file Example.hex auto detected as Intel Hex
avrdude: input file Example.hex contains 904 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.50s

avrdude: verifying ...
avrdude: 904 bytes of flash verified

avrdude: safemode: Fuses OK (E:FF, H:D9, L:E4)

avrdude done. Thank you.



----------
(program exited with code: 0)
Press return to continue


Upd.

При попытке добавить вместо _delay_ms(0); пустой функции или просто i++; или asm("nop"); к адекватному поведению МК не возвращает. :shock:
Последний раз редактировалось Retrograd Пт авг 05, 2022 12:12:09, всего редактировалось 1 раз.
Не так страшно показаться идиотом, как страшно оказаться идиотом только потому что постеснялся что-то спросить чтобы не показаться идиотом.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение WiseLord »

Я бы сделал "New_key_status" volatile. Да и вообще, всегда всё что пишется/читается и в прерывании, и в основном цикле, должно быть volatile. Без этого, скорее всего, компилятор просто выбрасывает всю начинку основного цикла, т.к. проверка (if) всегда с его точки зрения даёт нулевой результат.

Наоборот, интересно, почему код работает при включении задержки. Должен, по идее, точно так же не работать.
Retrograd
Открыл глаза
Сообщения: 72
Зарегистрирован: Пн авг 01, 2022 19:06:25
Откуда: Россия

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Retrograd »

Я бы сделал "New_key_status" volatile. Да и вообще, всегда всё что пишется/читается и в прерывании, и в основном цикле, должно быть volatile. Без этого, скорее всего, компилятор просто выбрасывает всю начинку основного цикла, т.к. проверка (if) всегда с его точки зрения даёт нулевой результат.

Наоборот, интересно, почему код работает при включении задержки. Должен, по идее, точно так же не работать.

Спасибо. Думаю что я понял в чем дело.
Не так страшно показаться идиотом, как страшно оказаться идиотом только потому что постеснялся что-то спросить чтобы не показаться идиотом.
Юрий1239
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб окт 23, 2021 17:05:26

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Юрий1239 »

Кто знает точность внутренней опоры attiny24, в зависимости от температуры ?
Аватара пользователя
Starichok51
Модератор
Сообщения: 19039
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

кроме даташита - никто.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
veso74
Поставщик валерьянки для Кота
Сообщения: 1902
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение veso74 »

Atmel-7701_Automotive-Microcontrollers-ATtiny24-44, стр. 159
Absolute accuracy (Including INL, DNL, quantization error, gain and offset error),
Single-ended conversion VREF = 4V, VCC = 4V, ADC clock = 200kHz -> 2..4 LSB bits (–40°C to +125°C)
Юрий1239
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб окт 23, 2021 17:05:26

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Юрий1239 »

Atmel-7701_Automotive-Microcontrollers-ATtiny24-44, стр. 159


Спасибо, я там ещё график нашёл неподалёку
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

Товарищи коты, а подскажите, пожалуйста!
Я особо не заморачивалась форматным выводом данных на дисплейчики посредством МК. В основном, хватало целое вывести в несколько знакомест с лидирующим пробелом или без оного.
А есть ли что то, позволяющее сформировать строку в буфере из целых и вещественных переменных, с комбинированием с символами по заданному формату, как это делает printf ?
Белая и Пушистая
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

есть такое, sprintf называется
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

ARV, спасиба.
Белая и Пушистая
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

А кто подскажет, в голом Си (на МК) реально отловить деление на ноль, не проверяя делитель перед делением?
try... catch вроде ж только для плюсов....

Добавлено after 37 minutes 19 seconds:
ну и другие ошибки, типа корня из отрицательного числа...
Белая и Пушистая
Ответить

Вернуться в «AVR»