Вт янв 22, 2013 13:33:52
Ср янв 23, 2013 19:00:25
phanis писал(а):Еще для управления можно использовать (транзистор + диодный мост).
clawham писал(а):дык синхронизация тож ручная....развертка аналогично ну если не хочет не надо и не будет он заниматься измерениями экстрасенсы тут увы.....уехали....
Ср янв 23, 2013 23:29:47
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TTT_PIN = 1;
GIFR|=(1<<6); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<6);
OCR1A = procent;
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TTT_PIN = 1;
GIFR|=(1<<6); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<6);
OCR1A = procent;
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
TTT_PIN = 0;
}
Чт янв 24, 2013 12:49:34
Чт янв 24, 2013 13:38:25
ldi r16,200
loop_no_zero:
dec r16
brne loop_no_zero
Чт янв 24, 2013 14:51:52
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
// сюда попадаем, когда таймер досчитал до OCR0A
// формируем импульс включения симистора, равный одному периоду входной частоты таймера - примерно 50 мкс
//PORTB.4 = 1; // для отладки
if(PINB.3)
{
// импульс ещё не начал формироваться
PORTB.3 = 0; // начинаем формировать импульс включения симистора
PORTB.0 = 1; // начинаем формировать импульс ШИМ
OCR0A++; // увеличиваем OCR0A на единицу, чтобы попасть в это же самое прерывание на следующем такте
// таймера. В дальнейшем, прежнее значение OCR0A восстанавливать не надо, т.к. оно задаётся
// в начале каждого полупериода
}
else
{
// импульс включения симистора уже формируется
PORTB.3 = 1; // закончили формировать
}
//PORTB.4 = 0; // для отладки
}
Чт янв 24, 2013 15:55:20
Чт янв 24, 2013 18:44:41
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TTT_PIN = 1;
GIFR|=(1<<6); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<6);
OCR1A = procent;
#asm
ldi r16,200
loop_no_zero:
dec r16
brne loop_no_zero
#endasm
TTT_PIN = 0;
}
Пт янв 25, 2013 09:30:19
Сб янв 26, 2013 13:59:10
Барсик писал(а):..Исходник к схеме download/file.php?id=133950 в прикошаченном файле. .....
clawham писал(а):у Вас уже есть 12 тактов прерывания .... надбавьте ещё 32-12 НОПа и хватит....использовать вставки очень опасно!!! компилятор не сохраняет использованный Вами регистр ибо он не используется в прерывании(Сишной его части) - потому если где-то в программе он будет использоваться и тут произойдёт прерывание - вы его запортите! да и не нужно этого....Вам не 2000 тактов надо пропустить...всего 20....
interrupt [EXT_INT0] void ext_int0_isr(void)
{
OCR1A = procent;
OCR1B = procent+60;
TCNT1 = 0; // сбросили таймер
GICR&=~(1<<6); // запретили прерывание INT0 // GIFR = 0x10000000
}
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 10.10.2010
Author :
Company :
Comments:
Chip type : ATmega8
Program type : Application
Clock frequency : 16,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
#include <spi.h>
#include <string.h>
#include <stdio.h>
#include <ds1307_twi.h>
#include <bcd.h>
#include <lcd.c>
#define delay_ 30 // плавность включения
#define TRIAC_PIN PORTD.4 // пин управления симистором
#define power_x 25 // координаты расположения мощности
#define power_y 40 // на дисплее
int status = 0; // текущее значение яркости
unsigned int tick = 0; //счетчик тиков таймера
unsigned char b_cnt = 0; //счетчик принятых бит
bit start_cond = 0; //флаг стартового условия
bit start_triac_timer = 0;
volatile unsigned char addr_1 = 0; //прямой байт адреса
volatile unsigned char addr_0 = 0; //инверсный байт адреса
volatile unsigned char cmd_1 = 0; //прямой байт команды
volatile unsigned char cmd_0 = 0; //инверсный байт команды
volatile unsigned char cmd = 0; //байт команды
unsigned char hour,min,sec; //часы, минуты, секунды
unsigned char day,month,year; //день, месяц, год
char cnt[]; // промежуточная переменная для функции sprint()
long int count_RTC = 0;
// строки для примера
//char txt1[]="19:42";
// Таблица задержек для 16-тибитного таймера
flash const unsigned int nagruzka[99] = {
20324, // 1% нагрузки
19794, // 2% нагрузки
19384, // 3% нагрузки
19036,18728,18450,18190,17948,17720,17504,17296,17096,16904,16718,16536,16360,16188,16022,15858,15696,
15538,15384,15232,15082,14934,14788,14644,14500,14360,14220,14082,13944,13808,13674,13540,13406,13274,13142,
13012,12882,12752,12622,12494,12366,12238,12110,11982,11854,11728,11600,11472,11346,11218,11090,10962,10834,
10706,10578,10448,10318,10188,10058,9926,9794,9660,9526,9392,9256,9118,8980,8840,8700,8556,8412,8266,8118,
7968,7816,7662,7504,7342,7178,7012,6840,6664,6482,6296,6104,5904,5696,5480,5252,5010,4750,4472,4164,
3816, // 97% нагрузки
3406, // 98% нагрузки
2876 // 99% нагрузки
};
// External Interrupt 0 service routine
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if (start_triac_timer == 1) {
OCR1A = nagruzka[status];
OCR1B = nagruzka[status]+60;
TCNT1 = 0; // сбросили таймер
TCCR1B=0x02;
GICR&=~(1<<6); // запретили прерывание INT0 // GIFR = 0x10000000
}
else {
TCCR1B=0x00;
}
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
TCNT0=0xFA; // запускаем таймер на 96 мкс
TCCR0=0x04; // частота таймера 62.500 кГц
if (tick >= 90 && tick < 98) //если прошло от 8,64 мс до 9,408 мс
{
start_cond = 1; //фиксируем стартовое условие
addr_1 = addr_0 = cmd_1 = cmd_0 = 0; //обнуляем ранее полученную команду и адрес
}
if (tick >= 20 && tick < 27 && start_cond) //если прошло от 1,92 мс до 2,592 мс
{
b_cnt++; //приняли "1" и увеличили счетчик битов
if (b_cnt < 9) addr_1 = (addr_1 << 1) + 1; //первый байт - прямой адрес
if (b_cnt >= 9 && b_cnt < 17) addr_0 = (addr_0 << 1) + 1; //второй байт - инверсный адрес
if (b_cnt >= 16 && b_cnt < 25) cmd_1 = (cmd_1 << 1) + 1; //третий байт - прямая команда
if (b_cnt >= 24) cmd_0 = (cmd_0 << 1) + 1; //четвертый байт - инверсная команда
}
if (tick >= 9 && tick < 16 && start_cond) //если прошло от 0,864 мс до 1,536 мс
{
b_cnt++; //приняли "0" и увеличили счетчик битов
if (b_cnt < 9) addr_1 = (addr_1 << 1); //далее - аналогично по байтам
if (b_cnt >= 9 && b_cnt < 17) addr_0 = (addr_0 << 1);
if (b_cnt >= 16 && b_cnt < 25) cmd_1 = (cmd_1 << 1);
if (b_cnt >= 24) cmd_0 = (cmd_0 << 1);
}
tick = 0; //обнулили тики
if (b_cnt == 32) //если приняли уже 4 байта
{
// if ((addr_1+addr_0) == 0xFF) addr = addr_0; //закомментировано, потому что нам
// else addr = 0; //необходима только команда
if ((cmd_1 + cmd_0) == 0xFF) { //проверили правильность приема команды
cmd = cmd_1;
b_cnt = 0; //обнулили счетчик битов
start_cond = 0; //сбросили стартовое условие
}
else {
cmd = 0;
b_cnt = 0; //обнулили счетчик битов
start_cond = 0; //сбросили стартовое условие
TCCR0=0x00; //остановили таймер
TCNT0=0x00;
}
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xFA; //переинициировали таймер - отсчитывает 96 мкс
tick++; //увеличили число тиков
if (tick > 500) { //если прошло более 48 мс
TCCR0=0x00; //сбросили все к исходному состоянию
TCNT0=0x00;
tick = 0;
start_cond = 0;
cmd = 0;
}
}
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TRIAC_PIN = 0; // открыли симистор
}
// Timer 1 output compare B interrupt service routine
interrupt [TIM1_COMPB] void timer1_compb_isr(void)
{
TRIAC_PIN = 1; // вернулись в режим ожидания
GIFR|=(1<<6); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<6); // разрешаем прерывание INT0.
}
/*===== ФУНКЦИЯ ПЛАВНОГО ВКЛЮЧЕНИЯ =======*/
void soft_on () {
TCCR1B=0x02;
while (status<98) {
status++;
delay_ms(delay_);
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
};
status = 98;
TCCR1B=0x00;
TRIAC_PIN = 0; // полностью включили
}
/*============ ФУНКЦИЯ ПЛАВНОГО ВЫКЛЮЧЕНИЯ С ТЕКУЩЕЙ ЯРКОСТИ =================*/
void soft_off () {
TCCR1B=0x02;
while (status>0) {
status--;
delay_ms(delay_);
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
}
status = 0;
TCCR1B=0x00;
TRIAC_PIN = 1; // полностью выключили
}
/*======= ВКЛЮЧЕНИЕ ЧАСОВ DS1307 ========*/
void DS1307_on () {
unsigned char tmp;
tmp = rtc_read(0x00);
tmp &=~(1<<7);
rtc_write(0x00, tmp); //включение DS1307, бит 7 ноль
tmp = rtc_read(0x02);
tmp &=~(1<<6);
rtc_write(0x02, tmp); // бит 6 ноль - 24ох часовой режим
}
void main(void)
{
// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0xFF;
// Port C initialization
// Func6=Out Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out
// State6=0 State5=T State4=T State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0x4F;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=1 State3=P State2=P State1=T State0=T
PORTD=0x1C;
DDRD=0x10;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: On
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=0xC0;
MCUCR=0x0A;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x19;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2*4000,000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x50;
SPSR=0x01;
// 2 Wire Bus initialization
// Generate Acknowledge Pulse: On
// 2 Wire Bus Slave Address: 68h
// General Call Recognition: Off
// Bit Rate: 100,000 kHz
TWSR=0x00;
TWBR=0x48;
TWAR=0xD0;
TWCR=0x44;
// Global enable interrupts
#asm("sei")
LCD_init();
fill_screen(bgcolor);
//rtc_write(0x02,rtc_read(0x02)&~0x40); // установили 24 часовой формат (бит 6 регистра 0х02 равен 0)
//rtc_write(0x00,rtc_read(0x00)&~0x80); // включили часы (бит 7 регистра 0х00 ранен 0)
DS1307_on ();
rtc_init (0,0,0);
//rtc_set_time (bin2bcd(20),bin2bcd(47),bin2bcd(12));
//rtc_set_date (bin2bcd(17),bin2bcd(03),bin2bcd(11));
//put_string(50, 0,txt1, 0xF800, 2);
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
while (1)
{ count_RTC++;
/*==================== РЕАКЦИЯ НА НАЖАТИЕ КЛАВИШ ВЫКЛЮЧАТЕЛЯ ================*/
/*if (PINB.0==0) { // ждем нажатие клавиши выключателя
delay_ms(50); // антидребезг
if (status==0) {
TCCR1B=0x02; // запуск таймера на 2000 кГц
soft_on (98); // плавно от 1% до 99% мощности
TCCR1B=0x00; // остановка таймера ( чтобы не молотил в пустую 200 мкс импульсы на PORTC.5 )
PORTC.5 = 1; // 100%
status = 98;
}
else {
TCCR1B=0x02;
soft_off(status); // плавно выключаем с текущей мощности
TCCR1B=0x00;
PORTC.5 = 0; // 0%
status=0;
};
}*/
/*if (PINB.5==0) { // вкл/выкл основного света
// реле вкл/выкл
}*/
/*===== УВЕЛИЧЕНИЕ/УМЕНЬШЕНИЕ ЯРКОСТИ =====================*/
if (cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
TCCR1B=0x02;
status++;
if (status > 97) {
TCCR1B=0x00;
status = 98;
TRIAC_PIN = 0; // полностью включили
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
}
else {
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
delay_ms(delay_);
}
}
if (cmd == 0b11000000) { // кнопка "Sleep" - уменьшение яркости
TCCR1B=0x02;
status--;
if (status < 1) {
status = 0; // чтобы не уйти в минус
TCCR1B=0x00;
TRIAC_PIN = 1; // полностью выключили
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
}
else {
sprintf(cnt,"%u",status); // преобразование "яркости" в строку
put_string(power_x, power_y,cnt, 0x07E0, 3); // выводим на экран
delay_ms(delay_);
}
}
/*=================== ВКЛЮЧЕНИЕ/ВЫКЛЮЧЕНИЕ С ПУЛЬТА ====*/
if (cmd == 0b11011000) { // кнопка "TV" - вкл/выкл диммера
GICR&=~(1<<7); // запретили прерывание INT1 (от TSOP) // GIFR = 0x01000000
if (status == 0) {
soft_on (); // 100% мощности
}
else {
soft_off(); // плавно выключаем
};
GIFR|=(1<<7); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<7); // разрешаем прерывание INT1
}
if (cmd == 0b10000000) { // кнопка "VIDEO" - вкл/выкл основного света
// реле вкл/выкл
LCD_PowerOff ();
}
if (count_RTC > 100000) { // чтобы не опрашивать DS1307 слишком часто
count_RTC = 0;
rtc_get_time(&hour,&min,&sec); //считать время
rtc_get_date(&day,&month,&year); //считать дату
sec = bcd2bin(sec);
min = bcd2bin(min);
hour = bcd2bin(hour);
day = bcd2bin(day);
month = bcd2bin(month);
year = bcd2bin(year);
sprintf(cnt,"%02u:%02u:%02u",hour,min,sec);
put_string(10, 10,cnt, 0x07E0, 1);
sprintf(cnt,"%02u.%02u.20%02u",day,month,year);
put_string(10, 100,cnt, 0x07E0, 1);
}
};
}
Сб янв 26, 2013 15:01:05
Вс янв 27, 2013 16:33:47
Работает так. По прерыванию в начале каждого полупериода сетевого напряжения, запускается таймер. Как только таймер досчитает до OCR0A, включается симистор.takei писал(а):Барсик прошу прощения что оставил ваш пост без внимания, с интересом попытался разобраться , но там хоть и откомментирована каждая строка, я не смог вникнуть в структуру программы.
Вс янв 27, 2013 17:56:24
takei писал(а):Вот первый результат по программе
Выход PD0 , прицепил светодиод, яркость меняется, значится схема получается живая...
Далее МОС3052+ВТ136, лампа горит во весь накал, при уменьшении периода синусоиды кнопкой минус
Вс янв 27, 2013 17:58:13
clawham писал(а): я закупился BTA24-600CWRG - 25 ампер 600 вольт, Изолированная подложка!!!!!
Вс янв 27, 2013 20:59:56
Да действительно,слышал такое: чтобы использовать регистры во вставках есть функция блокировки регистров, но они получается выпадают из работы компилятора и оптимизатора.clawham писал(а):не путайте пожалуйста милли и МИКРО секунды!!!
.............
надбавьте ещё 32-12 НОПа и хватит....использовать вставки очень опасно!!! компилятор не сохраняет использованный Вами регистр ибо он не используется в прерывании(Сишной его части) - потому если где-то в программе он будет использоваться и тут произойдёт прерывание - вы его запортите! да и не нужно этого....Вам не 2000 тактов надо пропустить...всего 20....
Определенно есть и этоtakei писал(а):Только, наверное 70 это сильно, может есть метод задать эти 21 mS программно в цифровом значении?
Спасибо.
delay_us(21);
Пн янв 28, 2013 20:01:26
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if ( каким тут воспользоватся условием????? ) {
TTT_PIN = 1;
GIFR|=(1<<6); // сбросили флаг прерывания - Флаг сбрасывается ЕДИНИЦЕЙ
GICR|=(1<<6);
OCR1A = procent;
#asm("nop"); // все элементарно просто спасибо clawham
delay_us(19); // опять все просто, спасибо vitalik_1984
TTT_PIN = 0;
}
else {
OCR1A = 0; //???????????????
TTT_PIN = 0; //??????????????
};
}
Пн янв 28, 2013 22:27:26
Пн янв 28, 2013 22:48:08
Пн янв 28, 2013 22:51:26
Вт янв 29, 2013 08:04:37
как я это прочел:clawham писал(а):а что такое /4?
Это сдвиг влево на 2 разряда!
вот и пишите 1024<<2
Если не знаете, зачем тогда вообще направление сдвига говорить?clawham писал(а):а нам надо деление ... то вправо... ж не знаю что у него во чно преобразовывается