- Вложения
-
- код.png
- (178.27 КБ) 699 скачиваний
Шим синус на atmega48
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Нужно сделать синус для инвертора. Для этого я буду использовать таймер 2, atmega48, загружая в регистр ocr2 последовательно массив для синусоиды из 160ти значений (нужно именно 160), которые предварительно расчитал в exel. Сначала массив загружаю в прямом, затем в обратном направлении (от 0 до максимума и с маусмума до 0 синусоиды). Исходник прикрепил ниже. Загрузил его в протеусе. ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит. Подскажите в чем ошибка?
- Реклама
Как это? Во всяком случае увеличиваться один раз должно по любому. Вот потом может быть все что угодно.DenChik87 писал(а):ШИМ сначало увеличивается пропорционально, соответствуя таблице массива, но до значения 255 так и не доходит.
Дело в том, что первый цикл(на увеличение) идет от 0 до 159, что правильно, а вот уменьшение идет от 160 до 0, что никак не есть хорошо. Даже больше скажу - плохо. И даже еще больше - очень плохо.
Нельзя выходить за границы массива.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Даже один раз не проходит! Ни чего не понимаюvem566 писал(а):Как это? Во всяком случае увеличиваться один раз должно по любому.
- Вложения
-
- код.png
- (174.09 КБ) 692 скачивания
- Сообщения: 2406
- Зарегистрирован: Ср фев 23, 2011 12:12:31
DenChik87 писал(а):Переписал код
Глупый не задает вопросы. Глупый и так все знает.
а с чего оно должно работать? у тебя в одном месте запятая пропущена - 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 точки.
и чтобы опять не ошибиться, просто скопируй мою "таблицу" в свой текст...
да и значения синуса не правильно посчитаны. должно быть так:
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
Действительно запятую пропустилStarichok51 писал(а):а с чего оно должно работать? у тебя в одном месте запятая пропущена - 185187
да и значения синуса не правильно посчитаны.
и в исходнике из первого поста должно быть так:
for (int i = 158; i >= 0; i--)
{
...
...
}
.
И не понятно почему надо загружать 158, у меня же 160 значений, значит от 0 до 159(включительно) и от 159 до 0(включительно) т.е. наверное так:
for (int i = 0; i <160; i++)
{
...
...
}
for (int i = 160; i >= 0; i--)
{
...
...
}
- Вложения
-
- код.png
- (176.23 КБ) 339 скачиваний
ну, забыл я в конце строк поставить запятые...
тебе же уже русским языком сказали, что за границы массива нельзя выходить!
у тебя же всего 160 значений - от 0 до 159. стошестидесятого значения в массиве НЕТ!!!
и я тебе русским языком сказал, что вершина синуса - это 159-е значение, после которого нужно "опускаться" по синусу обратно. то есть, нужно обратно идти со 158-го значения.
нельзя повторять угол (фазу) 90 градусов два раза.
код ты опять прикрепил... срань ты прикрепил, а не код...
а кто будет проверять верхнее значение индекса "i"? код не только до конца массива дошел, он пошел гулять дальше, далеко за границами массива...
и уже пора забыть про кнопку, делал, как по первому посту - туда-обратно.
тебе же уже русским языком сказали, что за границы массива нельзя выходить!
у тебя же всего 160 значений - от 0 до 159. стошестидесятого значения в массиве НЕТ!!!
и я тебе русским языком сказал, что вершина синуса - это 159-е значение, после которого нужно "опускаться" по синусу обратно. то есть, нужно обратно идти со 158-го значения.
нельзя повторять угол (фазу) 90 градусов два раза.
код ты опять прикрепил... срань ты прикрепил, а не код...
а кто будет проверять верхнее значение индекса "i"? код не только до конца массива дошел, он пошел гулять дальше, далеко за границами массива...
и уже пора забыть про кнопку, делал, как по первому посту - туда-обратно.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Сделал все как вы сказали. Подскажите то что сейчас написаное должно работать? Дело в том что если пошагово отследить в протеусе, то происходит следующее: массив последовательно загружается от 0 до 93го значения, затем сбрасывается и снова начинает с 0го, загружая последовательно значения из массива, пока i не дойдет до 160, затем все тоже самое только в обратном направлении.Не ругайтесь
Очень хочется разобраться.
- Вложения
-
- код.png
- (173.37 КБ) 589 скачиваний
- Сообщения: 599
- Зарегистрирован: Ср янв 06, 2010 10:01:46
Первым делом я бы заменил int на unsigned char везде, где значение по определению не может выйти за 255 и всегда положительное. Конечно я не уверен, что дело именно в этом, но может при приведении типов что-то не то происходит...
я тебе уже, вроде, 3 раза сказал, что второй цикл нужно начинать с числа 158. а ты опять туда записал 159...
я накидал по быстрому в АтмелСтудио твой код. у меня в симуляторе ничего и нигде не останавливается.
и первый цикл идет сразу же без остановки до конца (до 159), и второй цикл идет без остановки в обратную сторону.
не могу знать что там у тебя происходит не так.
причин в твоем коде для такого сброса в ноль счетчика цикла я не вижу.
дело не в знаковом типе числа. в регистр таймера число все равно записывается правильно. таймер ничего не знает о том, что кто-то считает число отрицательным.
я накидал по быстрому в АтмелСтудио твой код. у меня в симуляторе ничего и нигде не останавливается.
и первый цикл идет сразу же без остановки до конца (до 159), и второй цикл идет без остановки в обратную сторону.
не могу знать что там у тебя происходит не так.
причин в твоем коде для такого сброса в ноль счетчика цикла я не вижу.
дело не в знаковом типе числа. в регистр таймера число все равно записывается правильно. таймер ничего не знает о том, что кто-то считает число отрицательным.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Вот мой исходник, в AVRS5, и схема в протеусе8.5. Если не затруднит взгляните и сами все увидите. Я пробовал уже и в 7мой версии протеуса загружать, думал может в нем дело. Пробовал компилировал в atmel6, запускаю в протеусе и та же картина.
- Вложения
-
- 1.rar
- (39.4 КБ) 196 скачиваний
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?for (i=158;i>=0;i--){
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
У меня i объявлена типа int, вот же есть исходник, можете взглянуть. Я уже пробовал этот код и AVR5 и в AVR6 и в протеус 8 и в протеус 7. Пробовал убирать оптимизацию кода(думал может компилятор язвит). Ничего не помагло!COKPOWEHEU писал(а):for (i=158;i>=0;i--)Если исправите тип i, здесь возникнет ошибка (бесконечный или пустой цикл в зависимости от того, на знаковое или беззнаковое исправите), да и зачем повторять 0-ю точку несколько раз?
Если контроллер начинает первый цикл с начала, проверьте не сбрасывается ли он. Добавьте в начало мигание диодом или что-то подобное.
Спасибо про повторение 0-й точки. Действительно надо так писать: for(i=158;i>0;i--) следующий же цикл с 0я начинается.
Я не проверял работу в железе, только в протеусе. Сбрасываться ничего не должно.
- Вложения
-
- 1.rar
- (39.4 КБ) 178 скачиваний
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Я и написал что ошибка возникнет только если исправите тип счетчика. Для 2-байтового знакового числа все нормально а для 1-байтного, которого достаточно для данного случая, возникла бы проблема. В исправленном случае, для строгого сравнения ( > вместо >= ) и беззнакового числа все нормально.
"не должно" и "не сбрасывается" - разные вещи. Сбрасываться оно может не только из-за кода, но и из-за неотключенной собаки, например. Поэтому и советую проверить как оно на самом деле. Ввести в начале мигалку диодом или поставить брякпоинт а инициализации не так долго, зато будете уверенным.Сбрасываться ничего не должно.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Невероятно но факт!!! Заменил массив c типа int на тип char и все заработало!!!
С типом int массив нормально читается если число значений в нем не превышает 80ти. С типом char все 160 значений выводятся без проблем!!!
Всем кто отвечал респектухиии!!! Особенно коту metan, ведь он по сути давно дал правильный ответ (надо было сразу проверить его версию)!!! Тема закрыта) Но если кто может рассказать сие явление буду очень признателен! 
- Сообщения: 291
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
DenChik87, у Atmega48, насколько я помню, 512байт SRAM. Вы так "смело" под стеком выделяете 320байт (если int двухбайтовый). Уверены что со стеком все нормально? Долго отвечал, не видел Вашего последнего ответа, скорей всего именно проблемы со стеком были.
1) sin_mass массив сделать байтовым
2) Я бы убрал sin_mass из под стека
Еще лучше - хранить sin_mass во флеше, для GCC + avr-libc, вроде так:
Далее совсем просто, индекс i (тоже незачем делать двухбайтовым, он вполне может быть однобайтовым):
1) sin_mass массив сделать байтовым
Код: Выделить всё
unsigned char sin_mass[]={...};Код: Выделить всё
static unsigned char sin_mass[]={...};
#define SIN_VAL(i) (sin_mass[(i)])Код: Выделить всё
#include <avr/pgmspace.h>
...
unsigned char sin_mass[160] PROGMEM = {...};
#define SIN_VAL(i) (pgm_read_byte (sin_mass + (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 равно нулю -> можно переходить к следующему полупериоду */
}
Работает, говорите ? Странно... На осцилле должна получаться не синусовина, а две полу-синусовины
Вобщем, 2-полупериодное выпрямление. Разве что на втором проходе операционник переключается из +Кус в -Кус
Ага, действительно - переключается.
Ага, действительно - переключается.
/* здесь надо переключить, положительная/отрицательная часть синусоиды *
Вам бы, прежде чем вопросы бездумно постить на форуме, книгу бы для начинающи почитать. А конкретнее (как правило, самые первые разделы) - встроенные типы переменных.
Ну ладно бы с ними проблем не возникало, но уже же накололись на них. Неужели трудно (не интересно) взять и почитать ? Проще методом тыка строчить куски быдлокода и после каждой бежать на форум ?
Ну ладно бы с ними проблем не возникало, но уже же накололись на них. Неужели трудно (не интересно) взять и почитать ? Проще методом тыка строчить куски быдлокода и после каждой бежать на форум ?
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00



