Шим синус на atmega48

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Нужно сделать синус для инвертора. Для этого я буду использовать таймер 2, atmega48, загружая в регистр ocr2 последовательно массив для синусоиды из 160ти значений (нужно именно 160), которые предварительно расчитал в exel. Сначала массив загружаю в прямом, затем в обратном направлении (от 0 до максимума и с маусмума до 0 синусоиды). Исходник прикрепил ниже. Загрузил его в протеусе. ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит. Подскажите в чем ошибка?
Вложения
код.png
(178.27 КБ) 699 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

DenChik87 писал(а):ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит.
Как это? Во всяком случае увеличиваться один раз должно по любому. Вот потом может быть все что угодно.
Дело в том, что первый цикл(на увеличение) идет от 0 до 159, что правильно, а вот уменьшение идет от 160 до 0, что никак не есть хорошо. Даже больше скажу - плохо. И даже еще больше - очень плохо.
Нельзя выходить за границы массива.
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

vem566 писал(а):Как это? Во всяком случае увеличиваться один раз должно по любому.
Даже один раз не проходит! Ни чего не понимаю :dont_know: Переписал код, в котором OCR2 обновляю только после нажатия кнопки. Код прикрепил. Где-то до 80го нажатия значения загружаются из массива отлично, затем шим срывается и происходит "чихуа хуа"
Вложения
код.png
(174.09 КБ) 692 скачивания
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2406
Зарегистрирован: Ср фев 23, 2011 12:12:31

Сообщение AndTer »

DenChik87 писал(а):Переписал код
:facepalm:
Глупый не задает вопросы. Глупый и так все знает.
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

а с чего оно должно работать? у тебя в одном месте запятая пропущена - 185187
да и значения синуса не правильно посчитаны. должно быть так:
0, 3, 5, 8, 10, 13, 15, 18, 20, 23
25, 27, 30, 32, 35, 37, 40, 42, 45, 47
50, 52, 55, 57, 60, 62, 64, 67, 69, 72
74, 76, 79, 81, 84, 86, 88, 91, 93, 95
98, 100, 102, 104, 107, 109, 111, 114, 116, 118
120, 122, 125, 127, 129, 131, 133, 135, 137, 140
142, 144, 146, 148, 150, 152, 154, 156, 158, 160
162, 164, 166, 168, 169, 171, 173, 175, 177, 179
180, 182, 184, 186, 187, 189, 191, 192, 194, 196
197, 199, 200, 202, 203, 205, 206, 208, 209, 211
212, 213, 215, 216, 217, 219, 220, 221, 222, 224
225, 226, 227, 228, 229, 231, 232, 233, 234, 235
236, 237, 237, 238, 239, 240, 241, 242, 243, 243
244, 245, 245, 246, 247, 247, 248, 249, 249, 250
250, 251, 251, 251, 252, 252, 253, 253, 253, 254
254, 254, 254, 254, 255, 255, 255, 255, 255, 255

и в исходнике из первого поста должно быть так:
for (int i = 158; i >= 0; i--)
{
...
...
}
так как ты уже в первом цикле дошел до вершины синуса (90 градусов), и нужно обратно идти на шаг меньше, с 158 точки.

и чтобы опять не ошибиться, просто скопируй мою "таблицу" в свой текст...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Starichok51 писал(а):а с чего оно должно работать? у тебя в одном месте запятая пропущена - 185187
да и значения синуса не правильно посчитаны.
и в исходнике из первого поста должно быть так:
for (int i = 158; i >= 0; i--)
{
...
...
}
.
Действительно запятую пропустил :facepalm: Спасибо огромное :beer: Взял ваш массив(у вас тоже в коце строк запятых нет), но до конца и он не дошел, не понимаю почему :dont_know: Я даже сделал кнопку, нажимая которую инкрементирую значение массива и ложу его в OCR2, но до конца(255) массив не дошел. Код прикрепил.
И не понятно почему надо загружать 158, у меня же 160 значений, значит от 0 до 159(включительно) и от 159 до 0(включительно) т.е. наверное так:
for (int i = 0; i <160; i++)
{
...
...
}
for (int i = 160; i >= 0; i--)
{
...
...
}
Вложения
код.png
(176.23 КБ) 339 скачиваний
Реклама
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

ну, забыл я в конце строк поставить запятые...

тебе же уже русским языком сказали, что за границы массива нельзя выходить!
у тебя же всего 160 значений - от 0 до 159. стошестидесятого значения в массиве НЕТ!!!
и я тебе русским языком сказал, что вершина синуса - это 159-е значение, после которого нужно "опускаться" по синусу обратно. то есть, нужно обратно идти со 158-го значения.
нельзя повторять угол (фазу) 90 градусов два раза.

код ты опять прикрепил... срань ты прикрепил, а не код...
а кто будет проверять верхнее значение индекса "i"? код не только до конца массива дошел, он пошел гулять дальше, далеко за границами массива...
и уже пора забыть про кнопку, делал, как по первому посту - туда-обратно.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Сделал все как вы сказали. Подскажите то что сейчас написаное должно работать? Дело в том что если пошагово отследить в протеусе, то происходит следующее: массив последовательно загружается от 0 до 93го значения, затем сбрасывается и снова начинает с 0го, загружая последовательно значения из массива, пока i не дойдет до 160, затем все тоже самое только в обратном направлении.Не ругайтесь :? Очень хочется разобраться.
Вложения
код.png
(173.37 КБ) 589 скачиваний
Вымогатель припоя
Сообщения: 599
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

Первым делом я бы заменил int на unsigned char везде, где значение по определению не может выйти за 255 и всегда положительное. Конечно я не уверен, что дело именно в этом, но может при приведении типов что-то не то происходит...
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

я тебе уже, вроде, 3 раза сказал, что второй цикл нужно начинать с числа 158. а ты опять туда записал 159...

я накидал по быстрому в АтмелСтудио твой код. у меня в симуляторе ничего и нигде не останавливается.
и первый цикл идет сразу же без остановки до конца (до 159), и второй цикл идет без остановки в обратную сторону.
не могу знать что там у тебя происходит не так.
причин в твоем коде для такого сброса в ноль счетчика цикла я не вижу.

дело не в знаковом типе числа. в регистр таймера число все равно записывается правильно. таймер ничего не знает о том, что кто-то считает число отрицательным.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Вот мой исходник, в AVRS5, и схема в протеусе8.5. Если не затруднит взгляните и сами все увидите. Я пробовал уже и в 7мой версии протеуса загружать, думал может в нем дело. Пробовал компилировал в atmel6, запускаю в протеусе и та же картина.
Вложения
1.rar
(39.4 КБ) 196 скачиваний
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

for (i=158;i>=0;i--){
Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

COKPOWEHEU писал(а):for (i=158;i>=0;i--)Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.
У меня i объявлена типа int, вот же есть исходник, можете взглянуть. Я уже пробовал этот код и AVR5 и в AVR6 и в протеус 8 и в протеус 7. Пробовал убирать оптимизацию кода(думал может компилятор язвит). Ничего не помагло!
Спасибо про повторение 0-й точки. Действительно надо так писать: for(i=158;i>0;i--) следующий же цикл с 0я начинается.
Я не проверял работу в железе, только в протеусе. Сбрасываться ничего не должно.
Вложения
1.rar
(39.4 КБ) 178 скачиваний
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Я и написал что ошибка возникнет только если исправите тип счетчика. Для 2-байтового знакового числа все нормально а для 1-байтного, которого достаточно для данного случая, возникла бы проблема. В исправленном случае, для строгого сравнения ( > вместо >= ) и беззнакового числа все нормально.
Сбрасываться ничего не должно.
"не должно" и "не сбрасывается" - разные вещи. Сбрасываться оно может не только из-за кода, но и из-за неотключенной собаки, например. Поэтому и советую проверить как оно на самом деле. Ввести в начале мигалку диодом или поставить брякпоинт а инициализации не так долго, зато будете уверенным.
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Невероятно но факт!!! Заменил массив c типа int на тип char и все заработало!!! 8) С типом int массив нормально читается если число значений в нем не превышает 80ти. С типом char все 160 значений выводятся без проблем!!! 8) Всем кто отвечал респектухиии!!! Особенно коту metan, ведь он по сути давно дал правильный ответ (надо было сразу проверить его версию)!!! Тема закрыта) Но если кто может рассказать сие явление буду очень признателен! :P
Грызет канифоль
Сообщения: 291
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

DenChik87, у Atmega48, насколько я помню, 512байт SRAM. Вы так "смело" под стеком выделяете 320байт (если int двухбайтовый). Уверены что со стеком все нормально? Долго отвечал, не видел Вашего последнего ответа, скорей всего именно проблемы со стеком были.

1) sin_mass массив сделать байтовым

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

unsigned char sin_mass[]={...};
2) Я бы убрал sin_mass из под стека

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

static unsigned char sin_mass[]={...};
#define SIN_VAL(i) (sin_mass[(i)])
Еще лучше - хранить sin_mass во флеше, для GCC + avr-libc, вроде так:

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

#include <avr/pgmspace.h>
...
unsigned char sin_mass[160] PROGMEM = {...};
#define SIN_VAL(i) (pgm_read_byte (sin_mass + (i)))
Далее совсем просто, индекс i (тоже незачем делать двухбайтовым, он вполне может быть однобайтовым):

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

register unsigned char i = 0;

while (1) {
        /* здесь надо переключить, положительная/отрицательная часть синусоиды *

        do {
                /* SIN_VAL(i) - значение синуса, делаем с ним, что надо */
        } while (++i < (sizeof (sin_mass) - 1));
        /* здесь i - индекс последнего элемента */
        do {
                /* SIN_VAL(i) - значение синуса, делаем с ним, что надо */
        } while (--i > 0);
        /* здесь i равно нулю -> можно переходить к следующему полупериоду */
}
Друг Кота
Аватара пользователя
Сообщения: 6337
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Работает, говорите ? Странно... На осцилле должна получаться не синусовина, а две полу-синусовины :( Вобщем, 2-полупериодное выпрямление. Разве что на втором проходе операционник переключается из ус в ус

Ага, действительно - переключается.
/* здесь надо переключить, положительная/отрицательная часть синусоиды *
Изображение
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Теперь пытаюсь сделать чтобы значения регистра ocr2a обновлялились по прерыванию таймера2. Но массив не выводится, что не так?
Вложения
код.png
(129.25 КБ) 619 скачиваний
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Вам бы, прежде чем вопросы бездумно постить на форуме, книгу бы для начинающи почитать. А конкретнее (как правило, самые первые разделы) - встроенные типы переменных.
Ну ладно бы с ними проблем не возникало, но уже же накололись на них. Неужели трудно (не интересно) взять и почитать ? Проще методом тыка строчить куски быдлокода и после каждой бежать на форум ?
Встал на лапы
Аватара пользователя
Сообщения: 147
Зарегистрирован: Вс мар 09, 2014 09:13:00

Сообщение DenChik87 »

Посоветуйте что-нибудь для быстрого старта
Ответить

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