Jag skriver kod för att ta emot data via UART samtidigt som jag genererar 3 st PWM signaler mha interrupt på Timer0. När jag fått in relevant data sparas detta undan i en array som sedan skrivs ut via UART.
Jag har märkt att om jag kör init_timer(); så går inte processorn varken in i main() och heller inte in i switch-satsen som finns i ISR:en för UART delen.
Men om jag utesluter init_timer(); så kommer jag in i switch-satsen och relevant data läggs in i min array för att sedan skrivas ut i main(). Då kommer naturligtvis inga PWM signaler..
Har kontrollerat allt med en logikanalysator och kan se att mina PWM signaler kommer när jag kör med init_timer() men det kommer ingen utskrift från UARTen.
Har även kört ett eko direkt när jag tar emot ett tecken på UART dvs. c = RCREG; --> putch(c); och då kommer data.. Men den går aldrig in i switchen..
Kan detta ha att göra med prioritet i ISR? Jag har ju två olika typer av avbrott UART och Timer0.. Är det att processorn helt enkelt inte hinner gå in i switchen?
Någon som tror sig veta svaret på denna "gåta"?
För övrigt så är det fråga om en PIC18F14k50 med intern osc på 16MHz och Hi-techs kompilator..
Kod: Markera allt
#include <htc.h>
//#include "delay.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include "math.h"
#define LED1 LATC2
#define LED2 LATC1
#define LED3 LATC0
unsigned int t = 0;
unsigned char duty_LED1,duty_LED2,duty_LED3;
#define PWM_LIMIT 465
enum {START_WAIT, RECEIVING, MSG_RECEIVED} state = START_WAIT;
#define BUFFMAX 80
unsigned char gps_string[BUFFMAX] = 0; //Databuffer
int head = 0;
void init_PIC(void);
void init_interrupts();
void usart(void);
void init_timer(void);
void interrupt pic_isr(void);
void putch(unsigned char c);
void main(void){
duty_LED1 = 53;
duty_LED2 = 42;
duty_LED3 = 28;
init_PIC();
usart();
init_interrupts();
TMR0 = 255;
//init_timer();
while(1){
if(state == MSG_RECEIVED){
if(gps_string[4]=='C'){
for(int i = 0; i<head; i++){
putch(gps_string[i]);
}
}
state = START_WAIT;
}
}
}
void init_PIC(void){
OSCCON =0b11111111; //Internal 16MHz
OSCCON2 =0b00000000;
OSCTUNE = 0b00000000;
TRISC = 0;
PORTC = 0;
}
void init_interrupts(void){
GIE = 1; //*Interrupts
PEIE = 1;
TXIE = 0; //Disable transmit interrupt
RCIE = 1; //Enable receive interrupt
TMR0IE = 1; //TMR0 overflow enable bit
TMR0IF = 0; //TMR0 overflow flag bit
}
void usart(void){
TRISB = 0XFF;
TXEN = 1; //Allows sending
SYNC = 0; //The SYNC bit should be cleared to select asynchronous operation.
SPEN = 1; //SPEN bit is used to enable the entire serial port
ANSELH = ANSELH & 0b11110111; //ANSELH(3) ANS11: RB5 Analog Select Control bit, 0 = Digital input buffer of RB5 is enabled
BRGH = 0;
SPBRG = 51; // 4800
BRG16 = 0;
TX9 = 0;
RX9 = 0;
CREN = 0;
CREN = 1; //Allows receiving
}
void init_timer(void){
T08BIT = 1;
T0CS = 0; //timer mode
T0SE = 0;
PSA = 1; // prescaler
T0PS0 = 1;
T0PS1 = 1;
T0PS2 = 1;
TMR0ON = 1;
}
void interrupt pic_isr(void) {
unsigned char c;
if((RCIE)&&(RCIF)){ // If this interrupt was generated by a receive character
c = RCREG;
//putch(c);
switch(state){
case START_WAIT:
if(c == '$'){
head = 0;
state = RECEIVING;
}
break;
case RECEIVING:
if(c == '*'){
state = MSG_RECEIVED;
}
else{
gps_string[head] = c;
if(++head >= sizeof(gps_string)){
state = START_WAIT;
}
}
break;
}
}
if (TMR0IF == 1) {
TMR0IF = 0;
if(t<=duty_LED1){
LED1 = 1;
}
else if(t>duty_LED1){
LED1 = 0;
}
if(t<=duty_LED2){
LED2 = 1;
}
else if(t>duty_LED2){
LED2 = 0;
}
if(t<=duty_LED3){
LED3 = 1;
}
else if(t>duty_LED3){
LED3 = 0;
}
t++;
if(t>PWM_LIMIT){
t = 0;
}
TMR0 = 255;
}
if(OERR){ // If we missed a character (Overrun Error)
CREN = 0; // Reset the error bit
CREN = 1;
}
if(FERR){ // If Framing Error
c = RCREG; // Reset the error bit
CREN = 0; // Reset the error bit
CREN = 1;
}
}
void putch(unsigned char c){
while(!TXIF) //Set when TXREG is empty
continue; //Continue looping while TXREG is not available
TXREG = c; //Put character to be sent onto TXREG
}