PICmicro & dsPIC >> Source Share for PICmicro & dsPIC

Pages: 1 | 2 | >> (show all)
Kappa



Reged: Oct 04 2004
Posts: 89
USART on interrupt example ...
      #31407 - Mon Dec 31 2007 05:58 AM

Hi all, this is an example for using RX and TX interrupt for transmit and receiving text message.

Some adjustment also in order to receive RAW messages.

It's possible to add a serial time-out using a timer, for reset USART module.

This is a example for PIC18F452:

Code:
  
// **********************************************************************
// * *
// * File name: main.c *
// * *
// * Since: 31 December 2007 *
// * *
// * Version: 0.01 *
// * *
// * Author: Kappa [KP] *
// * *
// * Purpose: *
// * USART Interrupt test program *
// * *
// * History: *
// * *
// * 31/12/2007 [KP] File creation *
// * 31/12/2007 [KP] First Release *
// * *
// **********************************************************************

#include <htc.h>
#include <stdio.h>
#include <string.h>

#define FALSE 0
#define TRUE 1

#define LOW 0
#define HIGH 1

#define UART_DIVIDER 64 // 9600 bps for 40 MHz Osc

#define BUFFER_USART_LEN 64 // Size of TX/RX USART Buffer

//
// Enumeration status serial
//
enum uart_status
{
WAITING, // Waiting byte on serial
RECEIVING, // Receiving byte on serial
READY, // Message on buffer
PROCESSING // Processing message
};

//
// Struct of serial buffer
//
struct buffer_serial_tx
{
unsigned char buffer[BUFFER_USART_LEN]; // Buffer data
unsigned char ptr; // Pointer to buffer
unsigned char counter; // Number of byte
};

struct buffer_serial_rx
{
unsigned char buffer[BUFFER_USART_LEN]; // Buffer data
unsigned char ptr; // Pointer to buffer
enum uart_status status; // Status buffer
unsigned char counter; // Number of byte
};

//
// TX and RX Buffer
//
struct uart
{
// Buffer di ricezione trasmissione
struct buffer_serial_tx tx;
struct buffer_serial_rx rx;
} rs232;

// **********************************************************************
// * *
// * Setup FUSE of CPU *
// * *
// **********************************************************************

__CONFIG(1, OSCSDIS & HSPLL);

#if defined(__MPLAB_ICD__)
__CONFIG(2, WDTPS128 & WDTDIS & BORV45 & BOREN & PWRTDIS);
#else
__CONFIG(2, WDTPS128 & WDTDIS & BORV45 & BOREN & PWRTEN);
#endif

__CONFIG(3, CCP2RC1);

#if defined(__MPLAB_ICD__)
__CONFIG(4, STVREN & LVPDIS & DEBUGEN);
#else
__CONFIG(4, STVREN & LVPDIS & DEBUGDIS);
#endif

__CONFIG(5, UNPROTECT);
__CONFIG(6, UNPROTECT);
__CONFIG(7, UNPROTECT);

// **********************************************************************
// * Descrizione: Interrupt Service Routine High Priority *
// * *
// * Returns: None *
// * *
// * Parameters: None *
// **********************************************************************

void interrupt ISR_high(void)
{
// **********************************************************************
// * *
// * Interrupt Receive Uart RS232 *
// * *
// **********************************************************************

if((RCIF) && (RCIE))
{
// Overrun error bit
if(OERR) //
{ //
CREN=0; // Restart USART
CREN=1; //
} //

// If error ...
if(FERR)
{
// Flush buffer
RCREG=RCREG;
RCREG=RCREG;
RCREG=RCREG;
}
else
{
// If Message absent on buffer or pointer if out of buffer
if((rs232.rx.status == WAITING) || (rs232.rx.ptr >= BUFFER_USART_LEN))
{
// Reset counter of RX bytes
rs232.rx.counter = 0;

// Reset pointer of RX bytes
rs232.rx.ptr = 0;

// USART Receiving ...
rs232.rx.status = RECEIVING;
}

//
// If Receiving ...
//
if(rs232.rx.status == RECEIVING)
{
// Download and store byte
rs232.rx.buffer[rs232.rx.ptr++] = RCREG;

// Counter byte
rs232.rx.counter++;

// Test if received CR+LF byte (0x0D - 0x0A)
if(rs232.rx.buffer[rs232.rx.ptr-1] == '\r')
{
// Message on Buffer ...
rs232.rx.status=READY;
}
}
else
{
// Flush buffer
RCREG=RCREG;
RCREG=RCREG;
RCREG=RCREG;
}
}
}
}

// **********************************************************************
// * Descrizione: Interrupt Service Routine Low Priority *
// * *
// * Returns: None *
// * *
// * Parameters: None *
// **********************************************************************

void interrupt low_priority ISR_low(void)
{
// **********************************************************************
// * *
// * Interrupt Transmit Usart RS232 *
// * *
// **********************************************************************

if((TXIF) && (TXIE))
{
// Bytes to send ...
if(rs232.tx.counter > 0)
{
// TX byte
TXREG = rs232.tx.buffer[rs232.tx.ptr];

// Point to next byte
if (++rs232.tx.ptr > BUFFER_USART_LEN)
rs232.tx.ptr = 0;
}

// End TX byte, disable interrupt ...
if(rs232.tx.counter == 0)
{
// END TX message
TXIE = 0;
}
else
{
// Decrement number of bytes
rs232.tx.counter--;
}
}
}

// **********************************************************************
// * Descrizione: Initialize CPU *
// * *
// * Returns: CPU Initialized *
// * *
// * Parameters: None *
// **********************************************************************

void init(void)
{
// **********************************************************************
// * *
// * Setup PORT C *
// * *
// **********************************************************************

//
// RC0 = Unused (Input - HIGH)
// RC1 = Unused (Input - HIGH)
// RC2 = Unused (Input - HIGH)
// RC3 = Unused (Input - HIGH)
// RC4 = Unused (Input - HIGH)
// RC5 = Unused (Input - HIGH)
// RC6 = TX Usart (Input - HIGH)
// RC7 = RX Usart (Input - HIGH)
//
PORTC = 0b11111111;
LATC = 0b11111111;
TRISC = 0b10111111;

// **********************************************************************
// * *
// * Setup UART Service *
// * *
// **********************************************************************

SPBRG = UART_DIVIDER; // Setup baudrate
TXSTA = 0b00100100;
RCSTA = 0b10010000;

RCIE = 1; // Attivo Interrupt Receive
RCIP = 1; // High Priority interrupt

TXIE = 0; // Reset Interrupt Trasmit
TXIP = 0; // Low Priority interrupt

// **********************************************************************
// * *
// * Setup Gestione interruzioni *
// * *
// **********************************************************************

IPEN=1; // Enable interrupt Priority
GIEL=1; // Enable interrupt Peripheral
GIEH=1; // Enable interrupt Global
}

// **********************************************************************
// * Descrizione: Main Routine *
// * *
// * Returns: None *
// * *
// * Parameters: None *
// **********************************************************************

void main(void)
{
// Initialize CPU
init();

// Initiaize status
rs232.rx.status = WAITING;

// Welcom message
rs232.tx.counter = sprintf(rs232.tx.buffer, "Welcomes on USART example on %s\r", __DATE__);
rs232.tx.ptr = 0;
TXIE = HIGH;

// Infinite loop
while(TRUE)
{
// Message on buffer ...
if(rs232.rx.status == READY)
{
// Processing buffer
rs232.rx.status = PROCESSING;

// Echo replay
memcpy(rs232.tx.buffer, rs232.rx.buffer, rs232.rx.counter);

// Number of TX char
rs232.tx.counter = rs232.rx.counter;

// Initialize TX pointer
rs232.tx.ptr = 0;

// Start TX
TXIE = HIGH;

// Reset RX Buffer
memset(rs232.rx.buffer, NULL, rs232.rx.counter);

// Reset Pointer and counter RX
rs232.rx.ptr = 0;
rs232.rx.counter = 0;

// Restart receive USART
rs232.rx.status = WAITING;
}
}
}




Kappa.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Tenson
newbie


Reged: Jul 20 2008
Posts: 49
Re: USART on interrupt example ... [Re: Kappa]
      #66332 - Mon Jul 21 2008 05:29 PM

Hi

I would like to remind you that variables/structures shared by ISR / main should be declared volatile.


Post Extras: Print Post   Remind Me!   Notify Moderator  
Legend
stranger


Reged: Dec 30 2008
Posts: 1
Loc: China
Re: USART on interrupt example ... [Re: Tenson]
      #91332 - Wed Dec 31 2008 03:30 AM

Quote:

Hi

I would like to remind you that variables/structures shared by ISR / main should be declared volatile.





agree^


Post Extras: Print Post   Remind Me!   Notify Moderator  
shahrul
newbie


Reged: Apr 23 2009
Posts: 38
Loc: Malaysia
Re: USART on interrupt example ... [Re: Legend]
      #109442 - Sun Apr 26 2009 11:31 PM

I try compile this code, but there is an error.
I don't understand, that void interrupt ISR_high(void) and void interrupt low_priority ISR_low(void) is the interrupt functions right?
Is that function need to be declared or not?
Why there is no setup on INTCON and PIE1 like INTCON=0b11000000;
PIE1=0b00100000;

--------------------
SHAHRULNIZAM.COM
SHAHRULNIZAM.WS


Post Extras: Print Post   Remind Me!   Notify Moderator  
Kappa



Reged: Oct 04 2004
Posts: 89
Re: USART on interrupt example ... [Re: shahrul]
      #109502 - Mon Apr 27 2009 03:25 AM

Hi,
Quote:


I try compile this code, but there is an error.





With that version of compiler ?

Quote:


I don't understand, that void interrupt ISR_high(void) and void interrupt low_priority ISR_low(void) is the interrupt functions right?





Check the manual of the compiler or some examples included with it.

Quote:


Is that function need to be declared or not?





For management to interrupt is to be declared.

Quote:


Why there is no setup on INTCON and PIE1 like INTCON=0b11000000;
PIE1=0b00100000;





In init() function :

Code:


RCIE = 1; // Attivo Interrupt Receive
RCIP = 1; // High Priority interrupt

TXIE = 0; // Reset Interrupt Trasmit
TXIP = 0; // Low Priority interrupt



Kappa.


Post Extras: Print Post   Remind Me!   Notify Moderator  
shahrul
newbie


Reged: Apr 23 2009
Posts: 38
Loc: Malaysia
Re: USART on interrupt example ... [Re: Kappa]
      #109512 - Mon Apr 27 2009 03:45 AM

Quote:


Quote:


I try compile this code, but there is an error.




With that version of compiler ?




I'm using software MPlab v8.2 with HI-TECH C Pro for the PIC10/12/16. I setup at device PIC16F877A.

Quote:

Quote:


I don't understand, that void interrupt ISR_high(void) and void interrupt low_priority ISR_low(void) is the interrupt functions right?




Check the manual of the compiler or some examples included with it.




I check the HI-TECH C Manual, but not available the function.


Quote:

Quote:


Why there is no setup on INTCON and PIE1 like INTCON=0b11000000;
PIE1=0b00100000;





In init() function :

Code:


RCIE = 1; // Attivo Interrupt Receive
RCIP = 1; // High Priority interrupt

TXIE = 0; // Reset Interrupt Trasmit
TXIP = 0; // Low Priority interrupt






Oh, I see that RCIE and TXIE. But in the PIC16F877A not available the RCIP and TXIP.
What is the alternative if I want to use with PIC16F877A?
Shahrul..

--------------------
SHAHRULNIZAM.COM
SHAHRULNIZAM.WS


Post Extras: Print Post   Remind Me!   Notify Moderator  
Dan HenryModerator
Guru
****

Reged: Oct 16 2003
Posts: 3866
Loc: Colorado
Re: USART on interrupt example ... [Re: shahrul]
      #109572 - Mon Apr 27 2009 10:12 AM

Quote:

I setup at device PIC16F877A.
Quote:


I don't understand, that void interrupt ISR_high(void) and void interrupt low_priority ISR_low(void) is the interrupt functions right?






PIC16s do not have interrupt priority levels.


Post Extras: Print Post   Remind Me!   Notify Moderator  
shahrul
newbie


Reged: Apr 23 2009
Posts: 38
Loc: Malaysia
Re: USART on interrupt example ... [Re: Dan Henry]
      #109602 - Mon Apr 27 2009 01:41 PM

Quote:

I setup at device PIC16F877A.



Quote:

PIC16s do not have interrupt priority levels.



So, how I want to write USART interrupt in PIC16s?

--------------------
SHAHRULNIZAM.COM
SHAHRULNIZAM.WS


Post Extras: Print Post   Remind Me!   Notify Moderator  
Dan HenryModerator
Guru
****

Reged: Oct 16 2003
Posts: 3866
Loc: Colorado
Re: USART on interrupt example ... [Re: shahrul]
      #109612 - Mon Apr 27 2009 03:45 PM

Quote:

So, how I want to write USART interrupt in PIC16s?



Adjust the code for your PIC (e.g., combine Tx and Rx interrupt handling into one interrupt function, delete lines dealing with priority level, resolve PORT and SFR differences, etc.).


Post Extras: Print Post   Remind Me!   Notify Moderator  
shahrul
newbie


Reged: Apr 23 2009
Posts: 38
Loc: Malaysia
Re: USART on interrupt example ... [Re: Dan Henry]
      #110252 - Mon May 04 2009 12:10 AM Attachment (97 downloads)

Quote:


Adjust the code for your PIC (e.g., combine Tx and Rx interrupt handling into one interrupt function, delete lines dealing with priority level, resolve PORT and SFR differences, etc.).




I have tried with this code
Code:
 
char DATA[4],V3,V4;
void interrupt ISR(void)
{int i;
//lcd_goto(0x00);
//lcd_string(" INTERRUPT ");
if(RCIF==1){
DATA[0]=DATA[1];
DATA[1]=DATA[2];
DATA[2]=DATA[3];
DATA[3]=DATA_IN;
if(DATA[2]==0x0F){
if(DATA[3]==0xF0){
V3=DATA[0];
V4=DATA[1];}}
}}



This function is to capture 4 byte data. I have succesfull using this function by call function. But, I'm fail to do this interrupt. This function not located in the interrupt vector (i.e address 0x04 for PIC16F877A).
What is my mistake?
Another problem, why I cannot call another function in the interrupt function?

--------------------
SHAHRULNIZAM.COM
SHAHRULNIZAM.WS


Post Extras: Print Post   Remind Me!   Notify Moderator  
Pages: 1 | 2 | >> (show all)



Extra information
0 registered and 6 anonymous users are browsing this forum.

Moderator:  jtemples, Dan Henry, Andrew L, mikerj 

Print Topic

Forum Permissions
      You cannot start new topics
      You cannot reply to topics
      HTML is enabled
      UBBCode is enabled

Rating: ****
Topic views: 10241

Rate this topic

Jump to

Contact Us | Privacy statement HI-TECH Software

Powered by UBB.threads™ 6.5.5