роботы робототехника микроконтроллеры


 Страниц (5): « 1 [2] 3 4 5 »   

> Описание: не могу заставить что бы одновременно шим увеличивался и моргали фары
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



nest пишет:
Demckiy пишет:
работает только одно ШИМ или управления портами
это как ?


Я не знаю как объяснить, это надо смоделировать в протеусе ...там сразу видно....
 
 Top
nest Администратор Post Id



Администратор


Сообщений всего: 4866
Дата рег-ции: Сент. 2009  



Demckiy пишет:
Я не знаю как объяснить
что то типа:
сначала это запускается и меняется, а потом делается так. а всё это время происходит вот это, но только если сделать тут.
 
 Top
ОЛЕГ Супермодератор Post Id



Супермодератор


Сообщений всего: 1732
Дата рег-ции: Нояб. 2008  



Могу предположить, что в случае с лампами накаливания можно обойтись без ШИМ одними только задержками delay.
 
 Top
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



Начну все сначала.С начала настроим таймер...

void Timer0_Init(void)
{
/* биты регистра:
COM0A1 COM0A0 COM0B1 COM0B0 Reserved Reserved WGM01 WGM00 */
TCCR0A=0b10000011;

/* биты регистра:
FOC0A FOC0B Reserved Reserved WGM02 CS02 CS01 CS00 */
TCCR0B=0b00000001;

TCNT0=0b00010000;

OCR0A=0b11111111;

OCR0B=0b00000000;

/* биты регистра:
TOIE1 OCIE1A OCIE1B Reserved ICIE1 OCIE0B TOIE0 OCIE0A */
TIMSK=0b00000011;
}

Посмотрите таймер правильно настроен??? И зачем в TCNT0 записано 0b00010000;

в OCR0A записано 0b11111111;
 
 Top
nest Администратор Post Id



Администратор


Сообщений всего: 4866
Дата рег-ции: Сент. 2009  



Demckiy пишет:
И зачем в TCNT0 записано 0b00010000;
в OCR0A записано 0b11111111;
посмотрите в даташите, за то отвечают эти регистры в МК
 
 Top
mihail Post Id



Гуру


Сообщений всего: 1065
Дата рег-ции: Март 2010  



Demckiy пишет:
Начну все сначала.С начала настроим таймер.
Это не начало. Даже не середина.

Сначала необходимо определиться с целью.
Улучшение освещения салона автомобиля
Затем сформулировать задачу.
При открывании/закрывании двери включать свет. По истечении нескольких секунд плавно выключить свет.
Составить алгоритм.
При изменении состояние кнопки.
Включить свет.
Подождать (8 секунд).
Плавно выключить свет (4 секунды).

Определиться с необходимыми для решения задачи ресурсами.
Изменение состояния кнопки можно отслеживать внешним прерыванием.
Длительную задержку можно реализовать на 16 разрядном таймере/счетчике.
Плавно выключить свет с помощью ШИМ на 8 разрядном таймере/счетчике.

Подобрать удовлетворяющий всем требованиям микроконтроллер.
У ATmega8 есть все что нужно и даже больше.
Выполнить расчеты
Расчеты
Написать программу
код
Тестирование программы
исправление ошибок
Изготовление устройства
Травить, паять и тд тп
Тестирование устройства
исправление ошибок
(Добавление)
Бонус. Программа реализующая вышеизложенный алгоритм.
/*******************************************
Program :
Compiler : WinAVR
Chip type : ATmega8
System Clock : 8 MHz
*******************************************/


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


// External Interrupt 0 service routine
ISR(INT0_vect)
{
TCCR2 = 0b00000000; // stop Timer/Counter 2

TCNT1 = 0;
TCCR1B = 0b00000101; // start Timer/Counter 1

PORTB |= 0b00000001; // LED on
}


// Timer 1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
TCNT2 = 0;
OCR2 = 15;
TCCR2 = 0b00000111; // start Timer/Counter 2

TCCR1B = 0b00000000; // stop Timer/Counter 1
}


// Timer 2 overflow interrupt service routine
ISR(TIMER2_OVF_vect)
{
PORTB &= 0b11111110; // LED off
OCR2 += 2;

if( OCR2 > 240 )
{
TCCR2 = 0b00000000; // stop Timer/Counter 2
}
}


// Timer2 output compare interrupt service routine
ISR(TIMER2_COMP_vect)
{
PORTB |= 0b00000001; // LED on
}


int main(void)
{
// Input/Output Ports initialization

// Port B initialization
DDRB = 0b00000001; // PB0 LED
PORTB = 0b00000000;


// Port C initialization
DDRC = 0b00000000;
PORTC = 0b00000000;


// Port D initialization
DDRD = 0b00000000; // PD2 button
PORTD = 0b00000100;


// Timer/Counter 1 initialization

// bits: COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
TCCR1A = 0b00000000;

// bits: ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
TCCR1B = 0b00000000;

TCNT1 = 0;


// Timer/Counter 2 initialization

// bits: - - - - AS2 TCN2UB OCR2UB TCR2UB
ASSR = 0b00000000;

// bits: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
TCCR2 = 0b00000000;

TCNT2 = 0;

OCR2 = 15;


// Timer(s)/Counter(s) Interrupt(s) initialization

// bits: OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 - TOIE0
TIMSK = 0b11000100;


// External Interrupt(s) initialization

// bits: SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00
MCUCR = 0b00000001;

// bits: INT1 INT0 - - - - IVSEL IVCE
GICR = 0b01000000;

// bits: INTF1 INTF0 - - - - - -
GIFR = 0b01000000;


// Global enable interrupts
sei();


while (1)
{

}

return 0;
}

(Отредактировано автором: 10 Января, 2011 - 23:42:17)

 
 Top
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



CODE:
[quote=mihail]/*******************************************
Program :
Compiler : WinAVR
Chip type : ATmega8
System Clock : 8 MHz
*******************************************/


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


// External Interrupt 0 service routine
ISR(INT0_vect)
{
TCCR2 = 0b00000000; // stop Timer/Counter 2

TCNT1 = 0;
TCCR1B = 0b00000101; // start Timer/Counter 1

PORTB |= 0b00000001; // LED on
}


// Timer 1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
TCNT2 = 0;
OCR2 = 15;
TCCR2 = 0b00000111; // start Timer/Counter 2

TCCR1B = 0b00000000; // stop Timer/Counter 1
}


// Timer 2 overflow interrupt service routine
ISR(TIMER2_OVF_vect)
{
PORTB &= 0b11111110; // LED off
OCR2 += 2;

if( OCR2 > 240 )
{
TCCR2 = 0b00000000; // stop Timer/Counter 2
}
}


// Timer2 output compare interrupt service routine
ISR(TIMER2_COMP_vect)
{
PORTB |= 0b00000001; // LED on
}


int main(void)
{
// Input/Output Ports initialization

// Port B initialization
DDRB = 0b00000001; // PB0 LED
PORTB = 0b00000000;


// Port C initialization
DDRC = 0b00000000;
PORTC = 0b00000000;


// Port D initialization
DDRD = 0b00000000; // PD2 button
PORTD = 0b00000100;


// Timer/Counter 1 initialization

// bits: COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
TCCR1A = 0b00000000;

// bits: ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
TCCR1B = 0b00000000;

TCNT1 = 0;


// Timer/Counter 2 initialization

// bits: - - - - AS2 TCN2UB OCR2UB TCR2UB
ASSR = 0b00000000;

// bits: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
TCCR2 = 0b00000000;

TCNT2 = 0;

OCR2 = 15;


// Timer(s)/Counter(s) Interrupt(s) initialization

// bits: OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 - TOIE0
TIMSK = 0b11000100;


// External Interrupt(s) initialization

// bits: SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00
MCUCR = 0b00000001;

// bits: INT1 INT0 - - - - IVSEL IVCE
GICR = 0b01000000;

// bits: INTF1 INTF0 - - - - - -
GIFR = 0b01000000;


// Global enable interrupts
sei();


while (1)
{

}

return 0;
}[/quote]


Спасибо за код, но c WinAVR не знаком, работаю с CVAVR. Не могли бы написать для CVAVR и с комментариями!!??

Заранее спасибо.

(Отредактировано автором: 15 Января, 2011 - 09:54:22)

 
 Top
mihail Post Id



Гуру


Сообщений всего: 1065
Дата рег-ции: Март 2010  



/*******************************************
Program :
Compiler : CVAVR
Chip type : ATmega8
System Clock : 8 MHz
*******************************************/

#include <mega8.h>

/* обработчик прерывания по внешнему сигналу на INT0 */
interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCCR2 = 0b00000000; /* остановка таймера/счетчика 2 */

TCNT1 = 0; /* обнуление счетного регистра таймера/счетчика 1 */
TCCR1B = 0b00000101; /* запуск таймера/счетчика 1 с предделителем 1024 */

PORTB |= 0b00000001; /* установить 1 на PB0, включение светодиода */
}


/* обработчик прерывания по переполнению таймера/счетчика 1 */
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCNT2 = 0; /* обнуление счетного регистра таймера/счетчика 2 */
OCR2 = 15; /* запись начального значения в регистр сравнения таймера/счетчика 2 */
TCCR2 = 0b00000111; /* запуск таймера/счетчика 2 с предделителем 1024 */

TCCR1B = 0b00000000; /* остановка таймера/счетчика 1 */
}


/* обработчик прерывания по переполнению таймера/счетчика 2 */
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
PORTB &= 0b11111110; /* установить 0 на PB0, выключение светодиода */
OCR2 += 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */

if( OCR2 > 240 ) /* если значение регистра сравнения таймера/счетчика 2 больше
240, то ... */
{
TCCR2 = 0b00000000; /* остановка таймера/счетчика 2 */
}
}


/* обработчик прерывания по совпадению таймера/счетчика 2 */
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
PORTB |= 0b00000001; /* установить 1 на PB0, включение светодиода */
}


void main(void)
{
/* инициализация порта B */
DDRB = 0b00000001; /* PB0 светодиод */
PORTB = 0b00000000;


/* инициализация порта C */
DDRC = 0b00000000;
PORTC = 0b00000000;


/* инициализация порта D */
DDRD = 0b00000000; /* PD2 кнопка */
PORTD = 0b00000100;


/* инициализация таймера/счетчика 1 */

/* регистр управления таймером/счетчиком 1 А */
/* биты: COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 */
TCCR1A = 0b00000000;

/* регистр управления таймером/счетчиком 1 В */
/* биты: ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10 */
TCCR1B = 0b00000000;

TCNT1 = 0; /* обнуление счетного регистра таймера/счетчика 1 */


/* инициализация таймера/счетчика 2 */

/* регистр асинхронного режима таймера/счетчика 2 */
/* биты: - - - - AS2 TCN2UB OCR2UB TCR2UB */
ASSR = 0b00000000;

/* регистр управления таймером/счетчиком 2 */
/* биты: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20 */
TCCR2 = 0b00000000;

TCNT2 = 0; /* обнуление счетного регистра таймера/счетчика 2 */

OCR2 = 15; /* запись начального значения в регистр сравнения таймера/счетчика 2 */


/* инициализация прерываний таймеров/счетчиков */

/* биты: OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 - TOIE0 */
TIMSK = 0b11000100; /* разрешены прерывания по переполнению таймера/счетчика
1, по переполнению таймера/счетчика 2 и по совпадению таймера/счетчика 2 */


/* инициализация прерываний по внешнему сигналу */

/* биты: SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00 */
MCUCR = 0b00000001; /* флаг прерывания выставляется при изменении логического
уровня на INT0 */

/* биты: INT1 INT0 - - - - IVSEL IVCE */
GICR = 0b01000000; /* разрешение прерывания INT0 */

/* биты: INTF1 INTF0 - - - - - - */
GIFR = 0b01000000; /* сброс флага INT0 */


/* общее разрешение прерываний */
#asm("sei"Подмигивающий


while (1)
{

}
}

(Отредактировано автором: 15 Января, 2011 - 20:05:00)

 
 Top
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



mihail,ОГРОМНОЕ СПАСИБО...буду разбираться..
 
 Top
cjA Post Id



Генерал


Сообщений всего: 3291
Дата рег-ции: Янв. 2010  



Demckiy
я тоже присоединяюсь
каждая строчка по русски закоментированна я тоже си по содам mihail'a учу/вспоминаю
 
 Top
ОЛЕГ Супермодератор Post Id



Супермодератор


Сообщений всего: 1732
Дата рег-ции: Нояб. 2008  



Михаилу мегареспект!
 
 Top
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



mihail,как сделать что бы При изменении состояние кнопки.

Плавно включить свет (4 секунды).
Подождать (8 секунд).
Плавно выключить свет (4 секунды).

и как Вы в программе задали что бы подождать 8 секунд и плавное выключение на протяжении 4 секунд??? не могли бы объясни как Вы высчитали и записали программно??
 
 Top
mihail Post Id



Гуру


Сообщений всего: 1065
Дата рег-ции: Март 2010  



Тактовая частота микроконтроллера 8000000 Hz. Это значит что за одну секунду источник тактового сигнала микроконтроллера выдает 8 миллионов тактовых сигналов. Из этого следует, что один тактовый сигнал длится (1 / 8000000) секунды.

Если предделитель таймера/счетчика равен 1024, то значения счетного регистра таймера/счетчика изменяется на 1 через 1024 тактовых сигналов микроконтроллера. Значит изменение на 1 происходит за ((1 / 8000000) * 1024) секунды.

16 разрядный таймер/счетчик считает от 0 до 65535. Следовательно переполнение таймера/счетчика произойдет через (((1 / 8000000) * 1024) * 65536) секунды.

Таким образом, получается, что время переполнения таймера = (( 1 / тактовая частота микроконтроллера ) * значение предделителя таймера) * значение счетного регистра таймера.

(((1 / 8000000) * 1024) * 65536) = 8.388608 секунды

За предделитель таймера/счетчика 1 отвечают биты CS22, CS21 и CS20 регистра TCCR1B. Подробная таблица есть в datasheet.

Плавное выключение света выполняется программным ШИМ организованным на таймере/счетчике 2. Расчеты выполняются аналогично. Посмотрите осциллограмму в симуляторе и все станет ясно.

PS Чтобы реализовать Ваш алгоритм необходимо изменить программу. Я думаю, надо ввести переменную состояния. И проверяя ее значение в программе, определять порядок действий.

(Отредактировано автором: 16 Января, 2011 - 02:13:35)

 
 Top
cjA Post Id



Генерал


Сообщений всего: 3291
Дата рег-ции: Янв. 2010  



mihail пишет:
Я думаю, надо ввести переменную состояния

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
я - присоединяюсь! надо!

2 Админ- пожалуйсто не стирайте, это в меммориз! (как жаль что я весь СНГ проболел Грустный )
 
 Top
Demckiy Post Id


Полковник


Сообщений всего: 79
Дата рег-ции: Май 2010  



mihail,зачем мы в OCR2 записали число 15???

(((1/8000000)*1024)*256)=0,03407, вот что получается, а не 4 сек.

И как уменьшается ШИМ, объясните, с приведенным кодом с программы.

Чего лампочка моргает когда ШИМ уменьшается при моделировании в PROTEUS'е ?
Скачать файл: schPWM.zip
Скачан раз: 259
 
 Top
Страниц (5): « 1 [2] 3 4 5 »
« Программирование микроконтроллеров »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown
  Яндекс.Метрика   Рейтинг@Mail.ru