Страница 1 из 1
Режим CTC
Добавлено: Пт мар 29, 2013 20:26:34
ATH
Доброго времени суток. Программа должна мигать светодиодом и при нажатии на кнопку увеличивать частоту мигания, при достижении регистра сравнения нуля в него должно записываться первоначальное число. Собрал в железе и в протеусе, там и там почему-то программа работает сначала правильно потом генерация пропадает вообще, помогите найти ошибку.
#include <mega8.h>
#include <delay.h>
unsigned int pwm;
void main(void)
{
TCCR1A=0b01000000;
TCCR1B=0b00001101;
pwm=1000; // переменная регистра сравнения
OCR1A=pwm;
PORTB=0x00;
DDRB=0x3;
PORTC=0xFF;
DDRC=0x00;
while (1)
{
if(PINC.4==0){
pwm=pwm-100;
delay_ms(1000);
if(pwm<=0){pwm=1000;}
OCR1A=pwm;
}
}
}
Re: Режим CTC
Добавлено: Пт мар 29, 2013 22:54:59
oleg110592
Смущает if(pwm<=0){pwm=1000;} pwm у вас unsigned, как она может быть меньше нуля?
Re: Режим CTC
Добавлено: Сб мар 30, 2013 05:40:15
ATH
Исправил. Если кнопку быстро отжимать и нажимать программа работает правильно. Если немного задержать то светодиод просто горит или не горит, как бы зависает потом минуты через 2, отвисает и работает

#include <mega8.h>
#include <delay.h>
int pwm;
void main(void)
{
TCCR1A=0b01000000;
TCCR1B=0b00001101;
pwm=1000;
OCR1A=pwm;
PORTB=0x00;
DDRB=0x3;
PORTC=0xFF;
DDRC=0x00;
while (1)
{
if(PINC.4==0){
pwm=pwm-100;
delay_ms(1000);
}
OCR1A=pwm;
if(pwm<=0){pwm=1000;}
}
}
Re: Режим CTC
Добавлено: Сб мар 30, 2013 07:28:55
korsaj
А вот и нет!
Пока вы удерживаете кнопку у вас повторяется =pwm-100 и в один прекрасный момент pwm = 0 а вы от него отнимаете 100 и получаете заем (переполнение) 0-100 = (65536 - 100 = 65436). В алгоритмах всегда должен быть "ограничитель". Вот типа такого
Код: Выделить всё
if (Button == 0) {
if (pwm != 0) pwm = pwm - 100;
else pwm = 1000;
OCR1A = pwm;
delay_ms(1000);
}
Re: Режим CTC
Добавлено: Сб мар 30, 2013 09:21:44
oleg110592
если pwm int, то если
pwm=0, при вычислении
pwm-100, pwm будет = -100
попробуйте так:
Код: Выделить всё
unsigned int pwm=1000;
void main(void)
{
.....
while (1)
{
if(PINC.4==0){
pwm=-100;
if(pwm==0) pwm=1000;
delay_ms(1000);
}
OCR1A=pwm;
}
}
А компилятор GCC?
Re: Режим CTC
Добавлено: Сб мар 30, 2013 12:33:47
ATH
CodevisionAVR. Все равно работает не правильно, я бы сказал что он как бы "зависает" в определенном месте и через минуту "отвисает":(
Может это как то связано с тем что регистр OCR1A 16-ти разрядный?
#include <mega8.h>
#include <delay.h>
unsigned int pwm;
void main(void)
{
TCCR1A=0b01000000;
TCCR1B=0b00001101;
pwm=1000;
OCR1A=pwm;
PORTB=0x00;
DDRB=0x3;
PORTC=0xFF;
DDRC=0x00;
while (1)
{
if(PINC.4==0){
if(pwm !=0) { pwm=pwm-100;}
else {pwm=1000;}
OCR1A=pwm;
delay_ms(1000);
}
}
}
Re: Режим CTC
Добавлено: Сб мар 30, 2013 13:57:31
ChipKiller
ATH писал(а):CodevisionAVR. Все равно работает не правильно...
.. ну конечно - во всем виноват CodevisionAVR, а не "кривой" алгоритм

.
PS. Сделайте опрос кнопок через таймер - избавитесь от "неожиданностей" (дребезга)
Re: Режим CTC
Добавлено: Сб мар 30, 2013 19:08:04
oleg110592
Ошибся я, это в шпротеусе работает:
Спойлер
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
// Declare your global variables here
void main(void)
{
// Declare your local variables here
static unsigned int pwm;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=0 State0=T
PORTB=0x00;
DDRB=0x03;
// Port C initialization
PORTC=0xFF;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// 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: 8000.000 kHz
// Mode: Fast PWM top=0x03FF
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x83;
TCCR1B=0x09;
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: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
OCR1A=1000;
pwm=1000;
while (1)
{
if(PINC.4==0)
{
pwm-=100;
if(pwm==0) pwm=1000;
delay_ms(1000);
}
OCR1A=pwm;
}
}