I just recently decided to migrate an existing design which was based on Interrupt on change pins to standard IO polling due to some constraints in the part that I was using. I am trying to figure out the worst case time required to poll a GPIO for an event, process the event and exit the loop. I have seen the word "non-blocking" code thrown around various literature and my guess is that is what I would like to implement here. Any pointers or Pseudo-code would be very helpful. The part I am using is PIC18F85K22 and I am running the internal clock at 64MHz(Max).
PIC18 IO polling
interruptspic
Related Solutions
Remove all that config stuff, and just turn off the WDT. It should run off the 8 MHz internal oscillator, and flash your LED. I can do that with the similar PIC18F2455. If that doesn't work you might have a hardware problem.
You will find things much easier if you use MPLAB and the C18 compiler. If you don't want to use Windows you might be able to use the new MPLAB-X, there is a Linux version.
Every processor has its own special interrupt-handling quirks.
Microchip's PIC18F4331 page has links to an errata document and the PIC18F4331 datasheet. In particular, the datasheet has some good tips in section 20 "Enhanced universal synchronous asynchronous receiver transmitter (EUSART)" and even more particularly, the 3 steps listed in section 20.0 and the 10 steps of "To set up an Asynchronous Reception" in section 20.3.2.
I've changed a few things that look like they might help:
// WARNING: untested code
int main(void){
//***********************Initializing Values****************************//
unsigned int ResultADC, FLAG;
unsigned char temp, idle; //High Byte result store, 8bits long
//***********************ADC and SPI Settings****************************//
Initialize_control(); //Initialize Control Configuration Pins
InitializeADC(); //Initialize ADC in Continuous Mode
USART_initialize(); //Initialize USART module
InitializeMasterSPI(); //Initialize SPI module
//***********************ADC Capture and Output to SPI******************//
while(1){ //While ADC buffer has something
//Enable transmission
TXREG = 0xff; //Debugger
while(!TXSTAbits.TRMT);//wait while TSR is full
TXREG = 0x0; //Debugger
while(!TXSTAbits.TRMT);//wait while TSR is full
}
return 0;
}
//////////////////INTERRUPT SERVICE ROUTINE/////////////////
static void interrupt isr(void){
// The PIC hardware has already disabled global interrupts
// by the time it starts executing the ISR,
// so there's no need to do "PIE1bits.RCIE = 0;".
int count;
//Read USART data
//PIR1bits.RCIF;//Data has been passed to RCREG
RX_Data[count] = RCREG; //Read RX register
count++;
//Reading RCREG automatically clears the RX flag.
// so there's no need to do "PIR1bits.RCIF = 0;".
// Q: How to read more than 1 byte?
// A: FIGURE 20-5 of the datasheet
// Implies that there's only a 1 byte buffer.
// Therefore, to read more than 1 byte, we must:
// pull the current byte out of the hardware buffer,
// store it in a software buffer RX_Data[] in RAM,
// then return to normal background main loop
// until the next byte in the message
// triggers another interrupt.
// Would it be better to do the following in the main loop?
if (count==3){
//Use data for control
Control_Arduino(RX_Data);
count = 0;
}
/*
The datasheet p. 229 is a little confusing about
whether "CREN" should be set (step 5) or cleared (step 9).
p. 219 which clearly seems to say CREN should be set.
But maybe it needs to be cleared to flush out any errors,
and then be set?
Are the following 2 lines really necessary?
*/
RCSTAbits.CREN = 0; //clear error (if any)
RCSTAbits.CREN = 1; //Enables Receiver
// the PIC hardware enables global interrupts
// automatically during the return-from-interrupt,
// so there's no need to do a "PIE1bits.RCIE = 1;"
// See the datasheet section 10.0: "Interrupts" for details.
}
//**********************Functions****************************//
void USART_initialize(void){
//Configuration TX and RX pins
// *normally* we use a "0" to indicate "output",
// but the TX output pin is different, see p. 217 of datasheet
TRISCbits.RC6 = 1; //TX output
TRISCbits.RC7 = 1; //RX input
//TXSTA: Transmit Status and Control Register
TXSTAbits.SYNC = 0; //Asynchronous mode
TXSTAbits.TX9 = 0; //8bit transmission
TXSTAbits.BRGH = 1; //Set HIGH Baud rate
TXSTAbits.TXEN = 1; //Enable transmitter
TXSTAbits.SENDB = 0; //Disable break
//RCSTA: Receive Status and Control Register
RCSTAbits.SPEN = 1; //Serial Port enabled
RCSTAbits.RX9 = 0; //8bit reception
RCSTAbits.CREN = 1; //Enables Receiver
//Test bits
// RCSTAbits.FERR = 0; //No framing error, cleared by reading
// RCSTAbits.OERR = 0; //No Overrun error, cleared by clearing CREN
//Disable receiver CREN 0
//BAUDCON Control register
BAUDCONbits.BRG16 = 1; //16bit baud rate generator
SPBRG = 0xCF; // Set to 19200 baud rate, 12Mhz, High Speed, BRG16
//Test bits
// BAUDCONbits.RCIDL = 0; //Receive in progress
// USART interrupts configuration
RCONbits.IPEN = 1; // ENABLE interrupt priority
// (p. 4 of http://www.gooligum.com.au/tutorials/midrange/PIC_Mid_C_3.pdf )
ei(); // same as INTCONbits.GIE = 1; // ENABLE interrupts
INTCONbits.PEIE = 1; // ENable peripheral interrupts.
PIE1bits.RCIE = 1; // ENABLE USART receive interrupt
PIE1bits.TXIE = 0; // disable USART TX interrupt
// make sure the RX flag is clear
PIR1bits.RCIF = 0;
}
Other code online:
"AN944: Using the EUSART on the PIC16F688" http://www.gooligum.com.au/tutorials/midrange/PIC_Mid_C_3.pdf https://forum.sparkfun.com/viewtopic.php?t=7542 http://panteltje.com/panteltje/pic/scope_pic/ http://www.microchip.com/forums/m411875.aspx http://www.enmcu.com/guides/autobaudratebasedoneusartmodule
Tell us if you ever figure out the real problem, OK?
Related Topic
- Acknowledge polling in EEPROM
- Electronic – PIC18 electric connection loose
- PIC32 does not get UART RX interrupts in xc32 Compiler
- Electronic – PIC18 High Priority Interrupt doesn’t Interrupt the Low one (xc8)
- PIC18 and RTCC combination
- Electronic – STM32F7 gets stuck in external interrupt callback function
- Electronic – Low Jitter and Latency on signal trigger using WFI / WFE on STM32F405
Best Answer
A non blocking call to a portion of code usually implies the request for a resource, such as a printer, or an event in your case.
If the printer is busy, or the event has not happened, there are two possibilities:
the first option is blocking: the code execution is halted in what is called busy waiting, or spooling. The processor can't do anything and that is a waste of power and time.
the second way is non blocking: the code executions continues, the processor can do something else, possibly servicing other events, then check back later. The problem is that if your event expires in some way code execution may well not come back in time.
Some pseudo c to illustrate an example of busy wait:
Non blocking wait:
Please note: the above samples assume that the functions event_n_has_happened return immediately whether the event has happened or not. They might be something like checking if an input pin is high or low, or whatever.