Hjälp med 16F1937
Re: Hjälp med 16F1937
Om du vill ändra *hela* port a så prova PORTA=255 och PORTA=0.
Notera att PORTA=1 enbart sätter lägsta biten.
Bit 0 i PORTA borde dock "blinka"...
Notera också att ANSELA enbart är för PORTA. Det finns andra
ANSELx register för de övriga portarna som har analoga funktioner.
Notera att PORTA=1 enbart sätter lägsta biten.
Bit 0 i PORTA borde dock "blinka"...
Notera också att ANSELA enbart är för PORTA. Det finns andra
ANSELx register för de övriga portarna som har analoga funktioner.
Re: Hjälp med 16F1937
Det var som attan, det har jag missat helt.
Jo jag såg i databladet att varje port har eget ansel reg. Bra nu kan jag försöka skriva ut ngt kul på displayen tack för hjälpen så länge
Jo jag såg i databladet att varje port har eget ansel reg. Bra nu kan jag försöka skriva ut ngt kul på displayen tack för hjälpen så länge

Re: Hjälp med 16F1937
PORTA är ett register med 8 bitar, alltså värderna 0-255 (decimalt).
Ett sätt att undvika missförstånd är att skriva binärt, d.v.s:
PORTA=0b00000000 till PORTA=0b11111111, det gör det lättare
att se vilken pinne som är hög eller låg.
Sen så kommer du ju aldrig att sätta hela PORTA på en gång
i alla fall eftersom det är olika styrsignaler till LCD'n och de
måste ju hanteras separat med bit-instruktioner...
Ett sätt att undvika missförstånd är att skriva binärt, d.v.s:
PORTA=0b00000000 till PORTA=0b11111111, det gör det lättare
att se vilken pinne som är hög eller låg.
Sen så kommer du ju aldrig att sätta hela PORTA på en gång
i alla fall eftersom det är olika styrsignaler till LCD'n och de
måste ju hanteras separat med bit-instruktioner...

Re: Hjälp med 16F1937
Jag förstår, jag har använt 0b000000000 innan så jag förstår inte varför jag börjar strula med annat nu.
Kompilatorn har färdiga funktioner för display. Jag ville bara testa då att porten var rätt satt. Det kommer säkert fler frågor, har lite andra portar som skall sättas, bla en pwm ut och en adc in samt ett interupt
Kompilatorn har färdiga funktioner för display. Jag ville bara testa då att porten var rätt satt. Det kommer säkert fler frågor, har lite andra portar som skall sättas, bla en pwm ut och en adc in samt ett interupt
Re: Hjälp med 16F1937
Två nya problem.
Vill ha ett interrupt när pinnen RB0 dras hög. Då ska den Stänga av lite utgångar skriva ut en varningtext samt hänga kvar i en oändlig loop till det kommer en reset via MCLR.
1 Jag får fel när jag kompilerar som beskrivs nedan. Kommentar jag bort Print display i interuptet går kompileringen genom. det blir väl ngn konflikt på ngt sätt men jag kan inte se det??
32 365 Reentrancy is not allowed: function 'Print_Display' called from two threads Manoverpanel.c
184 365 Reentrancy is not allowed: function 'Lcd_Out' called from two threads __Lib_Lcd.c
184 365 Reentrancy is not allowed: function 'Lcd_Out' called from two threads __Lib_Lcd.c
50 365 Reentrancy is not allowed: function 'Lcd_Chr_CP' called from two threads __Lib_Lcd.c
18 365 Reentrancy is not allowed: function 'Lcd_Cmd' called from two threads __Lib_Lcd.c
0 102 Finished (with errors): 01 jun 2014, 14:22:32 Manoverpanel.mcppi
2 Med print bortkommenterat i interupt så går det flasha. Men när jag provar dra RB0 hör verkar hela kretsen ressetas som om det vore via MCLR. det verkar inte alls gå in i Interupt rutinen jag gar skrivit. Vad göra?
Vill ha ett interrupt när pinnen RB0 dras hög. Då ska den Stänga av lite utgångar skriva ut en varningtext samt hänga kvar i en oändlig loop till det kommer en reset via MCLR.
1 Jag får fel när jag kompilerar som beskrivs nedan. Kommentar jag bort Print display i interuptet går kompileringen genom. det blir väl ngn konflikt på ngt sätt men jag kan inte se det??
32 365 Reentrancy is not allowed: function 'Print_Display' called from two threads Manoverpanel.c
184 365 Reentrancy is not allowed: function 'Lcd_Out' called from two threads __Lib_Lcd.c
184 365 Reentrancy is not allowed: function 'Lcd_Out' called from two threads __Lib_Lcd.c
50 365 Reentrancy is not allowed: function 'Lcd_Chr_CP' called from two threads __Lib_Lcd.c
18 365 Reentrancy is not allowed: function 'Lcd_Cmd' called from two threads __Lib_Lcd.c
0 102 Finished (with errors): 01 jun 2014, 14:22:32 Manoverpanel.mcppi
2 Med print bortkommenterat i interupt så går det flasha. Men när jag provar dra RB0 hör verkar hela kretsen ressetas som om det vore via MCLR. det verkar inte alls gå in i Interupt rutinen jag gar skrivit. Vad göra?
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
#define PWM PORTD.F1
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 Print_Display(char *text1, char *text2){
BACKLIGHT=1;
Lcd_out(1,1,text1);
Lcd_out(2,1,text2);
}
void interrupt(){
SERVO=0;
BUZZ=1;
delay_ms(100);
BUZZ=0;
// Print_Display("Servo Error!!!","Reset panel");
BACKLIGHT=0;
while(1){
SERVO=0;
}
}
void main() {
TRISA=0b00000000;
TRISB=0b00110011;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00000000;
LCDCON=0b00000000;
ANSELA=0;
ANSELB.F0=0;
INTCON.F0=1;
IOCBP.F0=1;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
BUZZ=1;
delay_ms(10);
BUZZ=0;
Print_Display("test1","test2");
}
Re: Hjälp med 16F1937
Du kan normalt inte anropa en funktion inifrån interruptrutinen som du
även använder "på utsidan". Du kan ju få ett interrupt medan du redan
ligger i 'Print_Display(), och det är det den larmar om. Kom ihåg att ditt
interrupt kan inträffa när som helst.
Så undvik att anropa funktioner i din interrupt som du även
använder normalt, så att säga.
Du kan t.ex låta din interrupt bara sätta en flagga som du sedan
kollar i din main() loop och gör det som behöver göras *där*.
> det verkar inte alls gå in i Interupt rutinen jag gar skrivit.
Verkar?
Det ser du väl på t.ex utgångarna som ska "stängas av".
Gör den inte det?
även använder "på utsidan". Du kan ju få ett interrupt medan du redan
ligger i 'Print_Display(), och det är det den larmar om. Kom ihåg att ditt
interrupt kan inträffa när som helst.
Så undvik att anropa funktioner i din interrupt som du även
använder normalt, så att säga.
Du kan t.ex låta din interrupt bara sätta en flagga som du sedan
kollar i din main() loop och gör det som behöver göras *där*.
> det verkar inte alls gå in i Interupt rutinen jag gar skrivit.
Verkar?

Det ser du väl på t.ex utgångarna som ska "stängas av".
Gör den inte det?
Re: Hjälp med 16F1937
Uppfattat, ang funktion i interuptet. Låter vettigt när du förklarar så.
Då bilr det mao tex som nedan dådå.
Då får jag ändra "verkar" till DEN GÅR INTE IN i interupt funktionen alls, har testat och den släcker inget utan den hopper helt enkelt över.
Då bilr det mao tex som nedan dådå.
Då får jag ändra "verkar" till DEN GÅR INTE IN i interupt funktionen alls, har testat och den släcker inget utan den hopper helt enkelt över.
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
#define PWM PORTD.F1
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 Print_Display(char *text1, char *text2){
BACKLIGHT=1;
Lcd_out(1,1,text1);
Lcd_out(2,1,text2);
}
void interrupt(){
SERVO=0;
BUZZ=1;
delay_ms(100);
BUZZ=0;
k=1;
BACKLIGHT=0;
}
void main() {
TRISA=0b00000000;
TRISB=0b00110011;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00000000;
LCDCON=0b00000000;
ANSELA=0;
ANSELB.F0=0;
INTCON.F0=1;
IOCBP.F0=1;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
if(k==1){
Print_Display("Servo Error!!!","Reset panel");
while(1){
SERVO=0;
BACKLIGHT=0;
}
}
BUZZ=1;
delay_ms(10);
BUZZ=0;
Print_Display("test1","test2");
}
Re: Hjälp med 16F1937
Jag kan inte se att du har någon loop i main().
Normalt har man en while loop med ett villkor som
aldrig blir "falskt". På en microprocessor ska programmet
i princip *aldrig* lämna main(), förrutom för interrupt...
Nu kör det bara rakt igenom en gång och sedan är det stopp.
Många kompilatorer lägger till en "catch all" loop efter main()
för det fall att man av misstag kommer dit. Sen vet i fasen vad
som händer då ditt interupt kommer, kanske en reset...
Normalt har man en while loop med ett villkor som
aldrig blir "falskt". På en microprocessor ska programmet
i princip *aldrig* lämna main(), förrutom för interrupt...
Nu kör det bara rakt igenom en gång och sedan är det stopp.
Många kompilatorer lägger till en "catch all" loop efter main()
för det fall att man av misstag kommer dit. Sen vet i fasen vad
som händer då ditt interupt kommer, kanske en reset...
Re: Hjälp med 16F1937
Klart det ska vara en main while. Den försvann under ngn copy paste tror jag 
Nu har jag försökt enabla rätt intcon bit och sedan sätta att den ska trigga på ökande flank men inget händer banne mig.
sedan ang att den verkar resetas när jag drar den hög är bara ibland så det kan ju vara ngt som är lite svajigt elektriskt

Nu har jag försökt enabla rätt intcon bit och sedan sätta att den ska trigga på ökande flank men inget händer banne mig.
sedan ang att den verkar resetas när jag drar den hög är bara ibland så det kan ju vara ngt som är lite svajigt elektriskt
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
#define PWM PORTD.F1
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 Print_Display(char *text1, char *text2){
BACKLIGHT=1;
Lcd_out(1,1,text1);
Lcd_out(2,1,text2);
}
void interrupt(){
SERVO=0;
BUZZ=1;
delay_ms(100);
BUZZ=0;
k=1;
BACKLIGHT=0;
}
void main() {
TRISA=0b00000000;
TRISB=0b00110011;
TRISC=0b11000000;
TRISD=0b00000000;
TRISE=0b00000000;
LCDCON=0b00000000;
ANSELA=0;
ANSELB=0;
INTCON=0b0010000;
IOCBP=0b00000001;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
BUZZ=1;
delay_ms(10);
BUZZ=0;
Print_Display("test1","test2");
while(1){
if(k==1){
Print_Display("Servo Error!!!","Reset panel");
while(1){
SERVO=0;
BACKLIGHT=0;
}
}
}
}
Re: Hjälp med 16F1937
Hur är det, har MikroC miljön (IDE't) någon slags simulator?
Något i stil med MPSIM för Microchips egna verktyg? När det gäller
i alla fall MPSIM så kan man köra simuleringen och med ett verktyg
simulera input till IOC pinnen.
Jag har inte jämfört dina inställningar mot databladet, men det är ju flera
register som måste "stå rätt" för att ett interrupt ska "gå igenom", så att säga.
IOCIE i INTCON t.ex. Är den satt?
Och så klart GIE, annars fungerar *inga* interrupt.
Se:
FIGURE 7-1: INTERRUPT LOGIC (sid 93)
REGISTER 7-1: INTCON: INTERRUPT CONTROL REGISTER (sid 98)
13.0 INTERRUPT-ON-CHANGE (sid 151)
Det känns som att det saknas något, ditt värde på INTCON känns fel...
Nu så vet jag inte i vilken ände som nollan saknades, så jag vet inte
hur det faktiskt är satt...
Något i stil med MPSIM för Microchips egna verktyg? När det gäller
i alla fall MPSIM så kan man köra simuleringen och med ett verktyg
simulera input till IOC pinnen.
Jag har inte jämfört dina inställningar mot databladet, men det är ju flera
register som måste "stå rätt" för att ett interrupt ska "gå igenom", så att säga.
IOCIE i INTCON t.ex. Är den satt?
Och så klart GIE, annars fungerar *inga* interrupt.
Se:
FIGURE 7-1: INTERRUPT LOGIC (sid 93)
REGISTER 7-1: INTCON: INTERRUPT CONTROL REGISTER (sid 98)
13.0 INTERRUPT-ON-CHANGE (sid 151)
Det känns som att det saknas något, ditt värde på INTCON känns fel...
Nu så vet jag inte i vilken ände som nollan saknades, så jag vet inte
hur det faktiskt är satt...
Re: Hjälp med 16F1937
IOCIE och GIE var inte satta.. har nu satt de och den går in i interuptet nu. jag har ju satt på att den ska trigga på pos flank men den verkar trigga på neg. Sedan har jag satt variabel k=1 för att den sedan i main ska skriva ut servo error men där hoppar den aldrig in.
Den släcker backlighten vilket är det sista som skall göras i interupten men sen händer inget mer. Måste man skriva ngt för att den skall lämna interuptet eller sköts det automatiskt?
Vet inte i nuläget om mikroc har simulator ska kolla upp det. dock vet jag att debugger finns men jag har ej använt den funktionen ännu.
Den släcker backlighten vilket är det sista som skall göras i interupten men sen händer inget mer. Måste man skriva ngt för att den skall lämna interuptet eller sköts det automatiskt?
Vet inte i nuläget om mikroc har simulator ska kolla upp det. dock vet jag att debugger finns men jag har ej använt den funktionen ännu.
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
#define PWM PORTD.F1
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;
ANSELA=0;
ANSELB=0;
INTCON=0b10011000;
IOCBP=0b00000001;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
}
void Print_Display(char *text1, char *text2){
BACKLIGHT=1;
Lcd_out(1,1,text1);
Lcd_out(2,1,text2);
}
void interrupt(){
SERVO=0;
BUZZ=1;
delay_ms(100);
BUZZ=0;
k=1;
BACKLIGHT=0;
}
void main() {
initMain();
BUZZ=1;
delay_ms(50);
BUZZ=0;
Print_Display("test11","test22");
while(1){
if(k==1){
Print_Display("Servo Error!!!","Reset panel");
while(1){
SERVO=0;
BACKLIGHT=0;
BUZZ=0;
}
}
- SeniorLemuren
- Inlägg: 8427
- Blev medlem: 26 maj 2009, 12:20:37
- Ort: Kristinehamn
Re: Hjälp med 16F1937
Jo det finns simulator i mikroC. Angående variabeln k, prova med att definiera den som volatile bit k=0;
Re: Hjälp med 16F1937
> ...men den verkar trigga på neg.
Var kommer signalen från? Annan elektronik? Tryckknapp?
Om du har en knapp så får du ju massor av både pos och
neg flanker *varje* gång du trycker! IOC fungerar inte bra
på t.ex tryckknappar eller något annan signal som inte
är "ren" från störningar eller kontaktstudsar.
> ...som skall göras i interupten men sen händer inget mer.
Vad är "mer" mer specifikt? Jag är ganska säker på att den kommer
tillbaka från interruptet till main(), men ofta/alltid så är det så att man
måste nollställa den flagga som fick interruptet att trigga. I detta fall
är det alltså IOCBF flaggorna, det ska göras i slutet av interrupt().
Annars så kommer det sannolikt att "loopa" tillbaka till interrupt()
direkt efter att den har avslutats. Kap 13.3 och 13.4 talar om det.
(Dock förstår jag inte direkt EXAMPLE 13-1, men man borde kunna
använda vanliga bit-operationer mot flaggorna, eller ange flaggorna
direkt i C-koden.)
Var kommer signalen från? Annan elektronik? Tryckknapp?
Om du har en knapp så får du ju massor av både pos och
neg flanker *varje* gång du trycker! IOC fungerar inte bra
på t.ex tryckknappar eller något annan signal som inte
är "ren" från störningar eller kontaktstudsar.
> ...som skall göras i interupten men sen händer inget mer.
Vad är "mer" mer specifikt? Jag är ganska säker på att den kommer
tillbaka från interruptet till main(), men ofta/alltid så är det så att man
måste nollställa den flagga som fick interruptet att trigga. I detta fall
är det alltså IOCBF flaggorna, det ska göras i slutet av interrupt().
Annars så kommer det sannolikt att "loopa" tillbaka till interrupt()
direkt efter att den har avslutats. Kap 13.3 och 13.4 talar om det.
(Dock förstår jag inte direkt EXAMPLE 13-1, men man borde kunna
använda vanliga bit-operationer mot flaggorna, eller ange flaggorna
direkt i C-koden.)