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

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

Сообщение Z_h_e »

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

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

Сообщение RusikOk »

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

Сообщение RusikOk »

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

Сообщение WiseLord »

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

Сообщение ARV »

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

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

Сообщение 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
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

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

Сообщение serg_svd »

ARV писал(а):а в том, что не выключали "особую функцию порта"
Увы нет.
Была у меня версия управления, где макрос на включения ПОЛНОСТЬЮ настраивал регистр TCCR2, а макрос отключения его обнулял. И эта версия не работала, именно потому, что после обновления регистра я и записывал 0 в порт.
Поэтому я и посчитал, что все равно, что делать. То ли полностью регистр прописывать и обнулять, то ли просто таймер останавливать.
ARV писал(а):Вы же только ОСТАНАВЛИВАЛИ таймер, но не выключали режим.
А не выключая режим управлять портом прописывая туда 0 или 1 нельзя? Правильно я понял?
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

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

Сообщение 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) может быть я использую не тот принцип вывода?) или я чегото не понял?)Но по крайней мере я управляю семи точками вручную и мне это понятно...)
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение 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 раз.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение 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
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Вт авг 26, 2014 08:59:16

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

Сообщение WiseLord »

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

uint8_t myBuf[32];

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

Сообщение 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 *
не работает.
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

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

Сообщение rusl32 »

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

const unsigned char StrLoad[]        =  "Load";
вот так попробовать:

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

flash unsigned char StrLoad[]        =  "Load";
и

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

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

Сообщение Alex_Golubev »

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

Сообщение RoTToR »

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

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