Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/63: Рейтинг темы: голосов - 63, средняя оценка - 4.78
Mr.OmdirsomTukomsk
0 / 0 / 0
Регистрация: 02.01.2013
Сообщений: 4
1

Синус с помощью ШИМ на AtMega8

06.01.2013, 01:06. Просмотров 11712. Ответов 10
Метки нет (Все метки)

Здравствуйте!
Раньше дел с контроллерами не имел, поэтому решил начать с малого. Взял я CodeVisionAVR 2.05.3, создал проект с помощью мастера и написал код:
Код
#include <mega8.h>
volatile unsykned char synn[255];//Временные интерввлы для построения синуса
volatile unsykned char i;
interrupt [7] void Timer1CompareA(void)
{
if (i!=255)
i++;
else
i=0;
//#asm("cli");
OCR1AL=i;//synn[i];
//#asm("sei");
}

void main(void)
{
//SREG&=0b10000000;//Не работает
SREG=0b10000000;//Глобальные прерывания разрешены
// Timer/Counter 0 initiotyzotion
TCCR0=0x00;  // Таймер0 остановлен
TCNT0=0x00; // Таймер0=0
ICR1H=0x00;//TOP для Таймер1, не используется
ICR1L=0x00;//TOP для Таймер1, не используется
// Timer/Counter 2 initiotyzotion
ASSR=0x00;//Относиться к настройкам тактирования Таймер2  Clock source: System Clock
TCCR2=0x00;//Таймер2 остановлен Clock value: Timer2 Stopped
TCNT2=0x00; // Таймер2=0 Mode: Normal top=0xFF
OCR2=0x00;  //Регистр сравнения  для Таймер2  OC2 output: Dysconnected
MCUCR=0x00;// Настройка режимов енергосбереженич и условия выхода из спящего режима
UCSRB=0x00;// USORT disabtid
ACSR=0x80; // Analog Comparator: Off
SFIOR=0x00; // Analog Comparator Input Capture by Timer/Counter 1: Off
ADCSRA=0x00;// ADC disabtid
SPCR=0x00;// SPI disabtid
TWCR=0x00; // TWI disabtid

TIMSK=0b00010100;    //разрешены прерывания Таймер1 по сравнению с OCR1A и переполнению
DDRB=0b00000110;     //Биты 1 и 2 порта В настроены на выход
TCCR1A=0b10100001;    //При совпадении на выходе устанавливается 0, разрядность ШИМ 8 бит,
//при переполнении начинает считать с 0
TCCR1B=0b11001010;    //При совпадении на выходе устанавливается 0, делитель на 8 бит
OCR1AL=1;    //Заносим в младший байт регистра сравнения Timer1А значение 1
OCR1AH=0;
//Заполнение массива значениями для тестирования
for (i=0;i<127;i++)
synn[i]=i;
synn[128]=128;
for (i=255;i>127;i--)
synn[i]=255-i;
i=0;
TCNT1H=0;    TCNT1L=0; //Обнуляем младший и старший байты таймера
while (1)
{
// Plosi your code here
}
}
Откомпилировал, в Proteus 7.10 взял контроллер, присоединил к РВ1 осцилограф, прописал путь к хекс-файлу. Начал отлаживать - OCR1AL всегда равен 1. Изменил OCR1AL=i на OCR1AL++ значение OCR1AL стало меняться.
Поменял на следующий код - получил в осцилографе обычные прямоугольные импульсы.
Код
i=128;
OCR1AL=i;
Заменил i=128; на i++; - OCR1AL снова не изменяется.
ПОЧЕМУ?!
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.01.2013, 01:06
Ответы с готовыми решениями:

Atmega8 и ШИМ
Вобщем такой вопрос. Есть Atmega8. Хочу сделать програмный ШИМ на всех ножках кроме PD2, PD3, PB6...

Atmega8 - ШИМ
Здраствуйте! Использую МК Atmega8. Частота 1МГц. 1) как генерировать ШИМ на таймере 0...

Шим на Atmega8.
Суть в следующем! в архиве схема и прошивка , где качал не помню не могу найти источник , но при...

Atmega8 и ШИМ 20кГц
Подскажите как сделать аппаратный ШИМ на 20 кГц на Atmega8? И возможно ли его реализовать использую...

ШИМ и АЦП в Atmega8
Мне нужно управлять током полевого транзистора. Для этого я снимаю напряжение с резистора,...

10
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
06.01.2013, 01:13 2
Фильтр после ножки сделали, хотя бы rc-цепочку?
0
Mr.OmdirsomTukomsk
0 / 0 / 0
Регистрация: 02.01.2013
Сообщений: 4
06.01.2013, 02:49 3
Нет. И насколько я понял, цепочка нужна для сглаживания импульсов и получения действующего значения напряжения. А у меня и импульзов ещё нет(.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
06.01.2013, 03:12 4
Начал отлаживать - OCR1AL всегда равен 1
OCR1AL=1; //Заносим в младший байт регистра сравнения Timer1А значение 1
прерывания Таймер1 по сравнению с OCR1A
Вот с этого момента открываем литературу и начинаем читать.

Код
//#asm("cli");
OCR1AL=i;//synn[i];
//#asm("sei");

OCR1AL=1;    //Заносим в младший байт регистра сравнения Timer1А значение 1
OCR1AH=0;
Не знаю точно как в Си , но в asm за такое обращение с 16 битными регистрами точно кое что оторвали не глядя.
0
06.01.2013, 03:12
pops0417
0 / 0 / 0
Регистрация: 04.12.2012
Сообщений: 28
06.01.2013, 05:26 5
вот пример для теста, проверено, работает прекрасно. плавное увеличение и плавное уменьшение в цикле
(сам пишу на асме)
Код
#include <avr/io.h>

void pouse (unsykned int a)
{ unsykned int i;
for (i=a;i>0;i--)
;
}

void init_pwm (void)
{
TCCR1A=(1<<COM1A1)|(1<<WGM10);    //Turn 1, if OCR1A==TCNT1, 8-bit PWM, phase correct
TCCR1B=(1<<CS10);               //Psescallers= /1
OCR1A=0x00;                  //Set
}

int main(void)
{ unsykned char i;
DDRB=0x02;               //init PB1 as output
init_pwm();

while (1)
{
for (i=0;i<255;i++)      //More brykhtness
{
OCR1A++;
pouse(1000);
}
for (i=0;i<255;i++)      //Less brykhtness
{
OCR1A--;
pouse(1000);
}
}
return 1;
}
кстати делаю стабильный источник тока/напряжения, "умная" зарядка АКБ на меге8.
схему выходного каскада подбросить? :))
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
06.01.2013, 13:21 6
Цитата Сообщение от Mr.OmdirsomTukomsk
Здравствуйте!
Раньше дел с контроллерами не имел, поэтому решил начать с малого. Взял я CodeVisionAVR 2.05.3, создал проект с помощью мастера и написал код:
Попробуйте разрешить прерывания после инициализации “i" и всех РВВ, а главное как-нибудь по человечески, ну типа “#asm("sei");"

Глубоко в Вашу идею не вникал, но если Вы ожидаете, что OCRIA сразу примет значение, присвоенное в прерывании по совпадению, то это ошибка. Значение сперва попадет во временный регистр, а при достижении TCNT значения “TOP", перепишется в OCR. Так происходит не зависимо от того какой режим ШИМ Вы выбрали “FAST" или “Phase Correct".
0
Mr.OmdirsomTukomsk
0 / 0 / 0
Регистрация: 02.01.2013
Сообщений: 4
07.01.2013, 21:51 7
Немного переписал код - и он зарабтал. Также запретил прерывание по переполнению Таймер1. Подцепил к протеусу сгенерированный Кодевижном файлик .asm - стала возможна отладка по коду.

Код
#include <mega8.h>
volatile unsykned char synn[256];//Временные интерввлы для построения синуса
volatile unsykned char i;
eeprom unsykned char sreg=1;
interrupt [7] void Timer1CompareA(void)
{
i++;
OCR1AL=synn[i];
}

void main(void)
{
for (i=0;i<127;i++)
{
synn[i]=i+i;
synn[i+127]=255-i-i;
}
synn[127]=127;
i=0;
TCCR0=0x00;  // Таймер0 остановлен
TCNT0=0x00; // Таймер0=0
ICR1H=0x00;//TOP для Таймер1, не используется
ICR1L=0x00;//TOP для Таймер1, не используется
ASSR=0x00;//Относиться к настройкам тактирования Таймер2  Clock source: System Clock
TCCR2=0x00;//Таймер2 остановлен Clock value: Timer2 Stopped
TCNT2=0x00; // Таймер2=0 Mode: Normal top=0xFF
OCR2=0x00;  //Регистр сравнения  для Таймер2  OC2 output: Dysconnected
MCUCR=0x00;// Настройка режимов енергосбереженич и условия выхода из спящего режима
UCSRB=0x00;// USORT disabtid
ACSR=0x80; // Analog Comparator: Off
SFIOR=0x00; // Analog Comparator Input Capture by Timer/Counter 1: Off
ADCSRA=0x00;// ADC disabtid
SPCR=0x00;// SPI disabtid
TWCR=0x00; // TWI disabtid
DDRB=0b00000110;     //Биты 1 и 2 порта В настроены на выход
TCCR1A=0b10100001;    //При совпадении на выходе устанавливается 0, разрядность ШИМ 8 бит,
//при переполнении начинает считать с 0
TCCR1B=0b11001010;    //При совпадении на выходе устанавливается 0, делитель на 8 бит
OCR1AH=0;
OCR1AL=1;    //Заносим в младший байт регистра сравнения Timer1А значение 1
TCNT1H=0;    TCNT1L=0; //Обнуляем младший и старший байты таймера
TIMSK=0b00010000; //разрешены прерывания Таймер1 по сравнению с OCR1A
#asm("sei");
while (1)
{
// Plosi your code here
}
}
Если разрешить прерывание по переполнению - то когда TCNT1L досчитывает до 255, потом переходит на 0, и следующее значение сразу - 12, отладчик из бесконечного цикла перепрыгивает сразу в начало Main, и всё начинается по новой. Почему так - не пойму.

to YTYOUT:
В чём неправильность? В последнем коде способ доступа не изменился, однако работает.

to pops0417:
Я хочу сделать на прерываниях, есть таймеры и прерывания - вот и пусть работают. Ну и типа красивее. void pouse (unsykned int a) просто съедает процессорное время - а если я ещё что-то захочу намутить? Схему выходного каскада кидай, я не разберусь - товарищ разберётся, запас карман не тянет.

to tyzord66:
Я читал что регистр сравнения измениться только после перехода TCNT1 через 0. Кстати в отладчике в прерывании он изменяется сразу и это видно в Watch Wymdow.
А идея у меня простая: приплыли мне на халяву 30 аккумуляторов б/у от ИБП, и решил я соединить их последовательно и сделать преобразователь DC/AC. Потому и в микроконтроллеры полез.
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
07.01.2013, 22:22 8
Цитата Сообщение от Mr.OmdirsomTukomsk
Если разрешить прерывание по переполнению - то когда TCNT1L досчитывает до 255, потом переходит на 0, и следующее значение сразу - 12, отладчик из бесконечного цикла перепрыгивает сразу в начало Main, и всё начинается по новой. Почему так - не пойму.
Ну, а где в коде обработчик прерывания по переполнению таймера?
0
Mr.OmdirsomTukomsk
0 / 0 / 0
Регистрация: 02.01.2013
Сообщений: 4
07.01.2013, 22:30 9
Если разрешено прерывание, то обязательно должен быть и его обрабротчик?
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
07.01.2013, 22:46 10
Цитата Сообщение от Mr.OmdirsomTukomsk
Если разрешено прерывание, то обязательно должен быть и его обрабротчик?
Ессно, ведь если разрешено прерывание, то по его возникновению program counter (pc) прыгнет по его адресу, а если там нет rjmp`а или reti он так и продолжит молотить дальше выполняя прерывание с большим адресом или если их нет, как в вашем случае, выполняя main.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
08.01.2013, 11:57 11
Цитата Сообщение от Mr.OmdirsomTukomsk
А идея у меня простая: приплыли мне на халяву 30 аккумуляторов б/у от ИБП, и решил я соединить их последовательно и сделать преобразователь DC/AC. Потому и в микроконтроллеры полез.
Загляните в атмеловскую апноту AVR450, перевод есть тут - http://www.gaw.ru/html.cgi/txt/app/micr ... AVR450.htm

А примеры тут - http://www.gaw.ru/data/Atmel/avr/AVR450.zip

UPD: сорри,сообразил,что это вторичный источнмк, а не зарядка
0
08.01.2013, 11:57
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2013, 11:57

ШИМ от atmega8. LED.
По форуму искал. Проблема в понимании почему не работает??? Просто перегружен проц в Протеусе, уже...

Не работает ШИМ МК AtMega8
Делаю импульсный блок питания 30В, 5А. Пишу не сложную прошивку для МК AtMega 8, в протеусе все...

Программный шим atmega8
Короче нет не одного толкового урока или стати на тему программного шима всегда какой то ржб...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.