Форум myROBOT.ru » Шаг за шагом » Программирование микроконтроллеров » стробоскоп на фары автомобиля ....

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

31. ОЛЕГ - 16 Января, 2011 - 15:59:06 - перейти к сообщению
Demckiy пишет:
Чего лампочка моргает когда ШИМ уменьшается при моделировании в PROTEUS'е ?

Нелепо обсуждать многочисленные глюки Протеуса. Замешательство
32. mihail - 16 Января, 2011 - 20:10:57 - перейти к сообщению
Все что касается таймера/счетчика 2 имеет отношение только к ШИМ. В программе это сделано для простоты и лучшего понимания. Все можно было сделать на одном таймере/счетчике.
Demckiy пишет:
зачем мы в OCR2 записали число 15?
Это начальное значение скважности ШИМ.
Demckiy пишет:
(((1/8000000)*1024)*256)=0,03407, вот что получается, а не 4 сек.
Это частота ШИМ.
Demckiy пишет:
И как уменьшается ШИМ, объясните, с приведенным кодом с программы.
ШИМ изменяется так как меняется значение OCR2.
CODE:
OCR2 += 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */


Demckiy пишет:
Чего лампочка моргает когда ШИМ уменьшается при моделировании в PROTEUS'е ?
Тут лучше на реальном устройстве проверять. Если моргания заметны, тогда нужно частоту ШИМ увеличить. Это уже особенности человеческого зрения. В кино, вроде, 24 кадра в секунду и никто не жалуется Улыбка
33. Demckiy - 17 Января, 2011 - 19:18:04 - перейти к сообщению
Объявил переменную stan и присвоил ей 1. Красным цветом выделен добавленный код для организации таких действий:

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

Как указать в какое направления что бы двигался ШИМ?

Исправте если неправель. Заранее спасибо

/* обработчик прерывания по внешнему сигналу на INT0 */

interrupt [EXT_INT0] void ext_int0_isr(void)

{

TCCR2 = 0b00000000; /* остановка таймера/счетчика 2 */


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

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


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


if (stan==1)
{
stan = 0;
}
else
{
stan = 1;
}
//1 - ШИМ увеличивается
//0 - ШИМ уменьшается

}



/* обработчик прерывания по переполнению таймера/счетчика 2 */

interrupt [TIM2_OVF] void timer2_ovf_isr(void)

{

/* PORTB &= 0b11111110; установить 0 на PB0, выключение светодиода */

if (stan == 1)
{

OCR2 += 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */
}
else
{
OCR2 -=2; /* уменьшение значения регистра сравнения таймера/счетчика 2 */
}




if (( OCR2 > 240 ) or (OCR2<15)) /* если значение регистра сравнения таймера/счетчика 2 больше

240, или меньше 15 то ... */

{

TCCR2 = 0b00000000; /* остановка таймера/счетчика 2 */

}


}
34. mihail - 19 Января, 2011 - 03:14:36 - перейти к сообщению
Demckiy пишет:
if (( OCR2 > 240 ) or (OCR2<15)) /* если значение регистра сравнения таймера/счетчика 2 больше 240, или меньше 15 то ... */
Это не характерная для С конструкция.
CODE:
if (( OCR2 > 240 ) || ( OCR2 < 15 )) /* если значение регистра сравнения таймера/счетчика 2 больше 240 или меньше 15 то ... */
Так лучше.

В остальном все нормально. А будет ли работать как задумано, нужно в симуляторе посмотреть (для начала).
35. cjA - 19 Января, 2011 - 05:08:09 - перейти к сообщению
mihail пишет:
Это не характерная для С конструкция.

mihail пишет:
Так лучше.

да чем другая хуже? что мешает OR объявить инлайн оператором?

Но меня смущает это
if (stan==1)
{
stan = 0;
}
else
{
stan = 1;
}
//1 - ШИМ увеличивается
//0 - ШИМ уменьшается
}

Ведь это Сишные stan = NOT stan ? (нипонятные никому stan|=stan)
Что за паскалевский стиль? Вся красота пропадает.
36. Demckiy - 19 Января, 2011 - 07:44:22 - перейти к сообщению
mihail,в симуляторе не работает так (Плавно включить свет (4 секунды).
Подождать (8 секунд). Плавно выключить свет (4 секунды). ).
Свет плавно включается,но не выключается....

Прикрепил исходник и проект в proteus'e.
37. Demckiy - 19 Января, 2011 - 07:45:08 - перейти к сообщению
исходник
38. Demckiy - 20 Января, 2011 - 07:19:01 - перейти к сообщению
Как у увеличивать и уменьшать ШИМ???
39. nest - 20 Января, 2011 - 20:39:13 - перейти к сообщению
Demckiy пишет:
Как у увеличивать и уменьшать ШИМ???
почитайте про регистр OCRx
40. Demckiy - 22 Января, 2011 - 16:28:19 - перейти к сообщению
1-увеличиваем ШИМ
0-уменьшаем ШИМ


CODE:
if (stan == 1)
{
OCR2 -= 2; /* уменьшение значения регистра сравнения таймера/счетчика 2 */
}
else
{
OCR2 += 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */
}


Правильное условие ????
41. mihail - 22 Января, 2011 - 19:55:10 - перейти к сообщению
С точки зрения синтаксиса С конструкция правильная. Но, безотносительно остального кода, мало о чем говорящая. Управлять ШИМ можно 1000 + 1 способом. Вы выбрали этот. Лично я предпочел бы другой. Какой лучше Замешательство Но дело в другом. Попробуйте сами выполнить написанную вами программу строчка за строчкой, оператор за оператором.
42. Demckiy - 22 Января, 2011 - 20:08:08 - перейти к сообщению
mihail, вот вся программа


CODE:



#include <mega8.h>

bit stan = 0;

/* запуск таймера/счетчика 2 (Шим+)
остановка таймера/счетчика 1 (время)
----------------------------
запуск таймера/счетчика 1 (время)
- остановка таймера/счетчика 2 (время)
запуск таймера/счетчика 2 (Шим-)

/* обработчик прерывания по внешнему сигналу на INT0 */

interrupt [EXT_INT0] void ext_int0_isr(void)

{

if (stan == 1)
{
stan = 0;

}
else
{
stan = 1;

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

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

TCCR2 = 0b00000111; /* запуск таймера/счетчика 2 с предделителем 1024 */


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

}





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


}





/* обработчик прерывания по переполнению таймера/счетчика 1 */

interrupt [TIM1_OVF] void timer1_ovf_isr(void)

{

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

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

OCR2 = 240;

stan = 0;

PORTC = 0b0000001;

TCCR2 = 0b00000111; /* запуск таймера/счетчика 2 с предделителем 1024 */



}





/* обработчик прерывания по переполнению таймера/счетчика 2 */

interrupt [TIM2_OVF] void timer2_ovf_isr(void)

{


/* PORTB &= 0b11111110; /* установить 0 на PB0, выключение светодиода */

if (stan == 1)
{
OCR2 -= 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */
}
else
{
OCR2 += 2; /* увеличение значения регистра сравнения таймера/счетчика 2 */
}


if ( OCR2 > 240 )// если значение регистра сравнения таймера/счетчика 2 больше 240 или меньше 15 то ... */
{

TCCR2 = 0b00000000; /* остановка таймера/счетчика 2 */

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

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

}

}





/* обработчик прерывания по совпадению таймера/счетчика 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)

{



}

}



ШИМ наростает, но когда прошло 8 секунд должен спадать ШИМ,а он не уменьшается...((

Вы писала,предпочли бы другой какой-то вариант ,какой???
43. mihail - 22 Января, 2011 - 20:24:11 - перейти к сообщению
Я знаю, что программа работает не так как Вы хотите. Поэтому я и написал выше
Цитата:
Попробуйте сами выполнить написанную вами программу строчка за строчкой, оператор за оператором.
Я могу переписать программу, чтобы она работала так как Вы хотите, но Вы врядли разберетесь во всем этом. А значит, смысла в этом немного.
Программа это единое целое. Если Вы изменили что то, необходимо проследить как это повлияет на остальную часть программы.
44. Demckiy - 22 Января, 2011 - 20:28:53 - перейти к сообщению
mihail пишет:
Я знаю, что программа работает не так как Вы хотите. Поэтому я и написал выше
Цитата:
Попробуйте сами выполнить написанную вами программу строчка за строчкой, оператор за оператором.
Я могу переписать программу, чтобы она работала так как Вы хотите, но при этом Вы врядли разберетесь во всем этом. А значит, смысла в этом немного.
Программа это единое целое. Если Вы изменили что то, необходимо проследить как это повлияет на остальную часть программы.


mihail, пожалуйста перепишите программу ,с рус. комментариями. Заранее спасибо.

Я уже пробовал выполнить программу строчка за строчкой,оно не хочет работать. По готовом примере легче учится. и находить свои ошибки.
45. cjA - 22 Января, 2011 - 23:06:34 - перейти к сообщению
rem нужно заметить что в атмелях нет приоритетов в прерываниях, если возникло одно и вылезти из него не может, то другое его не вытащит.
У вас все не правильно, в обработчике прерывания на атмель должно стоять только присвоение какой то переменной определленного значения, а обрабатывать все лучьше в основном цикле

(это всего лишь ремарка и ИМХО)