Страница 1 из 2

Шим синус на atmega48

Добавлено: Сб мар 11, 2017 16:40:03
DenChik87
Нужно сделать синус для инвертора. Для этого я буду использовать таймер 2, atmega48, загружая в регистр ocr2 последовательно массив для синусоиды из 160ти значений (нужно именно 160), которые предварительно расчитал в exel. Сначала массив загружаю в прямом, затем в обратном направлении (от 0 до максимума и с маусмума до 0 синусоиды). Исходник прикрепил ниже. Загрузил его в протеусе. ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит. Подскажите в чем ошибка?

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 17:07:49
vem566
DenChik87 писал(а):ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит.
Как это? Во всяком случае увеличиваться один раз должно по любому. Вот потом может быть все что угодно.
Дело в том, что первый цикл(на увеличение) идет от 0 до 159, что правильно, а вот уменьшение идет от 160 до 0, что никак не есть хорошо. Даже больше скажу - плохо. И даже еще больше - очень плохо.
Нельзя выходить за границы массива.

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 18:21:58
DenChik87
vem566 писал(а):Как это? Во всяком случае увеличиваться один раз должно по любому.
Даже один раз не проходит! Ни чего не понимаю :dont_know: Переписал код, в котором OCR2 обновляю только после нажатия кнопки. Код прикрепил. Где-то до 80го нажатия значения загружаются из массива отлично, затем шим срывается и происходит "чихуа хуа"

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 19:15:49
AndTer
DenChik87 писал(а):Переписал код
:facepalm:

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 19:24:35
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 точки.

и чтобы опять не ошибиться, просто скопируй мою "таблицу" в свой текст...

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 21:14:06
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--)
{
...
...
}

Re: Шим синус на atmega48

Добавлено: Сб мар 11, 2017 21:46:05
Starichok51
ну, забыл я в конце строк поставить запятые...

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

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

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 06:31:27
DenChik87
Сделал все как вы сказали. Подскажите то что сейчас написаное должно работать? Дело в том что если пошагово отследить в протеусе, то происходит следующее: массив последовательно загружается от 0 до 93го значения, затем сбрасывается и снова начинает с 0го, загружая последовательно значения из массива, пока i не дойдет до 160, затем все тоже самое только в обратном направлении.Не ругайтесь :? Очень хочется разобраться.

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 08:14:40
metan
Первым делом я бы заменил int на unsigned char везде, где значение по определению не может выйти за 255 и всегда положительное. Конечно я не уверен, что дело именно в этом, но может при приведении типов что-то не то происходит...

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 08:20:30
Starichok51
я тебе уже, вроде, 3 раза сказал, что второй цикл нужно начинать с числа 158. а ты опять туда записал 159...

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

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

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 09:09:47
DenChik87
Вот мой исходник, в AVRS5, и схема в протеусе8.5. Если не затруднит взгляните и сами все увидите. Я пробовал уже и в 7мой версии протеуса загружать, думал может в нем дело. Пробовал компилировал в atmel6, запускаю в протеусе и та же картина.

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 09:43:45
COKPOWEHEU
for (i=158;i>=0;i--){
Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 10:11:07
DenChik87
COKPOWEHEU писал(а):for (i=158;i>=0;i--)Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.
У меня i объявлена типа int, вот же есть исходник, можете взглянуть. Я уже пробовал этот код и AVR5 и в AVR6 и в протеус 8 и в протеус 7. Пробовал убирать оптимизацию кода(думал может компилятор язвит). Ничего не помагло!
Спасибо про повторение 0-й точки. Действительно надо так писать: for(i=158;i>0;i--) следующий же цикл с 0я начинается.
Я не проверял работу в железе, только в протеусе. Сбрасываться ничего не должно.

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 11:28:17
COKPOWEHEU
Я и написал что ошибка возникнет только если исправите тип счетчика. Для 2-байтового знакового числа все нормально а для 1-байтного, которого достаточно для данного случая, возникла бы проблема. В исправленном случае, для строгого сравнения ( > вместо >= ) и беззнакового числа все нормально.
Сбрасываться ничего не должно.
"не должно" и "не сбрасывается" - разные вещи. Сбрасываться оно может не только из-за кода, но и из-за неотключенной собаки, например. Поэтому и советую проверить как оно на самом деле. Ввести в начале мигалку диодом или поставить брякпоинт а инициализации не так долго, зато будете уверенным.

Re: Шим синус на atmega48

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

Re: Шим синус на atmega48

Добавлено: Вс мар 12, 2017 13:52:25
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 равно нулю -> можно переходить к следующему полупериоду */
}

Re: Шим синус на atmega48

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

Ага, действительно - переключается.
/* здесь надо переключить, положительная/отрицательная часть синусоиды *

Re: Шим синус на atmega48

Добавлено: Сб мар 18, 2017 12:22:40
DenChik87
Теперь пытаюсь сделать чтобы значения регистра ocr2a обновлялились по прерыванию таймера2. Но массив не выводится, что не так?

Re: Шим синус на atmega48

Добавлено: Сб мар 18, 2017 12:29:46
Аlex
Вам бы, прежде чем вопросы бездумно постить на форуме, книгу бы для начинающи почитать. А конкретнее (как правило, самые первые разделы) - встроенные типы переменных.
Ну ладно бы с ними проблем не возникало, но уже же накололись на них. Неужели трудно (не интересно) взять и почитать ? Проще методом тыка строчить куски быдлокода и после каждой бежать на форум ?

Re: Шим синус на atmega48

Добавлено: Сб мар 18, 2017 12:40:43
DenChik87
Посоветуйте что-нибудь для быстрого старта