Hjälp med 16F1937
Re: Hjälp med 16F1937
Jag har INTCON.TMR0IF=0;... glöm koden innan den är rättad nu. Men betendet är detsamma med interuptet som inte reagerar.
Får kolla genom alla register och se om jag missta ngt... Jag har ett annat ex som jag har utgått från (http://embedded-lab.com/blog/?p=4653)och det ser ut som det vi har gjort nu... men ändå ngnstans går det fel.
Får kolla genom alla register och se om jag missta ngt... Jag har ett annat ex som jag har utgått från (http://embedded-lab.com/blog/?p=4653)och det ser ut som det vi har gjort nu... men ändå ngnstans går det fel.
Re: Hjälp med 16F1937
Jag har inte kollat om den är inblandad, men för vissa interrupt-källor
så behöver man även sätta INTCON.PEIE=1 ("Peripheral Interrupt Enable bit").
Jag minns inte om Timer0 också räknas till "peripherials", på äldre modeller
gick TMR0IF bredvid PEIE, så att säga. SAnnolikt är det något annat.
så behöver man även sätta INTCON.PEIE=1 ("Peripheral Interrupt Enable bit").
Jag minns inte om Timer0 också räknas till "peripherials", på äldre modeller
gick TMR0IF bredvid PEIE, så att säga. SAnnolikt är det något annat.
Re: Hjälp med 16F1937
OEIE var tyvärr inte inblandad som du misstänkte,
Har provat isolera problemet lite mer och bortkommenterat en del i ISR'n som du kan se i koden nedan.
Det händer i princip inget på PWM utgången så ngt måste vara fel så att PWM interuptet inte skapas. Dcok går PWM hög när jag duttar med kabel på INT pinnen vilket är helt logiskt.
Har provat isolera problemet lite mer och bortkommenterat en del i ISR'n som du kan se i koden nedan.
Det händer i princip inget på PWM utgången så ngt måste vara fel så att PWM interuptet inte skapas. Dcok går PWM hög när jag duttar med kabel på INT pinnen vilket är helt logiskt.
Kod: Markera allt
/*
Manöverpanel till fjärrvärme Pic16F1937, intern 8MHz OSC, extern MCLR
*/
#define BUZZ PORTC.F3 //Name ports
#define SERVO PORTD.F1
#define BACKLIGHT PORTC.F2
sbit PWM_OUT at RD0_bit;
int k=0;
char *text1;
char *text2;
//LCD module connection
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RA2_bit;
sbit LCD_D5 at RA3_bit;
sbit LCD_D6 at RA4_bit;
sbit LCD_D7 at RA5_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISA2_bit;
sbit LCD_D5_Direction at TRISA3_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA5_bit;
//End LCD module connection
void initMain(){
TRISA=0b00000000;
TRISB=0b00110011;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00000000;
LCDCON=0b00000000;
CPSCON0=0b00000000;
ANSELA=0;
ANSELB=0;
INTCON=0b10111000;
IOCBP=0b00000001;
OPTION_REG=0b00100111;
TMR0=180;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
if(k!=1){ //Kontroll att main inte körs efter interupt
BUZZ=1;
delay_ms(50);
BUZZ=0;
//BACKLIGHT=1;
Lcd_out(1,1,"Remote Heater");
Lcd_out(2,1,"Sp-E 2014");
}
}
void interrupt(){
/* if(INTF==1){
SERVO=0;
k=1;
BACKLIGHT=0;
INTCON.INTF=0;
} */
//if(TMR0IF==1){
PWM_OUT=1;
Delay_ms(2);
PWM_OUT=0;
INTCON.TMR0IF=0;
// }
//INTCON=0b00000000; //Nolla interupt för att det inte ska loopa hela tiden
}
void main() {
initMain();
while(1){
if(k==1){ //Hör till interuptet
BUZZ=1;
delay_ms(50);
BUZZ=0;
Lcd_out(1,1,"Servo Error!!!");
Lcd_out(2,1,"Reset panel!!!");
while(1){
SERVO=0;
BACKLIGHT=0;
BUZZ=0;
}
}
else if(Button(&PORTB, 5,1,0)||Button(&PORTB, 4,1,0)){
BACKLIGHT=1;
}
else if(Button(&PORTB, 5,1,1)&&Button(&PORTB, 4,1,1)){
BACKLIGHT=0;
}
}
}
Senast redigerad av newbadboy 6 juni 2014, 12:33:55, redigerad totalt 1 gång.
Re: Hjälp med 16F1937
Hur ser main-loopen ut? Som det är nu kör programmet genom en gång och "faller ut".
Re: Hjälp med 16F1937
Den kommer ju att "fastna" i den inre while(1) loopen, men
det kanske är avsikten (?).
> //Kontroll att main inte körs efter interupt
Det där förstår jag inte. Main() körs ju alltid utan just då då
koden ligger i interrupt() funktionen. Main() bara "pausar"
medans interrupt() körs...
För övrigt så har ju det här:
samma funktion som:
Det räcker ju att sätta utgångarna *en* gång...
det kanske är avsikten (?).
> //Kontroll att main inte körs efter interupt
Det där förstår jag inte. Main() körs ju alltid utan just då då
koden ligger i interrupt() funktionen. Main() bara "pausar"
medans interrupt() körs...
För övrigt så har ju det här:
Kod: Markera allt
while(1){
SERVO=0;
BACKLIGHT=0;
BUZZ=0;
}
Kod: Markera allt
SERVO=0;
BACKLIGHT=0;
BUZZ=0;
while(1){
}
Re: Hjälp med 16F1937
Japp, triggar man INT pinnen så kan man fastna i den inre loopen, tills man gör MCLR reset är det tänkt.
Ang
//Kontroll att main inte körs efter interupt
var något jag experimentrade med lite innan och kommer nog att tas väck sen så den behöver vi eg inte bry oss om.....det handlade om att bara skriva ut text på displayen en gång bara...
Ang
//Kontroll att main inte körs efter interupt
var något jag experimentrade med lite innan och kommer nog att tas väck sen så den behöver vi eg inte bry oss om.....det handlade om att bara skriva ut text på displayen en gång bara...
Re: Hjälp med 16F1937
> ...tills man gör MCLR reset är det tänkt.
Ah, OK. Ja vill man ha det så så är det väl OK.
De flesta skulle nog kalla det en "bugg"...
> var något jag experimentrade med lite innan...
OK. Städa gärna bort sådan innan det postas.
Inte så lätt för *oss* att veta vad vi ska bry oss om eller inte.
Så problemet just nu är att det ser ut som att TMR0 interruptet
inte triggar som det ska?
Ah, OK. Ja vill man ha det så så är det väl OK.
De flesta skulle nog kalla det en "bugg"...

> var något jag experimentrade med lite innan...
OK. Städa gärna bort sådan innan det postas.
Inte så lätt för *oss* att veta vad vi ska bry oss om eller inte.

Så problemet just nu är att det ser ut som att TMR0 interruptet
inte triggar som det ska?
Re: Hjälp med 16F1937
Den här koden fungerar. PIC16F1938.
TMR0 räknar upp och när den "slår runt" så körs ISR'en.
Du kan vä'l jämföra med vad du gör i din C kod...
EDIT: Plockade bort PEIE, den behövs inte...
TMR0 räknar upp och när den "slår runt" så körs ISR'en.
Du kan vä'l jämföra med vad du gör i din C kod...
Kod: Markera allt
; __CONFIG b'010010000101'
list p=16f1938
#include <p16f1938.inc>
;**********************************************
; RESET VECTOR
;**********************************************
RESET_VECT CODE 0x0000 ; processor reset vector
PAGESEL START
GOTO START
nop
nop
;*********************************************
; INTERRUPT SERVICE ROUTINE
;*********************************************
ISR CODE 0x0004 ; interrupt vector location
nop
banksel intcon
bcf intcon, tmr0if ; Clear TMR0 interrupt flag.
retfie
prog code
start
; Initiera Timer0
banksel option_reg
bcf option_reg, ps0 ; Högsta fart...
bcf option_reg, ps1 ; -"-
bcf option_reg, ps2 ; -"-
bcf option_reg, psa
bcf option_reg, tmr0cs ; Tmr0 clock source = osc.
banksel intcon
bsf intcon, tmr0ie ; Tmr0 interrupt enable.
; Starta interrupt
banksel intcon
bsf intcon, gie ; Global interrut enable.
movlw h'e0' ; Preload TMR0 for faster tests...
banksel tmr0
movwf tmr0
loop
goto loop ; Wait for interrupt to happen...
END
Re: Hjälp med 16F1937
Mina assembler kunskaper är rätt små men vad jag kan se är det samma konfig som jag har.
Nu till en uppdatering. Har rensat bort lite i koden som def inte kommer användas. Nu till det riktigt intressanta. Jag har fått igång PWM men ändå inte....
Om koden är exakt som den är nedan så är PWM utgången noll ända tills jag duttar med INT pinnen till 5V och då börjar pulståget snurra. Mao ord av ngn anledning behöver jag putta igång PWM signalen mha av INT pinnen. Om jag har if(TMR0IF==1) så kan jag inte putta igång pwm pulsen, vilket är ju helt rätt.
Nu stämmer ju inte frekvens men det kan jag ställa sen utan problem
Och ofta får jag bara ut 5V hela tiden på PWM utgången direkt jag spänningsätter kortet
Märkte också att om jag får 5V på utgången kan jag inte få bort det utan att sätta INTCON=0b00000000; i slutet på ISR, sedan slår jag på kortet, stänger av tar bort INTCON=0b000000000;. Slår jag nu på kortet och triggar som ovan nämnt med INT pinnen får jag ut pulståget
Så då kvarstår frågan varför drar inte TMR0 igång av sig själv? Och vad innebär konstant 5V?... shit nu börjar jag blir mer förvirrad
Nu till en uppdatering. Har rensat bort lite i koden som def inte kommer användas. Nu till det riktigt intressanta. Jag har fått igång PWM men ändå inte....
Om koden är exakt som den är nedan så är PWM utgången noll ända tills jag duttar med INT pinnen till 5V och då börjar pulståget snurra. Mao ord av ngn anledning behöver jag putta igång PWM signalen mha av INT pinnen. Om jag har if(TMR0IF==1) så kan jag inte putta igång pwm pulsen, vilket är ju helt rätt.
Nu stämmer ju inte frekvens men det kan jag ställa sen utan problem
Och ofta får jag bara ut 5V hela tiden på PWM utgången direkt jag spänningsätter kortet
Märkte också att om jag får 5V på utgången kan jag inte få bort det utan att sätta INTCON=0b00000000; i slutet på ISR, sedan slår jag på kortet, stänger av tar bort INTCON=0b000000000;. Slår jag nu på kortet och triggar som ovan nämnt med INT pinnen får jag ut pulståget
Så då kvarstår frågan varför drar inte TMR0 igång av sig själv? Och vad innebär konstant 5V?... shit nu börjar jag blir mer förvirrad
Kod: Markera allt
/*
Manöverpanel till fjärrvärme Pic16F1937, intern 4MHz OSC, extern MCLR
*/
#define BUZZ PORTC.F3 //Name ports
#define SERVO PORTD.F1
#define BACKLIGHT PORTC.F2
sbit PWM_OUT at RD0_bit;
int k=0;
char *text1;
char *text2;
//LCD module connection
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RA2_bit;
sbit LCD_D5 at RA3_bit;
sbit LCD_D6 at RA4_bit;
sbit LCD_D7 at RA5_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISA2_bit;
sbit LCD_D5_Direction at TRISA3_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA5_bit;
//End LCD module connection
void initMain(){
TRISA=0b00000000;
TRISB=0b00110011;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00000000;
LCDCON=0b00000000;
CPSCON0=0b00000000;
ANSELA=0;
ANSELB=0;
INTCON=0b10111000;
IOCBP=0b00000001;
OPTION_REG=0b00100111;
TMR0=180;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
BUZZ=1;
delay_ms(50);
BUZZ=0;
Lcd_out(1,1,"Remote Heater");
Lcd_out(2,1,"Sp-E 2014");
}
void interrupt(){
/* if(INTF==1){
SERVO=0;
k=1;
BACKLIGHT=0;
INTCON.INTF=0;
} */
// if(TMR0IF==1){
PWM_OUT=1;
Delay_ms(2);
PWM_OUT=0;
Delay_ms(18);
INTCON.TMR0IF=0;
// }
}
void main() {
initMain();
while(1){
if(k==1){ //Hör till interuptet
BUZZ=1;
delay_ms(50);
BUZZ=0;
Lcd_out(1,1,"Servo Error!!!");
Lcd_out(2,1,"Reset panel!!!");
while(1){
SERVO=0;
BACKLIGHT=0;
BUZZ=0;
}
}
else if(Button(&PORTB, 5,1,0)||Button(&PORTB, 4,1,0)){
BACKLIGHT=1;
}
else if(Button(&PORTB, 5,1,1)&&Button(&PORTB, 4,1,1)){
BACKLIGHT=0;
}
}
}
Re: Hjälp med 16F1937
Ja, det är ju så att även om din main() "fastnar" i den andra
while(1) loopen, så kommer ju Timer0 ändå att fortsätta snurra
och interruptet att fortsätta generera PWM pulser tills du stänger
av det hela eller resettar.
Är du säker på att du inte behöver skriva if(INTCON.INTF==1)
och if(INTCON.TMR0IF==1)? Du gör ju det på andra ställen. Jag
vet inte om MikroC är tillräckligt smart för att fixa det ändå...
while(1) loopen, så kommer ju Timer0 ändå att fortsätta snurra
och interruptet att fortsätta generera PWM pulser tills du stänger
av det hela eller resettar.
Är du säker på att du inte behöver skriva if(INTCON.INTF==1)
och if(INTCON.TMR0IF==1)? Du gör ju det på andra ställen. Jag
vet inte om MikroC är tillräckligt smart för att fixa det ändå...
- SeniorLemuren
- Inlägg: 8427
- Blev medlem: 26 maj 2009, 12:20:37
- Ort: Kristinehamn
Re: Hjälp med 16F1937
Här har du kod som genererats av mikroC Timer Calculator
Kod: Markera allt
//Timer0
//Prescaler 1:256; TMR0 Preload = 97; Actual Interrupt Time : 19,969 ms
//Place/Copy this part in declaration section
void InitTimer0(){
OPTION_REG = 0x87;
TMR0 = 97;
INTCON = 0xA0;
}
void Interrupt(){
if (TMR0IF_bit){
TMR0IF_bit = 0;
TMR0 = 97;
//Enter your code here
}
}
Re: Hjälp med 16F1937
Ja just det, det där har jag sett någonstans.
Så om jag förstår rätt så kan man antingen skriva
"INTCON.TMR0IF" eller "TMR0IF_bit".
Men inte enbart "TMR0IF"...
Så om jag förstår rätt så kan man antingen skriva
"INTCON.TMR0IF" eller "TMR0IF_bit".
Men inte enbart "TMR0IF"...