Уважаемый форум! Изучал прерывания на мегах и столкнулся с проблемой, а пока не решу дальше не иду. Задал свой вопрос на forum.roboclub.ru, но видно сильно подробно описал или вопрос сильно до- школьный, но в ответ -- тишина. Надеюсь, что вы будете более снисходительны.
При пошаговой отладке прерывания Таймер0 обратил внимание:
1.Предделитель таймера-биты CS03-CS00 регистра ТССR0B не устанавливаются.
2.При ручном вводе этого значения в поле TCCRn окна ‘Peripherals’ и при пошаговом выполнении программы, происходит затирание предварительно введенного значения в поле TCCRn окна ‘Peripherals’ инструкцией “TCCR0A=0х00;”. Если же остановить запущенную программу и вручную ввести значение в поле TCCRn окна ‘Peripherals’, то после запуска программы прерывание происходит, но при этом флаг прерываня в регистре TIFR0 устанавливается не TOV0(бit0), а OCF0A(bit1). При рассмотрение файла
m48def.inc, из папки include VMLABa, имена битов и адр. регистров соответствуют Д.Ш.
Но если просматривать побитно поле TCCRn окна ‘Peripherals’ то получаешь ахинею из имен битов, которых в ДШ нет.
Вопрос, что означают имена битов в окне TCCRn окна ‘Peripherals’? В ДШ. есть TCCR0А и ТCCR0В и имена битов совсем другие.
Далее про PCINT. Выводы PORTB.1-3 сделал входами с подтяжкой. В VMLAB повешал на них кнопки ‘control panel’. При нажатии на любую кнопку флаг прерывания устанавливается (бит0 в регистре PCIFR), но сам обработчик не выполняется и флаг не обнуляется. Листинги для обоих пакетов привожу. Проверял работу прерывания таймер0 на 90S2313 все работает. Кто сталкивался с этим - пожалуйста объясните и если можно то подробней. Если проверки делаю в цикле While то все работает.
""МЫ ВСЕ КОГДА-ТО УЧИЛИСЬ ХОДИТЬ.""
Chip type : ATmega48
Clock frequency : 0,015625 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Pin change 0-7 interrupt service routine
interrupt [PCINT0] void pin_change_isr0(void)
{
// Place your code here
PORTD.2=~PIND.2;//если произошло прерывание, то сигнал на выходе порта инверти-я.
}
// Timer 0 overflow interrupt service routine
/*interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xF0;//предварительная загрузка числа в счетный регистр таймера
// Place your code here
#asm("cli");
TIFR0=0x01;//стираю принудительно флаг, хотя по даташиту не нужно.
PORTD.3=~PIND.3;//по прерыванию сигнал на выходе порта инвертируется.
#asm("sei");
} */
// Declare your global variables here
void main(void)
{
// Crystal Oscillator division factor: 256
#pragma optsize-
CLKPR=0x80;
CLKPR=0x08;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Port B initialization
PORTB=0x0Е;
DDRB=0x00;
// Port D initialization
PORTD=0x1Е;
DDRD=0x1E;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0xF0;//предварительная загрузка таймера0
OCR0A=0x00;
OCR0B=0x00;
// Interrupt on any change on pins PCINT0-7: On
EICRA=0x00;
EIMSK=0x00;
PCICR=0x01;//включение прерывания на выводы порта РВ
PCMSK0=0x0E;//разрешение прерывания на линиях РВ3-1
PCIFR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Global enable interrupts
#asm("sei")
while (1)
{
}
}
Для VMLAB:
.MICRO "ATmega48"
.TOOLCHAIN "GENERIC"
.TARGET "1.hex" ; Proshivka na MK
.COFF "1.cof" ;
.SOURCE "1__.c"
.CLOCK 4meg
.POWER VDD = 5 VSS = 0
.STORE 2000m
; SW2-SW0 === K2-K0 on ControlPanal
K1 PB1 VSS ; кнопки с выхода порта на gnd.
K2 PB2 VSS ;
K3 PB3 VSS ;
; ===================================================
; Signals that will be ploted in SCOPE window
.plot V(PB1) V(PB2) V(PB3) V(PD2) V(PD3)