Får inte timer1 att snurra på en PIC16F88 så jag testar lite kod på en 16F877A med en LCD som ska skriva ut värdet på en variabel som ska tickas upp vid avbrott på timer1.
Testat på en PIC16F877A eftersom det är så bökigt att programmera PIC16F88 när man ska ha en kristall på samma ben som programmeringen sker.
char timer1=0;
void main() {
LCD_Init(&PORTD); // Initialize LCD connected to PORTD
T1CON = 0x0F; // Extern kristall, enable
PIR1.TMR1IF = 0; // Nollställ flaggan
PIE1.TMR1IE = 1; // Enabla timer1 interrupt
INTCON = 0b1100000; // GIE och PIE enable
LCD_Cmd(LCD_CLEAR); // Clear display
LCD_Cmd(LCD_CURSOR_OFF); // Turn cursor off
LCD_Out(1,1, "Timer1:"); // Print text to LCD, 2nd row, 1st column
while(1) {
Delay_ms(1000);
LCD_Chr(1,8,timer1+0x30);
}
}
void interrupt() {
if (PIR1.TMR1IF) {
timer1++;
PIR1.TMR1IF=0;
PIE1.TMR1IE=1; // För säkerhets skull
}
}
Det enda som händer är att det står Timer1:0 på displayen. värdet på timer1-variabeln är oförändrad.
Har satt en klockkristall på ca 32khz mellan T1OSI och T1OSO enligt datablad och sedan en konding mellan T1OSI och jord samt en konding mellan T1OSO och jord. Kondingarna är på 33pF enligt databladets rekommendation.
Nu har ju inte jag programmerat speciellt mycket PIC, och speciellt inte i C,men AVR är jag desto mer 'hemma' på. Jag reagerar över if-satsen i avbrottsrutinen, ska den verkligen behövas? Du ska inte behöva kolla flaggan, avbrottet triggar på flaggan och gör alltså arbetet åt tid!
Ta bort if-satsen och låt avbrottsrutinen enbart innehåller timer1++; (Och nollställning av flaggan, kan vara så att du måste göra det manuellt)
oJsan, i *detta* (med bara en interrupt källa) så kan man plocka
bort IF satsen, men annars är det "good practice" att ha den med.
Och igentligen en kolla av IE flaggan också...
För att *debugga* skulle jag naturligtsvis plocka bort den...
För att kolla vad det är, fungerar allt om du enbart ställer om T1CON till
"Internal clock" ?
PIC16 har samma interruptadress för alla interrupts, så man måste maska fram vilket av dem som skett om flera kan ske. I det här fallet behövs ju iofs inte det.
Kolla med skåpet om det oscillerar på kristallpinnarna.
Såg för att jag hade skrivit fel på INTCON. Det saknades en 0:a. Men jag får fortfarande inte det att fungera med extern kristall.
Hur felsöker man att köra med en extern kristall för timer1? Använder T1OSI och T1OSO.
Har kollat nu och ser bara en något förstörd signal från "huvudkristallen" på 8Mhz med lägre amplitud än om jag skulle mäta direkt på "huvudkristallen"
Någon kurva på ca 38khz ser jag inte skymten av. Har testat flera olika klockkristaller men det lirar inte på någon av dem. Så hur felsöker jag vidare?
Kan det ha något med koden då och vad kan vara fel i så fall?
Kristallernavet jag att de fungerar nu. Testade att köra dem som huvudkristall och det fungerade bra. Det är när jag vill att de ska jobba för Timer1 som det inte händer något.
Alltså måste det vara något i koden ovan jag har missat, men vad?
Jag vet inte om jag är blind, men var är svaret på den frågan ?
Det är du som har problem och du får inte mer hjälp tillbaka
genom att skita i frågorna du får. Gör som du vill, jag gör något annat...
TMR1ON = 1 ("T1 on")
TMR1CS = 1 ("extern clock")
T1OSCEN = 0 ("T1 oscillator off")
T1CKPS och T1SYNC efter behov...
Extern klocka in på T1CKI
Klockan kan du t.ex generare från en loop i main() delen av programmet.
Bara att koppla ihop två pinnar.
Eller med något externt, om du hellre vill det.