реклама на сайте
подробности

 
 
> Фазовое управление симисторами
Sadmi
сообщение Aug 30 2011, 09:28
Сообщение #1





Группа: Новичок
Сообщений: 9
Регистрация: 30-08-11
Пользователь №: 66 930



Добрый день. Это мой первый опыт программирования на Си вообще и под МК в частности. Прошу сразу не пинать.
Задача стоит такая: организовать управление восемнадцатью лампами накаливания с плавной регулировкой мощности.
После прохода напряжения через ноль счетчик отсчитывает определенное количество тактов (в зависимости от нужной мощности) и на 100 микросекунд (считает второй таймер) включается соответствующий порт.
Использую Atmega32, AVR Studio 5. Написал код, анализирую в AVS Studio, все работает правильно, загоняю в Протеус ничего не работает. Предполагаю, что что-то не так с прерываниями делаю, но что?
Прошу помощи! Спасибо!

CODE
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned long u; // переменная - результат АЦП
volatile unsigned long f; // первый нуль - 1, не первый - 0
/* Таблица задержек */
volatile unsigned char tz[25]={20,30,70,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
// Массив мощностей
volatile unsigned char pch[3][17]={
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, // Номер канала
{0,1,2,4,4,4,4,4,4,4, 4, 4, 4, 4, 4, 4, 4}, // Текущая мощность
{0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0}}; // Флаг установки канала
volatile unsigned char i=0; //
volatile unsigned char t=0;
volatile unsigned char q, fl=0;

/***Обработчик прерываний по окончанию преобразования АЦП***/
ISR (ADC_vect)
{
u = (ADC*11/4);
}

/*** Обработчик прерываний по совпадению таймера ***/
ISR(TIMER0_COMP_vect)
{
//--------------------------------------------------------------------------------------------
for (i=0; i<18; i++) // Перебираем каналы и включаем нужный
{
if (pch[1][i]==t)
{
if (pch[2][i]==0) // Если еще не установлен в текущем периоде
{
pch[2][i]=1;
switch (pch[0][i]) // Определяем линию и порт для установки - 1
{
case 0: PORTD |=1<<0; break;
case 1: PORTD |=1<<1; break;
case 2: PORTD |=1<<2; break;
}
}
}
}
t++;
if (t==25) {t=0;}
OCR0=tz[t]; // Новое значение совпадения

//-------------------------------------------------------------------------------------------
TCNT0=0; //Обнуляем таймер
TCNT2=0; //Обнуляем таймер

}

/***Обработчик прерывания по совпадению таймера (длительность откывающего импульса)***/
ISR(TIMER2_COMP_vect)
{
//Выключаем канал
PORTD=0;
/* switch (t)
{
case 0: PORTD &=~(1<<0); break;
case 1: PORTD &=~(1<<0); break;
case 2: PORTD &=~(1<<2); break;
}
*/ TCNT2=0; //Обнуляем таймер
}

/***Главная функция***/
int main (void)
{
DDRD = 0xFF; // Порт на выход
PORTD = 0x00;

DDRA = 0x00;

/* Настройка АЦП */
ADCSRA = (1 << ADEN) // разрешение работы АЦП
|(1 << ADSC) // запуск преобразования
|(1 << ADATE) // непрерывный режим работы АЦП
|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64
|(1 << ADIE); // разрешение прерывания
ADMUX = (1 << REFS1)|(1 << REFS0) // внутренний ИОН 2,56V
|(0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход (ADC0) PA1

/* Настройка таймера задержки (мощность канала)*/
TCCR0|=(1<<CS00); //
TCCR0|=(0<<CS01); // Установка предделителя (1024)--------------------------------------!!!
TCCR0|=(1<<CS02); //
OCR0=tz[pch[1][t]]; // Установка значения в регистре совпадения.
TCCR0|=(0<<FOC0)|(1<<COM00)|(1<<WGM01);
TIMSK|=(1<<OCIE0); // Разрешить прерывание по совпадению.

/* Настройка таймера (время открывающего импульса 100мкс)*/
TCCR2|=(1<<CS21); //
TCCR2|=(1<<CS20); // Установка предделителя (32)--------------------------------!!!
TCCR2|=(0<<CS20); //
OCR2=50; // Установка значения в регистре совпадения.
TCCR2|=(0<<FOC2)|(1<<COM20)|(1<<WGM21);
TIMSK|=(1<<OCIE2); // Разрешить прерывание по совпадению.

sei(); //глобальное разрешение прерываний

TCNT0=0;
TCNT2=0;

while(1)
{
if (u<20)
{
f++;
}
else
{
f=0;
}

if (f==1) // Обнаружен проход через нуль
{
t=0;
for (q=0; q<18; q++) //обнуляем флаги установки каналов
{
pch[2][q]=0;
}
TCNT0=0;
TCNT2=0;
PORTD |= 1<<3;
}
else
{
PORTD &= ~(1<<3);
}
}
}


Сообщение отредактировал IgorKossak - Aug 30 2011, 17:55
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
kovigor
сообщение Aug 30 2011, 18:31
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(Sadmi @ Aug 30 2011, 12:28) *
Задача стоит такая: организовать управление восемнадцатью лампами накаливания с плавной регулировкой мощности.


Это читали (я имею в виду "Два микроконтроллерных регулятора мощности"):

http://shema.org.ua/index.php?name=News&am...cle&sid=481

?

Сообщение отредактировал kovigor - Aug 30 2011, 18:32
Go to the top of the page
 
+Quote Post
Sadmi
сообщение Aug 31 2011, 03:59
Сообщение #3





Группа: Новичок
Сообщений: 9
Регистрация: 30-08-11
Пользователь №: 66 930



kovigor
Цитата(kovigor @ Aug 30 2011, 22:31) *
Это читали (я имею в виду "Два микроконтроллерных регулятора мощности"):

http://shema.org.ua/index.php?name=News&am...cle&sid=481

?


Спасибо, но там применяется другой принцип регулирования, "выбрасывают" полупериоды сетевого напряжения. А при таком способе заметны мерцания, особенно при низкой мощности.

-SANYCH-
Цитата(-SANYCH- @ Aug 31 2011, 01:10) *
Исходя из данного куска кода PORTD будет постоянно сбрасываться в ноль.
Что включает вот этот кусок кода PORTD |= 1<<3 ?
На какой частоте работает микроконтроллер?


До, порт сбрасывается в ноль, но это происходит один раз в 10 миллисекунд (в начале каждого полупериода).
PORTD |= 1<<3 - включаю третью линию порта D чтобы посмотреть на осциллографе (в протеусе), как срабатывает проход через ноль. Собственно поэтому и сбрасываю PORTD. Но даже, если убрать этот кусок, ничего не изменяется.
Микроконтроллер работает на 16 МГц.

Если отключаю обработку прерываний от нулевого таймера, вижу на осциллографе, на третьей линии PORTD, проход через ноль, иначе вообще никаких сигналов. Может слишком долго в обработчике прерываний ISR(TIMER0_COMP_vect) нахожусь? И это только три канала, а мну нужно будет 17.

Сообщение отредактировал Sadmi - Aug 31 2011, 04:03
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 03:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.02264 секунд с 7
ELECTRONIX ©2004-2016