Sida 1 av 3
Timer1 problem nu igen..
Postat: 9 maj 2007, 11:29:39
av ankan
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.
Så här se koden ut:
Kod: Markera allt
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.
Fattar inte varför den inte snurrar...
Postat: 9 maj 2007, 11:48:53
av oJsan
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)
Postat: 9 maj 2007, 11:54:27
av sodjan
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" ?
Postat: 9 maj 2007, 11:55:56
av bearing
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.
Postat: 9 maj 2007, 12:42:15
av ankan
Får det inte att fungera med interna heller genom att sätta T1CON till 0b00000001. Dvs bara sätta TMR1ON=1.
Hur kollar jag om kristallen fungerar och om PICen får kristallen att oscillera?
Postat: 9 maj 2007, 12:46:32
av sodjan
Vilken av kristallerna ?
Finns ingen anledning att bråka med timer1-osc innan du har fått
det att fungera med intern klockning av timer1...
Postat: 9 maj 2007, 14:01:45
av ankan
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.
Postat: 9 maj 2007, 14:10:12
av bearing
Så det funkar med interna nu?
Mät bara mellan jord och valfri av de pinnar som kristallen sitter på.
Postat: 9 maj 2007, 14:46:17
av ankan
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?
Kod: Markera allt
char timer1=0;
void main() {
LCD_Init(&PORTD); // Initialize LCD connected to PORTD
T1CON = 0x0F; // Extern kristall, enable
// T1CON = 0xF1; // Interna oscillatorn (fungerar)
PIR1.TMR1IF = 0; // Nollställ flaggan
PIE1.TMR1IE = 1; // Enabla timer1 interrupt
INTCON = 0b11000000; // 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(100);
LCD_Chr(1,9,timer1+0x30);
}
}
void interrupt() {
timer1++;
TMR1H=0x80;
PIR1.TMR1IF=0;
}
Postat: 9 maj 2007, 15:50:30
av ankan
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?
Postat: 9 maj 2007, 17:09:37
av sodjan
> Kristallernavet jag att de fungerar nu.
Kristaller navet ? Eller vad ska det vara ?
bearing> Så det funkar med interna nu?
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...
Postat: 9 maj 2007, 17:34:38
av ankan
> 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.
Jag får det alltså att fungera med intern oscillatorn.. Kanske var lite otydlig.
> Kristallernavet jag att de fungerar nu.
Kristallerna vet jag att de fungerar nu.. Kanske lite dålig meningsbyggnad och miss av mellanslag.
Har alltså kollat kristallerna och de är hela. Och jag tycker att koden jag har skrivit ovan borde fungera. Fattar inte vad som är fel. Några tips ?
Postat: 10 maj 2007, 10:09:28
av ankan
Hur ska jag felsöka? Behöver en snurrande Timer1 som väcker PICen 1ggr/sek.
Hur ska jag sätta T1CON om jag bara vill testa ingången på PICen tex genom att skicka clockpulser manuellt?
Postat: 10 maj 2007, 10:22:08
av sodjan
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.
Postat: 10 maj 2007, 10:56:51
av ankan
Okey det fungerade.. Så alltså är alla mina kristaller trasig eller så har jag börjat koppla fel på något konstigt sätt.
Kristallen ska väll kopplas mellan T1OSI och T1OSO och sedan ska det kopplas en konding mellan T1OSI och jord och en konding mellan T1OSO och jord.
Jag fattar inte vad som har börjat bli fel!