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

Страниц (2): [1] 2 »
 

1. Blitzkrieg - 08 Февраля, 2009 - 13:31:48 - перейти к сообщению
Столкнулся с каким-то глюкобагом, не пойму почиму так происходит.
Переменная cnt используетя для подсчета кол-ва переполнений регистра TMR0. То есть в данном случае каждые 10 мс переменная cnt увеличивается на 1. То есть если проверять условие ее равенства 100 - мы ждем 1 секунду.
Так вот в следующем коде в случае если эта переменная равна 300 я ее обнуляю.
Обнуляться она не хочет,бывает что обнуляется при первом отсчете до 300, далее просто забывает это сделать.
Проблема конечно решается нестрогим равенством, но это же погрешность.
Обнуляться она не хочет, обнуляется только один первый раз. Но при использоавнии второго кода все отлично срабатывает.

Код 1
CODE:
int Sensor1,Sensor2,Sensor3,Sensor4,Sensor5;
char Txt[6];
unsigned cnt;

void Read_Adc()
{
ADCON0=0b00000001;
delay_us(20);
ADCON0.GO=1;
while(ADCON0.GO);
Sensor1=(ADRESH*4)+(ADRESL/64);

ADCON0=0b00000101;
delay_us(20);
ADCON0.GO=1;
while(ADCON0.GO);
Sensor2=(ADRESH*4)+(ADRESL/64);

ADCON0=0b00001001;
delay_us(20);
ADCON0.GO=1;
while(ADCON0.GO);
Sensor3=(ADRESH*4)+(ADRESL/64);

ADCON0=0b00001101;
delay_us(20);
ADCON0.GO=1;
while(ADCON0.GO);
Sensor4=(ADRESH*4)+(ADRESL/64);
}

void Read_Adc1()
{
ADCON0=0b00010001;
delay_us(20);
ADCON0.GO=1;
while(ADCON0.GO);
Sensor5=(ADRESH*4)+(ADRESL/64);
}

void interrupt() {
if(INTCON.T0IF)
{
cnt++;
TMR0 = 61;
INTCON.T0IF = 0;
}
}

void main()
{
cnt=0;
TRISA = 0b00111111;
ANSEL = 0b00111111;
TRISB.F0=1;
ANSELH.F4=0;
INTCON.GIE=1;
INTCON.T0IE=1;
OPTION_REG.T0CS=0;
OPTION_REG.PSA=0;
OPTION_REG.PS2=1;
OPTION_REG.PS1=1;
OPTION_REG.PS0=1;
Lcd_Init(&PORTD);
Lcd_Cmd(LCD_CURSOR_OFF);
while(PORTB.F0);
do
{
if (cnt==1300) cnt=0;
Read_Adc();
WordToStr(Sensor1,Txt);
Lcd_Out(1,1,Txt);
WordToStr(Sensor2,Txt);
Lcd_Out(1,6,Txt);
WordToStr(Sensor3,Txt);
Lcd_Out(1,11,Txt);
WordToStr(Sensor4,Txt);
Lcd_Out(2,1,Txt);
WordToStr(cnt,Txt);
Lcd_Out(2,11,Txt);

}
while(1);
}




Код 2
CODE:
char Txt[6];
unsigned cnt;
void interrupt() {
if(INTCON.T0IF)
{
cnt++;
TMR0 = 61;
INTCON.T0IF = 0;
}
}

void main()
{
cnt=0;
TRISB.F0=1;
ANSELH.F4=0;
INTCON.GIE=1;
INTCON.T0IE=1;
OPTION_REG.T0CS=0;
OPTION_REG.PSA=0;
OPTION_REG.PS2=1;
OPTION_REG.PS1=1;
OPTION_REG.PS0=1;
Lcd_Init(&PORTD);
Lcd_Cmd(LCD_CURSOR_OFF);
while(PORTB.F0);
while(1)
{
WordToStr(cnt,Txt);
Lcd_Out(2,11,Txt);
if (cnt==300) cnt=0;
}

}


2. Гость - 08 Февраля, 2009 - 15:10:44 - перейти к сообщению
есть мысля:
во время последующих (после первого сброса) насчетов до 300
Цитата:
if (cnt==1300) cnt=0;
1300 я понимаю опечатка и не в том суть. контроллер всякой ерундой занимаеться (опрос сенсоров, вывод на LCD...), и успевает перещелкнутся на 301.
Цитата:
while(PORTB.F0);
я не понял это к чему относиться (под контроллеры писал мало и только под 51)
3. Blitzkrieg - 08 Февраля, 2009 - 15:19:37 - перейти к сообщению
Predator пишет:
есть мысля:
во время последующих (после первого сброса) насчетов до 300
Цитата:
if (cnt==1300) cnt=0;
1300 я понимаю опечатка и не в том суть. контроллер всякой ерундой занимаеться (опрос сенсоров, вывод на LCD...), и успевает перещелкнутся на 301.
Цитата:
while(PORTB.F0);
я не понял это к чему относиться (под контроллеры писал мало и только под 51)


Вот тоже мысль такая, что МК занят чем-то в момент когда cnt==300. Может если сравнивать с 301 может будет работать?
1300 это опечатка.
while(PORTB.F0); а это сделано длля начала работы программы, то есть программа не выполняется до тех пор пока не нажмешь кнопочку RB0.
4. redcat - 08 Февраля, 2009 - 17:02:41 - перейти к сообщению
а как насчёт if (cnt>=300) cnt=0;
5. Гость - 08 Февраля, 2009 - 17:29:26 - перейти к сообщению
не, если сравнивать с 301- то он может оказаться занят именно, когда 301. надо сравнивать в момент инкремента (типа если 299, то в 0, иначе ++)
6. Blitzkrieg - 08 Февраля, 2009 - 17:29:51 - перейти к сообщению
redcat пишет:
а как насчёт if (cnt>=300) cnt=0;

Вы обладаете катастрофической невнимательностью :-)
Blitzkrieg пишет:
Проблема конечно решается нестрогим равенством, но это же погрешность.
7. VCOM - 08 Февраля, 2009 - 18:24:44 - перейти к сообщению
Дак написать

void interrupt() {
if(INTCON.T0IF)
{
if(cnt<300){cnt++;}
TMR0 = 61;
INTCON.T0IF = 0;
}
}

Не?
8. Гость - 08 Февраля, 2009 - 18:44:06 - перейти к сообщению
еще надо else{cnt=0;}, ато на 300 застрянет и не обнулиться
9. VCOM - 08 Февраля, 2009 - 18:57:56 - перейти к сообщению
Дак оно у него в мэйне вроде как обнуляецца... Если в прерывании обнулять снова проскакивать будет Ж))))) Вот если хочеццо именно 300 прерываний, то тогда надо в прерывании считать, обнулять и флаг выставлять. А в основной проге уже не счетчик смотреть, а флаг, ну и сбрасывать тоже флаг в основной программе... Т.е. вот так должно быть:

char Txt[6];
unsigned int cnt;
unsigned char flag;

void interrupt() {
if(INTCON.T0IF)
{

cnt++;
if(cnt>=300){flag=1;cnt=0;}

TMR0 = 61;
INTCON.T0IF = 0;
}
}

void main()
{
cnt=0;
flag=0;

TRISB.F0=1;
ANSELH.F4=0;
INTCON.GIE=1;
INTCON.T0IE=1;
OPTION_REG.T0CS=0;
OPTION_REG.PSA=0;
OPTION_REG.PS2=1;
OPTION_REG.PS1=1;
OPTION_REG.PS0=1;
Lcd_Init(&PORTD);
Lcd_Cmd(LCD_CURSOR_OFF);
while(PORTB.F0);

while(1)
{
WordToStr(cnt,Txt);
Lcd_Out(2,11,Txt);

if (flag==1) {flag=0;} //Урра! Прошло 300 прерываний

}

}

Вот гдето так...
10. Гость - 08 Февраля, 2009 - 19:11:18 - перейти к сообщению
ну я так понял, что надо каждые 300 прерываний отсчитывать
Цитата:
бывает что обнуляется при первом отсчете до 300, далее просто забывает это сделать

Цитата:
if (cnt==300) cnt=0;
. а там ему виднее
11. VCOM - 08 Февраля, 2009 - 19:30:57 - перейти к сообщению
cnt>=300 Так оно железобетоннее Ж)))))
12. Blitzkrieg - 08 Февраля, 2009 - 21:27:50 - перейти к сообщению
VCOM пишет:
cnt>=300 Так оно железобетоннее Ж)))))

АГась, решил именно так пока и оставить, пока точность не требуется :-)
13. redcat - 09 Февраля, 2009 - 11:13:09 - перейти к сообщению
Blitzkrieg пишет:
redcat пишет:
а как насчёт if (cnt>=300) cnt=0;

Вы обладаете катастрофической невнимательностью :-)
14. VCOM - 09 Февраля, 2009 - 17:07:43 - перейти к сообщению
Мнееее. Эт то то все понятно. Главное чтоб по флагу событие нюхалось...
15. redcat - 09 Февраля, 2009 - 19:17:01 - перейти к сообщению
Blitzkrieg Извините,я не понял, о какой не внимательности идёт речь?