WinAvr в вопросах и ответах

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

Re: WinAvr в вопросах и ответах

Сообщение ARV »

я так же соглашусь с предыдущими ораторами - goto не есть табу. однако, глядя на предложенный костяк кода создается впечатление, что на самом деле можно было бы и обойтись без goto и, главное, без кучи операторов if. на счет кучи операторов - не стану настаивать, но вместо goto отлично подойдет break:

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

do{
// тут была метка для goto
...
   while(1){
      // тут ваши if-ы
      ...
                  if(some_condition) break;
   }
} while (1);
 
этот код сделает то же самое, что и ваш, но без goto - и, как мне кажется, совершенно не скажется на итоговом размере кода.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
stolyars
Родился
Сообщения: 18
Зарегистрирован: Пн сен 21, 2009 10:12:35
Откуда: Днепр

Re: WinAvr в вопросах и ответах

Сообщение stolyars »

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

Re: WinAvr в вопросах и ответах

Сообщение ARV »

stolyars писал(а):У меня такой вопрос по програмированию в среде WinAvr:динамическая индикация если сегменты семисегментника подключаются к разным портам.Как реализуется это практически?имеется в ввиду код?На одном сайте мне подсказали что можно собрать виртуальный порт,но как практически сделать мне не очень понятно.Буду благодарен за любую подсказку или наводку,ну а если еще пример реализации програмной покажете буду рад безмерно.Заранее спасибо за любой ваш ответ.
не улавливаю ни малейшей связи вопроса "со средой WinAVR" - вопрос исключительно "абстрактно-алгоритмический".

решение же проблемы элементарно: надо "распихать" биты управления индикаторами по разным "местам" в разных портах. задача несложная, но муторная. например, сегмент А у нас соответствует 4-ому биту в "символе", и вывести его надо в 6-й бит порта В. делается это примерно так:

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

#define seg_A _BV(4)
PORTB = (PORTB & ~_BV(PB6)) | ((c & seg_A) << 6);
как видите, мы обнуляем бит сегмента в порту, а затем в это место перемещаем бит из символа путем маскирования и сдвига.

главное в этом - минимизировать число сдвигов и логических операций, иначе удовольствие обойдется слишком дорого. для этого я всегда "тасую" сегменты в символе так, чтобы было наиболее удобно затем их выводить в порты. многие, например, просто задают биты по порядку: А - нулевой, В - первый и т.д. - это очень неудобно! немного помозговав, надо прийти к такому распределению битов, чтобы обойтись минимумом операций. например, надо вывести в порт В сегменты так xxAHGxxx, а в порт С остальные ВСxxxEFD. очевидно, что если сегменты в символе будут расположены DCAHGEFD, то в этом случае все получится весьма просто:

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

PORTB = (PORTB & 0b11000111) | (c & 0b00111000);
PORTC = (PORTC & 0b00111000) | (c & 0b11000111);


возможен вариант с битовыми полями, однако, он наверняка окажется более объемным по результирующему коду, хотя внешне может выглядеть более элегантным. я им не пользуюсь, потому и не стану советовать.

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

Мой уютный бложик... заходите!
Аватара пользователя
nsl2004
Мучитель микросхем
Сообщения: 402
Зарегистрирован: Пт май 29, 2009 10:14:29

Re: WinAvr в вопросах и ответах

Сообщение nsl2004 »

Прошу помочь в пограничном ( вроде как по WinAvr , а вроде как CVAVR) вопросе.
Есть функция написанная в WinAvr. Мне надо в ней разобратся и трансформировать для CVAVR. Мои измышления выглядят так
#define WIRE PB0
кусок кода пропущен
if (bit_is_set(PINB,wire)) presence++;
Изменяю что бы разобратся
if (bit_is_set(PINB,PB0)) presence++;
Теперь надо привести к виду для CVAVR
PB0 ( WinAvr) это PORTB.0 (CVAVR)
На этом ресурсе http://microsin.ru/content/view/629/44/
есть подсказка, что if (bit_is_set(PINB,0)) { ... } можно заменить на if (PINB & (1<<PINB0)) { ... } по аналогии меняем и получаем для CVAVR

if (PINB.0 & (1<<DQ)) presence++; // где DQ - #define DQ PORTB.0
И... функция все время возвращает 0. Ниже весь код функции

Win AVR

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

unsigned char ow_reset(void)
{   
   unsigned char presence=0;               
   DDRB |= _BV(WIRE);           
   _delay_us(490);       
   DDRB &= ~_BV(WIRE);   
   _delay_us(60);       
   if (bit_is_set(PINB,WIRE)) presence++;    
   _delay_us(480);                
   return(presence);                   
}       


Для CVAVR

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

unsigned char ow_reset(void)
    {
        unsigned char presence=0;
        DQ = 0;
        delay_us(480);
        DQ = 1;
        delay_us(70);
        if (PINB & (1<<PORTB.0)) presence++;
        delay_us(470);
        return(presence);
    }  /* 0 = на шине есть устройства, 1 = нет устройств */

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

Re: WinAvr в вопросах и ответах

Сообщение ARV »

nsl2004 писал(а):есть подсказка, что if (bit_is_set(PINB,0)) { ... } можно заменить на if (PINB & (1<<PINB0)) { ... } по аналогии меняем и получаем для CVAVR [/i]
if (PINB.0 & (1<<DQ)) presence++; // где DQ - #define DQ PORTB.0


у меня есть 2 совета для вас:
1. следуйте подсказке один к одному, не добавляя собственных фантазий, т.е. остановитесь на варианте if (PINB & (1<<PB0)) - CVAVR поймет ее не менее хорошо, чем WinAVR (PB0 - это стандартное обозначение номера пина порта В, т.е. #define PB0 0 - если ваш CVAVR не содержит такого определения, то добавьте его самостоятельно)
2. не пользуйтесь теми "фичами", которые вам предлагает CVAVR в виде отступления от стандарта - это касается способа обращения к битам портов в "точечной нотации". используйте только стандартный метод для любых Си-программ: вместо PORTB.0 = 1 всегда делайте PORTB |= 1 << PB0 и так далее для других вариантов. в этом случае вы никогда не будете иметь проблем с разными компиляторами.

ну и в виде бесплатного приложения: найдите макросы WinAVR bit_is_set(), bit_is_clear(), _BV() и т.п., сделайте их адаптацию для CVAVR и пользуйтесь ими самостоятельно - и вы не станете видеть разницы между компиляторами в большинстве своих проектов.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
nsl2004
Мучитель микросхем
Сообщения: 402
Зарегистрирован: Пт май 29, 2009 10:14:29

Re: WinAvr в вопросах и ответах

Сообщение nsl2004 »

2ARV По поводу фантазий это Вы точно. Иногда так заплутаю ... :)) Спасибо за наводку. Сейчас попробую реализовать.
wkarl
Родился
Сообщения: 8
Зарегистрирован: Чт июн 18, 2009 18:14:19
Откуда: Moscov

Re: WinAvr в вопросах и ответах

Сообщение wkarl »

//первый байт 0x81 8-[длина строки(7)+смещение(1)] 1-[смещение(1)]
const unsigned char str_default[]= {0x90, 0x39, 0xBD, 0x37, 0xBB, 0x39, 0x0, 0x97, 0xB7, 0x79};//d, E, F, A, U, L, t, 0, S, //0,9 regim127
const unsigned char str_ds18b20[]= {0x81, 0x9E, 0xAD, 0x82, 0xBF, 0x9D, 0x3E, 0xBB};//d, S, 1, 8, b, 2, 0, 0, F // 0,9 regim126
const unsigned char str_budil[]= {0x61 ,0x9D, 0x98, 0x9E, 0x11, 0x58};//, 0x0, 0x0, 0xAD};//0, b, u, d, I, I., 0, 0, S //1,8 regim52
Это фрагмент из программы Мосина для часов на Меге8 (http://wkarl.narod.ru/3t_dop14.htm)[/url]). Объясните, плиз, как эта кодировка связана с индикаторами? Кто возьмется прокомментировать прилагаемую программу для 5-разрядных часов на той же Меге8. Заранее — большое спасибо от студентов-управленцев инж. ф-та РУДН.
Вложения
cl5_v17t1_1.zip
Управляющая программа для замечательных часов Мосина
(32.62 КБ) 267 скачиваний
wkarl
wkarl
Родился
Сообщения: 8
Зарегистрирован: Чт июн 18, 2009 18:14:19
Откуда: Moscov

Re: WinAvr в вопросах и ответах

Сообщение wkarl »

//первый байт 0x81 8-[длина строки(7)+смещение(1)] 1-[смещение(1)]
const unsigned char str_default[]= {0x90, 0x39, 0xBD, 0x37, 0xBB, 0x39, 0x0, 0x97, 0xB7, 0x79};//d, E, F, A, U, L, t, 0, S, //0,9 regim127
const unsigned char str_ds18b20[]= {0x81, 0x9E, 0xAD, 0x82, 0xBF, 0x9D, 0x3E, 0xBB};//d, S, 1, 8, b, 2, 0, 0, F // 0,9 regim126
const unsigned char str_budil[]= {0x61 ,0x9D, 0x98, 0x9E, 0x11, 0x58};//, 0x0, 0x0, 0xAD};//0, b, u, d, I, I., 0, 0, S //1,8 regim52
Это фрагмент из программы Мосина для часов на Меге8 (http://wkarl.narod.ru/3t_dop14.htm). Объясните, плиз, как эта кодировка связана с индикаторами? Кто возьмется прокомментировать прилагаемую программу для 5-разрядных часов на той же Меге8. Заранее — большое спасибо от студентов-управленцев инж. ф-та РУДН.
Вложения
cl5_v17t1_1.zip
Упр. программа для часов Мосина
(32.62 КБ) 290 скачиваний
wkarl
wkarl
Родился
Сообщения: 8
Зарегистрирован: Чт июн 18, 2009 18:14:19
Откуда: Moscov

Re: WinAvr в вопросах и ответах

Сообщение wkarl »

Ув. tych ! О каком таком Вашем учебнике все говорят и ни одной ссылки. Он для начинающих подойдет?
wkarl
Аватара пользователя
AI_Disable
Сверлит текстолит когтями
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение AI_Disable »

Подскажите, где косяк. Простой код:

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

unsigned char a;
int main ()
{
while(1)
{
printf("a=%d", a);
}
}

ISR(вектор)
{
a++;
}

Однако работать не хочет. На дисплее "a" всегда равна нулю, хотя прерывания проходят стабильно. Но, если принтф перенести в обработчик прерывания, или a++ в цикл, то всё ок. То есть компилятор какбы создаёт две независимых переменных для цикла и для обработчика. Раньше такого не наблюдалось.
Сейчас обхожу это путём добавления квалификатора "volatile" при объявлением переменной. В принципе, всё устраивает, но раньше и без volatile работало.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

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

Мой уютный бложик... заходите!
petrunick
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Сб июн 13, 2009 22:30:14
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение petrunick »

В ВинАВРе компилятор неожиданно стал ругаться на GIMSK как на не объявленную переменную :shock: Абсолютно без разницы, каков другой код, в Мэйкфайле ничего не изменял кроме TARGET(имя проекта), инклуды вот такие

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

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>   
#include <util/delay.h>   

Это глюк программы или есть объяснение?
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Re: WinAvr в вопросах и ответах

Сообщение smac »

petrunick писал(а):В ВинАВРе компилятор неожиданно стал ругаться на GIMSK...

<avr/signal.h> - по-моему лишнее, заместо него давно <avr/interrupt.h>. Второй вопрос - платформу (микроконтроллер) не меняли?
petrunick
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Сб июн 13, 2009 22:30:14
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение petrunick »

При удалени <avr/signal.h> он ругается на sei() (глоб. разрешение прерываний) даже при наличии <avr/interrupt.h>
МК стоит АТмега128.
kondor
Нашел транзистор. Понюхал.
Сообщения: 150
Зарегистрирован: Чт апр 29, 2010 10:32:32

Re: WinAvr в вопросах и ответах

Сообщение kondor »

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

int main()
{
   int i;
   DDRD = 255;
   #define AA 7
   while (1)    {
   for (i = 0 ; i < 1500 ; i++ ) asm("NOP");
   PORTD = 0;
   for (i = 0 ; i < AA ; i++ ) asm("nop");
   PORTD = 255;
   }
   return 0;
}


Задержку именно по нижнему уровню, первый цикл для удобства.

AА = 5 => задержка 400 нс.
АА = 6 => задержка 450 нс.
АА = 7 => задержка 3.2 мкс.
АА = 8 => задержка 3.6 мкс.

почему такой скачек происходит ?

П.С. проверяю через протеус 7.6
П.С. про функции задержки знаю, просто хочу понять что происходит.
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Re: WinAvr в вопросах и ответах

Сообщение smac »

petrunick писал(а):При удалени ...

Тогда начнем издалека - версия компилятора какая?
Аватара пользователя
MOHOXPOM
Встал на лапы
Сообщения: 108
Зарегистрирован: Вт мар 18, 2008 08:25:31
Откуда: Красноярск
Контактная информация:

Проблемка

Сообщение MOHOXPOM »

Народ, выручай... Неделю бьюсь и не могу понять что происходит с кодом. Он типа "прыгает". Может компилятор мозги колупает (gcc 4.3.3 WinAvr под студией)? Строки 358, 370, 357

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

350:       sei();                                                                     //разрешаю все прерывания
+000004C1:   9478        SEI                      Global Interrupt Enable
351:       Timer_TOIE_ON;                                                               //разрешить прерывание по переполнению
+000004C2:   E084        LDI       R24,0x04       Load immediate
+000004C3:   BF87        OUT       0x37,R24       Out to I/O location
354:       _rfid_i = 0x08;
+000004C4:   E088        LDI       R24,0x08       Load immediate
+000004C5:   93800126    STS       0x0126,R24     Store direct to data space
358:         _rfid_j = 0x08;
+000004C7:   E058        LDI       R21,0x08       Load immediate
370:             InvBit(TEST);
+000004C8:   E440        LDI       R20,0x40       Load immediate
357:          _rfid_i--;
+000004C9:   91200126    LDS       R18,0x0126     Load direct from data space
+000004CB:   5021        SUBI      R18,0x01       Subtract immediate
+000004CC:   93200126    STS       0x0126,R18     Store direct to data space
358:         _rfid_j = 0x08;
+000004CE:   93500127    STS       0x0127,R21     Store direct to data space


На Си вот так

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

 sei();                                          //разрешаю все прерывания
 Timer_TOIE_ON;                                    //разрешить прерывание по переполнению

 _rfid_i = 0x08;

 do{
    _rfid_i--;
   _rfid_j = 0x08;

    _byte_key = *((unsigned char *)&_rfid_to_sent_array + _rfid_i - 1);

    do{
      _rfid_j--;

       if((_byte_key & 0x80) == 0x80)    {ClrBit(TEST); NOP;}
       else                    {SetBit(TEST); NOP;}
   
      InvBit(TEST);
      NOP;   

       _byte_key = _byte_key << 1;
    }while(_rfid_j > 0x00);
 }while(_rfid_i > 0x00);

 Timer_TOIE_OFF;                                    //запретить прерывание по переполнению
}


Кто подскажет ответ на проблему буду очень признателен. Заранее спасибо
Последний раз редактировалось MOHOXPOM Пт июн 18, 2010 08:31:29, всего редактировалось 1 раз.
Как зачем мне голова?! Я ей ем!!!
Аватара пользователя
MOHOXPOM
Встал на лапы
Сообщения: 108
Зарегистрирован: Вт мар 18, 2008 08:25:31
Откуда: Красноярск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение MOHOXPOM »

petrunick писал(а):При удалени <avr/signal.h> он ругается на sei() (глоб. разрешение прерываний) даже при наличии <avr/interrupt.h>
МК стоит АТмега128.

Попробуй ручками файл прописать #include <avr/iom128.h>

Хотя... Проверил свою отладочную на 128 меге.. Ну нету там GIMSKа....

Есть в таймерах на 8 бит - TIMSK и на 16 бит - ETIMSK
Как зачем мне голова?! Я ей ем!!!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Проблемка

Сообщение ARV »

MOHOXPOM писал(а):Народ, выручай... Неделю бьюсь и не могу понять что происходит с кодом. Он типа "прыгает". Может компилятор мозги колупает (gcc 4.3.3 WinAvr под студией)? Строки 358, 370, 357
типа прыгает - это что значит?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Negor
Вымогатель припоя
Сообщения: 586
Зарегистрирован: Ср мар 07, 2007 22:58:02
Откуда: Черкассы, Украина
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение Negor »

У меня такой вопрос. Как в WinAVR объявить переменную в области eeprom я знаю. А как объяснить компилятору что переменная должна лежать по конкретному адресу?
There is only 10 kind of people: those who understands binary code and those who dont!!!
Ответить

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