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

Обсуждаем контроллеры компании Atmel.
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

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

Сообщение TICLIR »

ARV писал(а):В WinAVR делается так:

eeprom_read_xxxx(uint8_t *adr) - считывает из EEPROM переменную, расположенную по адресу adr. вместо xxxx пишите byte, word или dword соответственно для чтения переменной размером в байт, 2 байта или 4 байта.

аналогично для записи имеются функции eeprom_write_xxxx(uint8_t *adr, ....) - вместо многоточия тип соответствующей переменной.

таким образом, получается примерно следующее:

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

#include (avr/eeprom.h) // скобки, естественно, угловые - форум не дает вставить нормальные

EEMEM uint8_t ee_var; // переменная размером в байт в EEPROM

int main(void){
   uint8_t my_var;

   my_var = eeprom_read_byte(&ee_var); // считали значение из EEPROM
   ...

   eeprom_write_byte(&ee_var, my_var); // сохранили значение в EEPROM
}

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

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

Сообщение ARV »

обычно косяки бывают в программе пользователя :) или в схеме.
установите фьюзами BODLEVEL побольше и проверьте, возникают изменения переменной или нет. если чудеса происходят ДАЖЕ в симуляторе (в том же протеусе или студии) - ищите ляп в программе своей.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

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

Сообщение TICLIR »

ARV писал(а):обычно косяки бывают в программе пользователя :) или в схеме.
установите фьюзами BODLEVEL побольше и проверьте, возникают изменения переменной или нет. если чудеса происходят ДАЖЕ в симуляторе (в том же протеусе или студии) - ищите ляп в программе своей.

Я реально не пробовал, только протеусе. Я в точности списал как в примере. В "CPU Registers" переменная находится,почему то, всегда в R0, просматривая коды в асамблере в протеусе это R0 участвует прерываниях и в других местах. Вот,возможно в ручную задать адрес переменной.
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

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

Сообщение ChipKiller »

TICLIR писал(а):В "CPU Registers" переменная находится,почему то, всегда в R0, просматривая коды в асамблере в протеусе это R0 участвует прерываниях и в других местах. Вот,возможно в ручную задать адрес переменной.
... может стОит написать static?
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

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

Сообщение TICLIR »

[/quote] ... может стОит написать static?[/quote]
"EEMEM uint8_t adres1;" интересно куда подставить static. Или куда то ещё?
TICLIR
Встал на лапы
Сообщения: 134
Зарегистрирован: Вс авг 01, 2010 16:05:25

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

Сообщение TICLIR »

TICLIR писал(а):Доброе время. Дело вот в чём, все примеры опробовал всё работат, смущает одно,переменная
EEMEM uint8_t ee_var, при работе программы, даже когда EEPROM не участвует, изменяет своё значени от 0 до 255. Проследить что её меняет не удалось. Это косяк, или нет.

Здравствуйте. С праздником! Так и не выяснил в чём тут дело, я на счёт адреса
EEPROM, взял тупо добавил еще адрес, с ним и работаю, тот так и
скачет сам для себя. Убираю первый, начинает скакать второй, так что
теперь их два.
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

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

Сообщение asteroid7 »

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

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

Сообщение ARV »


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

Мой уютный бложик... заходите!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Мораль другая - НЕ надо пользоваться оптимизацией -O0, -O1
На -Os и -O2 в том коде компилятором генерируется SBI, никаких ST(S) нет.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Rhime
Родился
Сообщения: 9
Зарегистрирован: Пн фев 15, 2010 21:54:49

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

Сообщение Rhime »

нужно так

#include (avr/eeprom.h) // скобки, естественно, угловые - форум не дает вставить нормальные

uint8_t EEMEM ee_var=(присваеваем значение переменной от произвольной записи); // переменная размером в байт в EEPROM

int main(void)
{
uint8_t my_var=0;(присваеваем значение переменной от произвольной записи)

my_var = eeprom_read_byte(&ee_var); // считали значение из EEPROM
...

eeprom_write_byte(&ee_var, my_var); // сохранили значение в EEPROM
}

или так

#include (avr/eeprom.h) // скобки, естественно, угловые - форум не дает вставить нормальные

uint8_t EEMEM ee_var=(присваеваем значение переменной от произвольной записи); // переменная размером в байт в EEPROM

int main(void)
{
char my_var=0;(присваеваем значение переменной от произвольной записи)

my_var = eeprom_read_byte(адрес памяти EEPROM типа 0х00 и т.д.); // считали значение из EEPROM
...

eeprom_write_byte(0х00, my_var); // сохранили значение в EEPROM
}

2 вариант работает 100%
Аватара пользователя
shootnikS
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср янв 05, 2011 17:51:35
Откуда: Пенза

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

Сообщение shootnikS »

Ребят схожу с ума:
Разрабатываю контроллер ШД с указанной связкой в теме.
Требуется получить определенное кол-во импульсов (здесь 10) с определенным периодом (здесь 1 с) на PB3. Таймер настроен на 250 (TCNT=0x06) тактов с делителем на 8 (TCCR0=(0<<CS00)|(1<<CS01)|(0<<CS02), переменная count_T - флаг для обсчета временного интервала. Проблема стоит в том, что проверка нуля на линии PB3 совсем не проходит (if (bit_is_0(PINB,3)) {sig_clock(freq_in,step_in,count_T); }), как не пробовал. Пробовал делать без проверки, просто запускал функцию sig_clock - ведет себя мягко говоря странно. подозреваю, что где-то конкретный косяк в таймере или в возвращении count_T.
Я уже измучился, если идей не будет совершу самое жестокое сделаю все на _ms_delay(freq_f). Помогите)

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

#define F_CPU 4000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>

#define bit_is_0(reg, bit) (!(reg & (1<<(bit))))

volatile unsigned int count_T=0;

ISR(TIMER0_OVF_vect){
count_T++;
TCNT0=0x06;     
};

void sig_clock(volatile unsigned int freq_f, volatile unsigned int step_f, volatile unsigned int count_f)
{
   ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  for (unsigned int a=0;a<step_f;a++){
            if (count_f==freq_f) {
                PORTB^= _BV(PB1);
                step_f--;
                count_f=0;
            }
        }
   }   
}

int main(void){
volatile unsigned int freq_in=0;
volatile unsigned int step_in=0;

DDRB=0x07;
PORTB=0x09;

TIMSK=(1<<TOIE0);
TCCR0=(0<<CS00)|(1<<CS01)|(0<<CS02);
TCNT0=0x06;

sei();
 
freq_in=1000; //период 1000 мс
step_in=10;    //кол-во импульсов

while(1){
    
   
if (bit_is_0(PINB,3)) {sig_clock(freq_in,step_in,count_T); }
 
}
};
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

извините, но не понял ряд аспектов...
1. вы говорите - надо выдать 10 импульсов на PB3, и в то же время постоянно опрашиваете этот пин, как если ы он был входом... что-то не догоняю смысла...
2. делать весь цикл, причем довольно долгий АТОМАРНЫМ - это страшно плохо. внутри атомарного лока все прерывания запрещены, т.е. ваш таймер не считает.
3. ощий алгоритм показался каким-то туманным... не могли бы вы пояснить его словами?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
shootnikS
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср янв 05, 2011 17:51:35
Откуда: Пенза

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

Сообщение shootnikS »

По таймеру: count_T - флаг для обработки временного интервала, т.е. инкрементирование count_T происходит по переполнению таймера (происходит через 500 мкс), из этого следует, что если нам нужен период импульса, например 200 мс, нам нужно чтобы count_T=200 :).
По функции: в функцию передаются три значения: freq_in, step_in, count_T. Чтобы выдать требуемое количество импульсов мы используем цикл for (unsigned int a=0;a<step_f;a++) в нем проверяем условие на период if (count_f==freq_f), изменяем состояние пина PORTB^= _BV(PB1); (импульс!) и дискрементируем step_f, чтобы остановиться.
В основной функции настраиваем порты и таймер, задаем значения переменным freq_in и step_in. В бесконечном цикле while(1) ждем когда на PB3 поступит 0 (реализация кнопки), чтобы вызвать функцию sig_clock и выдать нам 10 импульсом с периодом 1с, чего не происходит.
PS Извиняюсь, в прошлом посте писал, что выдача импульса на PB3, ошибся: импульс на PB1.
PPS Знаю, что использовать атомарный блок - это не есть хорошо, просто подумал, что временная погрешность будет меньше, ведь если не остановить таймер на время исполнения функции, можно проскочить, событие когда count_T==freq_in.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
shootnikS
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср янв 05, 2011 17:51:35
Откуда: Пенза

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

Сообщение shootnikS »

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

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

Сообщение ARV »

shootnikS писал(а):ммм...можно пример?

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

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

volatile uint8_t flag_go = 0;
ISR(TIMER0_OVF_vect){
   static uint8_t counter = 20; // счетчик "перепадов" импульсов - в 2 раза больше кол-ва импульсов
   if(flag_go){
      // если флаг установлен, поочередно меняем уровень на PB3 в "такт" с младшим битом счетчика
      if(counter & 0x01)
         PORTB &= ~_BV(PB3);
      else
         PORTB |= _BV(PB3); 
      // уменьшаем счетчик
      if(!--counter){
         // когда счетчик обнулился - сбрасываем флаг и готовим счетчик к следущей пачке импульсов
         counter = 20;
         flag_go = 0;
      }
   } else {
      // если флаг не установлен - готовим счетчик к очередной пачке импульсов
      counter = 20;
      // если надо - держим выход в нуле
      PORTB &= ~_BV(PB3);
   }
}

то есть в вашем основном цикле вы в нужный момент устанавливаете флаг flag_go = 1; и затем ждете, пока он обнулится, а тем временем формируются 10 импульсов... если флаг сбросите раньше - пачка импульсов прервется...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
shootnikS
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср янв 05, 2011 17:51:35
Откуда: Пенза

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

Сообщение shootnikS »

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

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

Сообщение ARV »

это отнюдь не гениально, это лишь намек на "нормальное" решение :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
shootnikS
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср янв 05, 2011 17:51:35
Откуда: Пенза

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

Сообщение shootnikS »

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

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

Сообщение ARV »

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

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

Мой уютный бложик... заходите!
Ответить

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