AVR interrupts in C++

AVR interrupts in C…
Defining interrupt handler function under gcc is quite simple. All you have to do is write your own function and name it with macro ISR(vector_name), enable interrupts and allow interrupt generation for selected peripheral. For example ISR for uart transmitter should look like this:


ISR(USART_TX_vect)
{
    Code sending next byte...
}

Such handler works in C and C++, it even might be sufficient. Anyway it’s not very friendly for object – oriented programming.

Interrupts and object-oriented programming…
Interrupt itself is kind of dysfunction in program processing. There are some methods to predict jump condition but processor can’t predict when will an interrupt occur. Every time interrupt occurs processor has to flush pipeline and jump to interrupt routine.
In C++ you can describe peripheral as a class, here is simple example for uart public interface:


class C_UART
{
public:
    /// Turning uart on, setting registers (baudrate...)
    void Init(void);
    /// Sending uiSize bytes of pBuffer.
    bool Send(char* pBuffer, unsigned int uiSize);
    /// Receiving uiSize bytes to pBuffer.
    bool Receive(char* pBuffer, unsigned int uiSize);
    /// Checking if uiSize of pBuffer is sent/received.
    bool IsTxReady(void)
    bool IsRxReady(void)
};

Such interface should be enough to send and receive sequence of bytes. In fact, because uart sends data byte after byte there has to be some data counters and local copies of pointers. They should be kept in private or protected area:


private:
    char* pTxBuffer;
    char* pRxBuffer;
    volatile unsigned int uiTxCounter;
    volatile unsigned int uiTxSize;
    volatile unsigned int uiRxCounter;
    volatile unsigned int uiRxSize;

Now it’s possible to check if uiTxCounter++ is equal to uiTxSize. If not – send next byte from pTxBuffer.
It’s what ISR should do, but it can operate on global/public variables only, it doesn’t have access to private members of objects.
First of all – I’m working with ATMega88, it has only one uart peripheral so I’ve added one static pointer to C_USART:


private:
    static C_UART* pUart;

Of course it’s possible to add static Create() method and use pUart as singleton, in this simple example it should be initiated in constructor of C_UART class (with this).
Also it could be an array of static pointers if there’s more then one instance of C_UART class (more then one uart peripheral so more interrupt sources also).
Because pUart is a static pointer so our uart object is now reachable, but it’s still inaccessible.
The definition of ISR(x) for USART_TX_vect macro looks like:


extern "C" void USART_TX_vect(void) __attribute__ ((signal));
void USART_RX_vect(void)

It’s not possible to make it class member, even static. But it’s possible to declare such function as a friend of C_UART class. Interrupt handler would be able to access static pUart and modify any of private members C_UART.
Here is my c_uart.h listing:


#ifndef _C_UART_H_
#define _C_UART_H_

extern "C" void USART_TX_vect(void) __attribute__ ((signal));
extern "C" void USART_RX_vect(void) __attribute__ ((signal));

class C_UART
{
private:
    char* pTxBuffer;
    char* pRxBuffer;
    volatile unsigned int uiTxCounter;
    volatile unsigned int uiTxSize;
    volatile unsigned int uiRxCounter;
    volatile unsigned int uiRxSize;
    static C_UART* pUart;
public:
    void Init(void);
    bool Send(char* pBuffer, unsigned int uiSize);
    bool Receive(char* pBuffer, unsigned int uiSize);
    bool IsTxReady(void);
    bool IsRxReady(void);
    C_UART();
    friend void USART_TX_vect(void);
    friend void USART_RX_vect(void);
};
#endif
About these ads

5 Responses to “AVR interrupts in C++”

  1. mojtaba Says:

    Can we use C++ for programming AVR microcontrollers?

  2. Janis Says:

    To ‘mojtaba’ (I know it’s late, but for someone else..):
    Yes, we surely can use C++ for programming AVR.
    On Windows WinAVR package have c++ compiler for avr.
    I use Eclipse CDT + WinAVR + AVRDude(for programming hardware) to make some code

  3. Elvis Says:

    What if I have to manage 4 serial ports? In the way you write I can use just a serial port

  4. Avr Code Examples,Avr Code,atmega128 code,source code Avr , Says:

    Avr Code Examples,Avr Code,atmega128 code,source code Avr ,…

    [...]AVR interrupts in C++ « Waterproofman[...]…

  5. Mike Says:

    Nice job I have included a link to your site from http://jaxcoder.com/Projects.aspx?id=788781549, a tutorial on “AVR Studio and C++”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: