Обсуждаем контроллеры компании Atmel.
Ответить

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

Пт авг 20, 2021 10:45:21

Какие оптимизации были включены?

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

Пт авг 20, 2021 10:47:53

Я же дал ссылки на соответствующие строчки в Makefile.

В любом случае, оптимизации одинаковые для разных версий gcc.

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

Пт авг 20, 2021 10:51:05

примерно та же песня и с avr-gcc, в другой теме, кажется, я приводил сравнения...

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

Сб сен 18, 2021 16:52:36

Всем привет котаны и котики! Пытаюсь с CodevisionAVR 3.12 пересесть на Atmel Studio7. вот мой небеольшой проектик переписываю в студии, и пришел вопрос как по USART дробные числа вывести в терминал. К примеру CodevisionAVR я бы делал так:
Код:
ftoa(adc,2,buffer); //Вывод напряжения с двумя знаками после точки
puts(buffer);
puts("\n\r");  //переход на новую строку


Для Студии нет подобных библиотек по выводу дробных чисел? было удобно(( Пошарив по stdlib.h, нашел пару функции dtostrf() и dtostre() не особо устроили... к примеру есть пять символов (12.38), а потом стало 9.88, то перед 9 появляется пробел(((
Код:
dtostrf(adc, 5, 2, buffer); // 2 - кол-во цифр после запятой
puts(buffer);
USART_sendLine(buffer);

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

Сб сен 18, 2021 20:01:46

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

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

Сб сен 18, 2021 23:09:42

подключить библиотеку поддержки float для printf и пользоваться возможностями этой функции. printf, кстати, сразу и будет в USART выводить.

ага и потерять минимум 1,5-2К памяти программ как вы говорили тут же на форуме

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

Вс сен 19, 2021 07:40:24

потерять... использовать с пользой. начиная с 16К флеша память уже не является препятствием. 1,5-2К вы же на float пожертвовали...

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

Вс сен 19, 2021 17:52:08

WiseLord писал(а):Вывод такой - вплоть до 8 версии качество оптимизации улучшалось, а потом начало становиться хуже.
да, код становится жирнее.
видимо писателям компилятора действительно:
ARV писал(а):начиная с 16К флеша память уже не является препятствием

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

Пн сен 20, 2021 13:04:44

slav0n, ARV, Котаны, как вы заметили я не гуру - а новичок, и больше головой об стену Си бьюсь, потихоньку выбиваю по кирпичику)))
Данный вопрос решил тем что взял функцию ftoa(float n,unsigned char decimals,char *str) из библиотеки stdlib.lib CVAVR и тупо в*ерачил её в AtmelStudio 7 .c и .h. Но у меня компилятор начал ругаться на такие строки strcpyf(str,"-NAN"); как я понял это обрабатываем ±inf, nan, поэтому тупо //, и заработало, вывод дробных есть.
Код:
void ftoa(float n,unsigned char decimals,char *str)
{
   float scale=0.5;
   unsigned char i,d;

   switch (((unsigned int *) &n)[1])
   {
      case 0xFFFF:
      //strcpyf(str,"-NAN");
      return;

      case 0x7FFF:
      //strcpyf(str,"NAN");
      return;
   };

   if (n<0.0) {n=-n; *str++='-';};
   if (decimals>6) decimals=6;
   i=decimals;
   while (i--) scale=scale*0.1;
   n=n+scale;
   i=0;
   scale=1.0;
   while (n>=scale)
   {
      scale=scale*10.0;
      // 08032010_1
      if (++i>38)
      {
         //strcpyf(str,"INF");
         return;
      }
   };
   if (i==0) *str++='0';
   else
   while (i--)
   {
      scale=floor(0.5+scale*0.1);
      d=(unsigned char) (n/scale);
      *str++=d+'0';
      n=n-scale*d;
   };
   if (decimals==0) {*str=0; return;};
   *str++='.';
   while (decimals--)
   {
      n=n*10.0;
      d=(unsigned char) n;
      *str++=d+'0';
      n=n-d;
   };
   *str=0;
}

Поизучав, что это такое strcpyf(char *dest,char flash *src) нашел инфу что должно содержаться в библиотеке #include <string.h> CVAVR, возможно ли её заменить стандартными функциями из библиотеке #include <string.h> в Студии. Ну и проект по сравнению с использованием функции dtostrf() стал весить на 12% меньше.

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

Пн сен 20, 2021 13:24:49

Данный вопрос решил тем что взял функцию ftoa(float n,unsigned char decimals,char *str) из библиотеки stdlib.lib CVAVR и тупо в*ерачил её в AtmelStudio

Лишние пробелы в начале строки не проще было пропустить?

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

Пн сен 20, 2021 13:40:16

Лишние пробелы в начале строки не проще было пропустить?

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

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

Пн сен 20, 2021 14:05:08

а как?

Что-то типа такого:
Код:
char* s = dtostrf(adc, 5, 2, buffer);
while(*s == ' ') s++;
puts(s);

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

Вс окт 10, 2021 18:16:23

Научите считать микросекунды(us)?
Делаю так, выходит ерунда:
Код:
// bool timer_status; //Статус для отображения на экране
...........
Timer1 overflow interrupt service routine
ISR (TIMER0_OVF_vect)
{   
    unsigned int timer_us;
    unsigned int timer_ms;
    TCNT0=0xF0;
    timer_us++;
    if(timer_us>999){ //1мс
      timer_ms++;
       timer_us=0;}
    if(timer_ms>499){//500мс
                timer_status=1; //сменили статус
                timer_ms=0;}
}
...................

void Timer0_Init(void)
{
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Normal top=0xFF
// Timer Period: 1 us
TCCR0B=(0<<CS01) | (1<<CS00);
TCNT0=0xF0;
TIMSK0=(1<<TOIE0);
}
................
int main(void)
{Timer0_Init();
  sei();
while (1)
    {
     if(timer_status!=0){     //каждые 500мс обновим

        timer_status=0;    //сбросили флаг таймера
    }
}

нужно как можно точнее считать 1us, 500ms это просто тренировка

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

Вс окт 10, 2021 19:47:39

Касательно TCNT0=0xF0...

Не уверен, что за оставшиеся 15 тактов до переполнения в прерывании успеет выполнится всё, что там написано (включая собственно вход-выход из прерывания), чтобы выйти в основную программу и успеть что-то сделать до нового прерывания.

На 16МГц отмерять интервалы с 1мкс (1МГц) таким методом вряд ли получится.

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

Вс окт 10, 2021 20:12:11

Касательно TCNT0=0xF0...

Не уверен, что за оставшиеся 15 тактов до переполнения в прерывании успеет выполнится всё, что там написано (включая собственно вход-выход из прерывания), чтобы выйти в основную программу и успеть что-то сделать до нового прерывания.

На 16МГц отмерять интервалы с 1мкс (1МГц) таким методом вряд ли получится.


к примеру 4us получается отмерить у ардуинщиков функцией micros() в ArduinoIDE, я так понимаю лучшего тоже не выжму?

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

Вс окт 10, 2021 23:27:26

Наверное, такие задержки стоит доверить компилятору
Код:
#include <util/delay.h>
_delay_us(1);

Если внешние ловите, то capture event на Capture pin (ICP1) использовать.

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

Пн окт 11, 2021 08:48:46

Если внешние ловите, то capture event на Capture pin (ICP1) использовать.

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

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

Ср окт 13, 2021 20:33:10

Код:
uint8_t ovf_count = 0;
uint16_t ticks;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
  TCCR0A = 0;
  TCCR0B = 0; // No clock source (Timer/Counter stopped)
  TCNT0  = 0;  // Timer/Counter Register
  TIFR0 |= _BV(TOV0);
  // Wait for rising edge of C-clock
  loop_until_bit_is_set(FREQ_PIN, FREQ_BIT);
  // Wait for falling edge of C-clock
  loop_until_bit_is_clear(FREQ_PIN, FREQ_BIT);
  TCCR0B = _BV(CS00); // Start Timer/Counter, No prescaling
  do {
    do {
      // Check for overflow
      if (bit_is_set(TIFR0, _BV(TOV0))) {
        TIFR0 |= _BV(TOV0);
        ++ovf_count;
      }
    } while (bit_is_clear(FREQ_PIN, FREQ_BIT));
    do {
      // Check for overflow
      if (bit_is_set(TIFR0, _BV(TOV0))) {
        TIFR0 |= _BV(TOV0);
        ++ovf_count;
      }
    } while (bit_is_set(FREQ_PIN, FREQ_BIT));
  } while (--pulses); // pulses - сколько внешних периодов считать
  TCCR0B = 0; // Stop Timer/Counter
  // Check for overflow
  if (bit_is_set(TIFR0, _BV(TOV0))) {
    TIFR0 |= _BV(TOV0);
    ++ovf_count;
  }
  // тиков таймера насчитали, -2 тика на } while(--pulses);
  // 1 тик таймера - 1 такт частоты контроллера
  ticks = (((uint16_t)ovf_count << 8) | TCNT0) - 2;
}

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

Вт ноя 16, 2021 12:16:04

Котаны! Подскажите, пожалуйста. Есть код для мигания светодиодов с помощью тактовой кнопки:

Код:
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 0b00000000; // Порт D вход
PORTD = 0b11111111; // Подключаем подтягивающие резисторы
DDRB = 0b11111111; // Порт B выход
PORTB = 0b00000000; // Лог. 0 на выходе
while(1)
{
while ((PIND&(1 << PD0)) == 1){} // Ждем пока на выводе PDO лог. 1
_delay_ms(50); // Задержка
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
PORTB &= ~(1 << PB1); // Лог. 0 на выводе PB1
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
PORTB |= (1 << PB1); // Лог. 1 на выводе PB1
}
while ((PIND&(1 << PD0)) == 0){} // Ждем пока на выводе PDO лог. 0
_delay_ms(50); // Задержка
}
}

Он рабочий, светодиоды загораются, все хорошо. Но, мне необходимо посадить кнопку на, к примеру, PB4
Тогда, я меняю код следующим образом:
Код:
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{

DDRB = 0b11101111; // Порт B4 на вход
PORTB = 0b00010000; // Лог. 1 на входе PB4
while(1)
{
while ((PINB&(1 << PB4)) == 1){} // Ждем пока на выводе PB4 лог. 1
_delay_ms(50); // Задержка
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0
{
PORTB |= (1 << PB0); // Лог. 1 на выводе PB0
PORTB &= ~(1 << PB1); // Лог. 0 на выводе PB1
}
else
{
PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0
PORTB |= (1 << PB1); // Лог. 1 на выводе PB1
}
while ((PINB&(1 << PB4)) == 0){} // Ждем пока на выводе PDO лог. 0
_delay_ms(50); // Задержка
}
}

... и получаю мигающие светодиоды. Реакции на кнопку нет никакой.
Как корректно пересадить кнопку на другую ножку?

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

Вт ноя 16, 2021 16:08:18

Код:
while ((PINB&(1 << PB4)) == 1){}

У вас здесь используется битовая операция, ее результат - не логическая константа.
Ответить