CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

bc2 писал(а):Как реализовать умножение?
Ну можно входную частоту подключить к INT0 или INT1, т.е. внешнее прерывание. Внешнее прерывание настроить на срабатывание и на фронт и на спад. В обработчике прерывания выдать импульс.

Если нужен импульс определенной ширины. В обработчике внешнего прерывания выходной порт устанавливает в 1. Запускаете таймер. В обработчике прерывания таймера (тут разные варианты могут быть) выходной порт в 0, остановка таймера.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
RusikOk
Нашел транзистор. Понюхал.
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев
Контактная информация:

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

Сообщение RusikOk »

[uquote="makser",url="/forum/viewtopic.php?p=470498#p470498"]Обращаю внимание: функция sqrt() иногда выдает не верный результат, пользуйтесь pow().[/uquote]так да немного не так. попробуйте узнать результат pow(2, 0). Вы будете удивлены но результат будет не верным
Аватара пользователя
RusikOk
Нашел транзистор. Понюхал.
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев
Контактная информация:

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

Сообщение RusikOk »

извините не знаю под чем я был. присваивал результат переменной целого типа
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

PWM

Сообщение serg_svd »

Нужна помощь по ШИМ.
Железо - ATmega32. Используется таймер 2 с выходом на OC2(PD7)/
Настройки такие
Изображение

Мастер выдает код инициализации таймера 2

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

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Fast PWM top=0xFF
// OC2 output: Non-Inverted PWM
// Timer Period: 4,096 ms
// Output Pulse(s):
// OC2 Period: 4,096 ms Width: 4,096 ms
ASSR=0<<AS2;
TCCR2=(1<<PWM2) | (1<<COM21) | (0<<COM20) | (1<<CTC2) | (1<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0xFF;


Для запуска и останова ШИМ я пытался использовать следующие макросы

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

#define OnPWM()         TCCR2 |=((1<<CS22) | (0<<CS21) | (0<<CS20))
#define OffPWM()        TCCR2 &=~((1<<CS22) | (1<<CS21) | (1<<CS20))


Задача состояла в управлении двигателем постоянного тока в простецком намоточном станке. Мне потребовался плавный разгон двигателя на старте и сброс оборотов перед окончанием намотки. Проблема у меня возникла в следующем. На старте, я в регистр OCR2 прописываю значение малых оборотов OCR2=40;. Далее, дискретно по определенным количествам витков я поднимаю значение до OCR2=255;.
Все работает, двигатель разгоняется.
Но при значении в регистре OCR2=255; я не могу стабильно остановить двигатель макросом OffPWM();.
ШИМ судя по всему отключается, но в порту PD7 остается 1.
Перерыл в интернете кучу примеров и обучалок, везде ставится задача стартануть ШИМ. А как остановить - не нашел.
Подскажите, пожалуйста, верное решение.

PS. дольше код уже сижу вдумчиво разбираю, чем эти катушки несчастные мотать. Пока сделал без плавного разгона и часть намотал, но хочется решить задачку
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

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

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

Сообщение ARV »

проще всего выключать ШИМ полным обнулением регистра TCCR2 - выключится и сам таймер, и режим порта. Но заранее в порту должен быть записан нолик.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

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

Сообщение serg_svd »

WiseLord, ARV, спасибо!
Я записывал в порт 0, но после выключения ШИМ. И, видимо, в этом и была ошибка.
переписал макросы так:

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

#define OnPWM()         TCCR2=(1<<PWM2) | (1<<COM21) | (0<<COM20) | (1<<CTC2) | (1<<CS22) | (0<<CS21) | (0<<CS20);
 
#define OffPWM()    do {\
                    PORTD &=~(1<<PORTD7);\
                    TCCR2=0x00;\
            }while(0)


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

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

Сообщение ARV »

Проблема у вас была не в том, что ПОСЛЕ записывали, а в том, что не выключали "особую функцию порта", которая включалась битами регистра TCCR2. Вы же только ОСТАНАВЛИВАЛИ таймер, но не выключали режим. После обнуления регистра все стало на свои места.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

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

Сообщение serg_svd »

ARV писал(а):а в том, что не выключали "особую функцию порта"

Увы нет.
Была у меня версия управления, где макрос на включения ПОЛНОСТЬЮ настраивал регистр TCCR2, а макрос отключения его обнулял. И эта версия не работала, именно потому, что после обновления регистра я и записывал 0 в порт.
Поэтому я и посчитал, что все равно, что делать. То ли полностью регистр прописывать и обнулять, то ли просто таймер останавливать.
ARV писал(а):Вы же только ОСТАНАВЛИВАЛИ таймер, но не выключали режим.

А не выключая режим управлять портом прописывая туда 0 или 1 нельзя? Правильно я понял?
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Можно. Но это значение PORT "не доходит" до ножки, будучи перехвачено особой функцией.
С другой стороны, единожды (при инициализации системы) записав PORT=0, мы должны бы иметь этот ноль на ножке при отключении особой функции (ШИМ).
Хотя я не уверен, возможно ШИМ меняет содержимое PORT, и обнулять его нужно каждый раз.
Tenken
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт янв 17, 2013 21:25:30
Откуда: Тула

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

Сообщение Tenken »

Здравствуйте, подскажите пожалуйста) Имеется светодиодная строка на 4 матрицах 8х8 с микросхемами max 7219 (вроде как spi) . Дабы разобраться в принципе управления этой микросхемой взял вот такую функцию)

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

void write(char data, char adress)
{   
       unsigned char i;
       //опускаем CS
       _soft_latch=0; 
       #asm("nop") //latch
 
       //задвигаем адрес
       for(i=0;i<8;i++)
       {       
       if(adress & 0x80)
       {
       _soft_data = 1;
       }
       else
       {
       _soft_data = 0;
       }
         #asm("nop") //shift
         _soft_shift=1;
         #asm("nop")
         _soft_shift=0; 
         adress <<= 1;   
       } 
 
       //задвигаем данные     
       for(i=0;i<8;i++)
       {       
       if(data & 0x80)
       {
       _soft_data = 1;
       }
       else
       {
       _soft_data = 0;
       }
         #asm("nop") //shift
         _soft_shift=1;
         #asm("nop")
         _soft_shift=0; 
         data <<= 1;   
      }               
       _soft_latch=1;   
}
И вроде бы понятно , но это включает конкретно в одной матрице 1 строку и ней конкретно" точки".
То есть чтобы вывести например цифру из точек высотой в 7, на одной матрице мне надо будет прописать:

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

write(char data, char adress)
write(char data, char adress)
write(char data, char adress)
write(char data, char adress)
write(char data, char adress)
write(char data, char adress)
write(char data, char adress)

короче говоря код слишком сильно разрастается)ибо это на одной матрице только , а их 4) может быть я использую не тот принцип вывода?) или я чегото не понял?)Но по крайней мере я управляю семи точками вручную и мне это понятно...)
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Всё верно, именно так информация и выводится.
У max7219 есть особая команда noop, при которой на матрицу ничего не выводится, но данные передаются в следующую подключенную по цепочке матрицу. На пальцах - если подключено 4 матрицы последовательно, и надо вывести что-то в третью, то передаётся noop/0 (для четвёртой), столбец/данные (для третьей), и снова дважды noop/0 для второй и первой. После защёлкивания всё отобразится как и хотелось.

Можете поизучать для примера мой драйвер для MAX7219 https://github.com/WiseLord/matrixclock ... /max7219.c

Самое здесь интересное - это sendDataBuf функция, в которую передаётся адрес из массива (32 байта - вертикальных столбика), после чего на матрицу выводится этот буфер. Программе всё что нужно - просто отрисовать что-либо в этот буфер, а затем просто дёрнуть эту функцию.
Последний раз редактировалось WiseLord Вс июл 02, 2017 08:52:21, всего редактировалось 1 раз.
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

No-Op Register
The no-op register is used when cascading MAX7219s
or MAX7221s. Connect all devices’ LOAD/CS inputs
together and connect DOUT to DIN on adjacent
devices. DOUT is a CMOS logic-level output that easily
drives DIN of successively cascaded parts. (Refer to
the Serial Addressing Modes section for detailed infor-
mation on serial input/output timing.) For example, if
four MAX7219s are cascaded, then to write to the
fourth chip, sent the desired 16-bit word, followed by
three no-op codes (hex XX0X, see Table 2). When
LOAD/CS goes high, data is latched in all devices. The
first three chips receive no-op commands, and the
fourth receives the intended data.

Всё едино гнать данные и адрес/команду каждый раз.
Docendo discimus
Vasiliy_tERKIN
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Вт авг 26, 2014 08:59:16

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

Сообщение Vasiliy_tERKIN »

Я пока еще не силен в указателях в функции у вас указана

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

void max7219SendDataBuf(uint8_t *buf)
{
   uint8_t i, j;

   for (i = 0; i < 8; i++) {
      PORT(MAX7219_LOAD) &= ~MAX7219_LOAD_LINE;
      for (j = 0; j < MATRIX_CNT; j++) {
         max7219SendByte(MAX7219_DIGIT_0 + i);
         max7219SendByte(buf[8 * j + i]);
      }
      PORT(MAX7219_LOAD) |= MAX7219_LOAD_LINE;
   }

   return;
}
Значит где то указано что эта переменная ссылается на что-то (с помощью & или нет?)
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Где-то в коде есть массив вроде

uint8_t myBuf[32];

В него отрисовывается нужная картинка (текст и т.д.), после чего вызов max7219SendDataBuf(myBuf) выведет всю эту картинку.
Alex_Golubev
Встал на лапы
Сообщения: 87
Зарегистрирован: Вс ноя 15, 2015 05:54:13

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

Сообщение Alex_Golubev »

Cv avr 3.25 ругается на следующие:

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

const unsigned char StrLoad[]        =  "Load";

при вызове функции:

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

void FlashToLCDtSimpl(const unsigned char  *xaddres){
     for(;*xaddres!=0;++xaddres){
      LcdWriteData (*xaddres);
   }
}

Выдает ошибку:
Error: function argument #1 of type 'flash unsigned char [17]' is incompatible with required parameter of type 'const unsigned char *'
Если убрать const unsigned char сделать unsigned char то ошибка пропадает, но зачем мне размещать статические строки в ОЗУ, Как правильно разместить строки во флешь? Что-то типа:

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

flash const unsigned char или const unsigned char flash или unsigned char const *

не работает.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Alex_Golubev писал(а):flash unsigned char [17]
В приведённом коде не вижу вообще ничего, на что мог бы компилятор ругаться именно так. Откуда вообще этот flash? Чего-то не хватает.
rusl32
Родился
Сообщения: 17
Зарегистрирован: Вс окт 25, 2015 19:09:46

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

Сообщение rusl32 »

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

const unsigned char StrLoad[]        =  "Load";

вот так попробовать:

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

flash unsigned char StrLoad[]        =  "Load";

и

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

void FlashToLCDtSimpl(flash unsigned char  *xaddres){
     for(;*xaddres!=0;++xaddres){
      LcdWriteData (*xaddres);
   }
}
Alex_Golubev
Встал на лапы
Сообщения: 87
Зарегистрирован: Вс ноя 15, 2015 05:54:13

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

Сообщение Alex_Golubev »

Так работает
RoTToR
Открыл глаза
Сообщения: 73
Зарегистрирован: Вс июн 07, 2009 23:16:16
Контактная информация:

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

Сообщение RoTToR »

Добрый день. Нужна Ваша помощь. Такое дело, сделал счетчик витков для намоточного станка на attiny2313 + семисегментный дисплей и щелевой датчик висящий на порте PB2 с одним прерыванием на оборот. Возникла идея еще измерять количество оборотов в минуту, максимальная скорость вращения 120-130 об/мин. мин. примерно 10 об/мин. хотелось бы получить точность не хуже плюс-минус пару оборотов в минуту.
Единственное что приходит в голову, измерять период с помощью Таймера1, но так как периоды получаются очень большие на малых оборотах, ничего не получается по формуле.
Помогите советом.!
Ответить

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