Свежие обсуждения
Микроконтроллеры

Микроконтроллерный датчик пульса

1 4 6

Сергей К: PCON|= 0xF7; //Пониженная частота
и
PCON|= 0x8; //Нормальная частота

Может, PCON&= 0xF7?

 

да! Точно! Хотел же заменить, но вылетело из головы
исправил, но ни замедления ни повышения скорости я не вижу
.....
Понизил в Протеусе частоту с 4МГц до 37кГц. Теперь и таци циферки замигали, подобно моему настоящему устройству. Неужели он запускается на 37кГц?

 

Сергей К, я в ПИКах не очень силён, поэтому только предложения/предположения:
- ещё раз, внимательно, покурить FUSES. Тип осциллятора, возможно что-то ещё;
- временно подключить кварц, посмотреть, что получится;
- посчитать циклы в прерывании (успевает ли выполниться за 4096 циклов)
- посмотреть, есть ли где запрещение прерываний, временно убрать.

 

Написал на ассемблере простую програмку, выводящую билибурду на дисплей (см. вложение). Проверил в железе - все работает на отлично. Значит ошибка в моей программе. Буду дальше "лопатить" процедуру обработки прерывания...

Пытался просмотреть длину обработчика прерывания. Количество команд - 0xACh (т.е. 172 команды). Теоретически - там должны быть переходы, сокращающие время выполнение. Циклов не должно быть.

Прогнал в режиме отладки (пошагово по ассемблерному коду). Выходит порядка 64 шагов...

82965.asm

 

Заменил я в своей основной программе обработчик прерывания на тестовый (на ассемблера) и все заработало!
Значить проблема в коде отображения цифр.

Оставил в обработчике только код, который отвечает за вывод цифр, но все равно - слайд-шоу. Код имеет следующий вид:

unsigned char Segment1,Segment2,Segment3,Segment4; //Отображаемая цифра
unsigned char ShowSegment; //Текущая отображаемая цифра
......

#int_TIMER0 // unimportant.
void TIMER0_isr(void )
{
PORTA&= 0b11110000; //Прячем цифры

PORTA|=0b10000000; //Убираем "точку"

if (ShowSegment==0)
{
PORTA = 0b10000001;
PORTB=Segment1;
// if ((Segment1 & 0b00000001) == 1) PORTA&=0b01111111;
}
if (ShowSegment==1)
{
PORTA = 0b10000010;
PORTB=Segment2;
// if ((Segment2 & 0b00000001) == 1) PORTA&=0b01111111;
}
if (ShowSegment==2)
{
PORTA = 0b10000100;
PORTB=Segment3;
// if ((Segment3 & 0b00000001) == 1) PORTA&=0b01111111;
}
if (ShowSegment==3)
{
PORTA = 0b10001000;
PORTB=Segment4;
// if ((Segment4 & 0b00000001) == 1) PORTA&=0b01111111;
}

ShowSegment++;
if (ShowSegment>=4) ShowSegment=0;

}

Прогонял код в MPLabs (в режиме ассемблера). Код выполняется быстро и без заметных задержек

 

Мистика....
Упростил код до:

#int_TIMER0 // unimportant.
void TIMER0_isr(void )
{
PORTA=PORTA<<1; #asm
nop
nop
nop
nop
nop
#endasm
if (PORTA>8) PORTA=1;
if (PORTA==0) PORTA=1;

PORTB=0b10101010;
}

все равно тормоза
я в растеряности....

 

А где сброс флага прерывания?

Привели бы уже всю программу, что ли

 

AHTOXA: А где сброс флага прерывания?
Похоже на PICC он не нужен.

 

AHTOXA: Привели бы уже всю программу, что ли
вот она.
Если в обработчике прерывания оставляю код на ассемблера (весь код до коментария "//Отображение цифры"), то все работает. Если на Си (весь код после коментария "//Отображение цифры") - то "тормозит"

83128.txt

 

PICC 4.023? Это уже второй глюк с ним получается. Может лучше 4.020 использовать? У меня с 4.020 проблем не было.