UC Software voorbeelden voor de opdrachten 1-6 + Appendices

In onderstaande “snippets” staan de codevoorbeelden voor de microcontroller opdrachten.

Opdracht 1:

/*
 * Getting Started with AVR: Finding Documentation and Turning on an LED (#2)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#include <avr/io.h>

int main(void)
{
    DDRB |= (1<<DDB5);
    
   /* Let op dit is inderdaad een oneindige lus ! */
    while(1)
    {
        // TODO: Please write your application code
        // Set port B5
        PORTB |= (1<<PORTB5);
    }
}
/*
 * Getting Started with AVR: Finding Documentation and Turning on an LED (#2)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // 16 MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB |= (1<<DDB5);
    
    while(1)
    {
        // TODO: Please write your application code
        // Toggle port B5
        PINB = (1<<PINB5);
        
        _delay_ms(500);
    }
}

Opdracht 2:

/*
 * Getting Started with AVR: Read an I/O as Input to Turn on LED (#4)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // 16 MHz

#include <avr/io.h>
#include <util/delay.h>

#define LED_ON     PORTB |=  (1<<PORTB5)
#define LED_OFF    PORTB &= ~(1<<PORTB5)
#define LED_TOGGLE PINB   =  (1<<PINB5)

int main(void)
{
    DDRB |=  (1<<DDB5);
    DDRB &= ~(1<<DDB7);
    
    while(1)
    {
        // TODO: Please write your application code
        if(!(PINB & (1<<PINB7))) // If PINB7 is low
        {
            LED_ON;
        }
        else
        {
            LED_OFF;
        }
    }
}
/*
 * Getting Started with AVR: Using Pin Change Interrupts (#5)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // 16 MHz

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define LED_ON     PORTB |=  (1<<PORTB5)
#define LED_OFF    PORTB &= ~(1<<PORTB5)
#define LED_TOGGLE PINB   =  (1<<PINB5)

#define SWITCH_PRESSED !(PINB & (1<<PINB7))

ISR(PCINT0_vect)
{
    if(SWITCH_PRESSED)
    {
        LED_ON;
    }
    else
    {
        LED_OFF;
    }    
}

int main(void)
{
    DDRB |= (1<<DDB5);
    DDRB &= ~(1<<DDB7);
    
    PCMSK0 |= (1<<PCINT7);
    PCICR  |= (1<<PCIE0);
    
    sei();
    
    while(1)
    {
        // TODO: Please write your application code
    }
}

Opdracht 3:

/*
 * Getting Started with AVR: Using Timer Overflow IRQs (#7)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // 16 MHz

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define LED_ON     PORTB |=  (1<<PORTB5)
#define LED_OFF    PORTB &= ~(1<<PORTB5)
#define LED_TOGGLE PINB   =  (1<<PINB5)

ISR(TIMER1_OVF_vect)
{
    LED_TOGGLE;
}

int main(void)
{
    DDRB |= (1<<DDB5);
    DDRB &= ~(1<<DDB7);

    TCCR1B |= (1<<CS12);
    TIMSK1 |= (1<<TOIE1);
    
    sei();
    
    while(1)
    {
        ; // Do nothing
    }
}

Opdracht 4:

/*
 * Getting Started with AVR: Using Timer Compare Match IRQs (#8)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // 16 MHz

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define LED_ON     PORTB |=  (1<<PORTB5)
#define LED_OFF    PORTB &= ~(1<<PORTB5)
#define LED_TOGGLE PINB   =  (1<<PINB5)

ISR(TIMER1_COMPA_vect)
{
    LED_TOGGLE;
}

void Timer_Frequency(uint8_t freq)
{
    // Initialize Timer 1:
    // - 256 prescaler
    // - CTC mode of operation
    TCCR1B |= (1<<CS12) | (1<<WGM12);
    
    // Enable output compare match interrupt for channel A
    TIMSK1 |= (1<<OCIE1A);    
    
    // Set output compare value for channel A
    // OCRnA = (F_CPU / (frequency * 2 * N)) - 1
    OCR1A = (F_CPU / (freq * 2 * 256)) - 1;
}

int main(void)
{
    DDRB |= (1<<DDB5);
    DDRB &= ~(1<<DDB7);

    Timer_Frequency(4);
    
    sei();
    
    while(1)
    {
        ; // Do nothing
    }
}

Opdracht 5:

/*	
 * Getting Started with AVR: Using the AVR USART to Loopback From a Serial Terminal
 * (#16)
 *
 * Initially created by Glen Nilsen
 * Revised for HAN University of Applied Sciences by Hugo Arends
 */

#define F_CPU 16000000UL // Clock speed
#define BAUD 9600
#define MYUBRR (F_CPU/16/BAUD-1)

#include <avr/io.h>

unsigned char USART_Receive(void)
{
    // Wait for data to be received
    while( !(UCSR0A & (1<<RXC0)) )
    {;}

    // Get and return received data from buffer
    return UDR0;
}

void USART_Transmit(unsigned char data)
{
    // Wait for empty transmit buffer
    while( !( UCSR0A & (1<<UDRE0)) )
    {;}

    // Put data into buffer, sends the data
    UDR0 = data;
}
void USART_Init(unsigned int ubrr)
{
    // Set baud rate
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;

    // Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

    // Set frame format: 8 data, 1 stop bit
    UCSR0C = (3<<UCSZ00);
}

int main(void)
{
    USART_Init(MYUBRR);
    
    // Replace with your application code
    while(1) 
    {
        USART_Transmit( USART_Receive() );
    }
}
    while(1) 
    {
        unsigned char data;
        
        // Wait for a character from the USART
        data = USART_Receive();
        
        // Echo the character
        USART_Transmit(data);
        
        // Verify the received character
        if(data == '1')
        {
            USART_Transmit('!');
        }
    }

Appendix B : Uart interrupt voorbeeld.

/**
* \file
*
* \brief UART Interrupt example
*
* Copyright (C) 2016 Atmel Corporation. All rights reserved.
* Modified by H. Arends for HAN University of Applied Sciences to support
* the ATmega328P microcontroller for the MIC1 lab.
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Support and FAQ: visit
* <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "avr/io.h"
#include "avr/interrupt.h"

#define F_CPU 16000000UL
#include "util/delay.h"

#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 32

#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE - 1)
#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)
    #error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE - 1)
#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)
    #error TX buffer size is not a power of 2
#endif

/* Static Variables */
static char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile char UART_RxHead;
static volatile char UART_RxTail;

static char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile char UART_TxHead;
static volatile char UART_TxTail;

/* Prototypes */
void InitUART(unsigned int ubrr_val);
char ReceiveByte(void);
void TransmitByte(char data);
unsigned char nUnreadBytes(void);
void ReceiveString(char *str);
void TransmitString(char *str);

int main(void)
{
    /* Initialize the UART */
    InitUART(MYUBRR);
    sei();
    
    while(1)
    {
        // CPU is busy doing something else...
        _delay_ms(1000);
        
        // Check for unread bytes in the receive buffer
        unsigned char nBytes = nUnreadBytes();
        
        // If there are unread bytes, receive them all and echo back
        // (Note: Make sure LF is enabled in Terminal Window)
        if(nBytes > 0)
        {
            char str[30];
            ReceiveString(str);
            TransmitString(str);
        }
    }

    return 0;
}

/* Initialize UART */
void InitUART(unsigned int ubrr_val)
{
    char x;
    
    /* Set the baud rate */
    UBRR0H = (unsigned char)(ubrr_val>>8);
    UBRR0L = (unsigned char)ubrr_val;
    
    /* Enable UART receiver and transmitter */
    UCSR0B = ((1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0));
    
    /* Flush receive buffer */
    x = 0;
    UART_RxTail = x;
    UART_RxHead = x;
    UART_TxTail = x;
    UART_TxHead = x;
}

/* Interrupt handlers */
ISR(USART_RX_vect)
{
    char data;
    unsigned char tmphead;
    
    /* Read the received data */
    data = UDR0;
    
    /* Calculate buffer index */
    tmphead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxHead = tmphead;
    
    if (tmphead == UART_RxTail)
    {
        /* ERROR! Receive buffer overflow */
    }
    
    /* Store received data in buffer */
    UART_RxBuf[tmphead] = data;
}

ISR(USART_UDRE_vect)
{
    unsigned char tmptail;
    
    /* Check if all data is transmitted */
    if (UART_TxHead != UART_TxTail)
    {
        /* Calculate buffer index */
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        
        /* Store new index */
        UART_TxTail = tmptail;
        
        /* Start transmission */
        UDR0 = UART_TxBuf[tmptail];
    }
    else
    {
        /* Disable UDRE interrupt */
        UCSR0B &= ~(1<<UDRIE0);
    }
}

char ReceiveByte(void)
{
    unsigned char tmptail;
    
    /* Wait for incoming data */
    while (UART_RxHead == UART_RxTail);
    
    /* Calculate buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxTail = tmptail;
    
    /* Return data */
    return UART_RxBuf[tmptail];
}

void TransmitByte(char data)
{
    unsigned char tmphead;
    
    /* Calculate buffer index */
    tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    /* Wait for free space in buffer */
    while (tmphead == UART_TxTail);
    
    /* Store data in buffer */
    UART_TxBuf[tmphead] = data;
    
    /* Store new index */
    UART_TxHead = tmphead;
    
    /* Enable UDRE interrupt */
    UCSR0B |= (1<<UDRIE0);
}

/*
 * This function returns the number of unread bytes in the receive buffer
 */
unsigned char nUnreadBytes(void)
{
    if(UART_RxHead == UART_RxTail)
        return 0;
    else if(UART_RxHead > UART_RxTail)
        return UART_RxHead - UART_RxTail;
    else
        return UART_RX_BUFFER_SIZE - UART_RxTail + UART_RxHead;
}

/*
 * This function gets a string of characters from the USART.
 * The string is placed in the array pointed to by str.
 *
 * - This function uses the function ReceiveByte() to get a byte
 *   from the UART.
 * - If the received byte is equal to '\n' (Line Feed),
 *   the function returns.
 * - The array is terminated with ´
/**
* \file
*
* \brief UART Interrupt example
*
* Copyright (C) 2016 Atmel Corporation. All rights reserved.
* Modified by H. Arends for HAN University of Applied Sciences to support
* the ATmega328P microcontroller for the MIC1 lab.
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Support and FAQ: visit
* <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "avr/io.h"
#include "avr/interrupt.h"

#define F_CPU 16000000UL
#include "util/delay.h"

#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 32

#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE - 1)
#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)
    #error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE - 1)
#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)
    #error TX buffer size is not a power of 2
#endif

/* Static Variables */
static char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile char UART_RxHead;
static volatile char UART_RxTail;

static char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile char UART_TxHead;
static volatile char UART_TxTail;

/* Prototypes */
void InitUART(unsigned int ubrr_val);
char ReceiveByte(void);
void TransmitByte(char data);
unsigned char nUnreadBytes(void);
void ReceiveString(char *str);
void TransmitString(char *str);

int main(void)
{
    /* Initialize the UART */
    InitUART(MYUBRR);
    sei();
    
    while(1)
    {
        // CPU is busy doing something else...
        _delay_ms(1000);
        
        // Check for unread bytes in the receive buffer
        unsigned char nBytes = nUnreadBytes();
        
        // If there are unread bytes, receive them all and echo back
        // (Note: Make sure LF is enabled in Terminal Window)
        if(nBytes > 0)
        {
            char str[30];
            ReceiveString(str);
            TransmitString(str);
        }
    }

    return 0;
}

/* Initialize UART */
void InitUART(unsigned int ubrr_val)
{
    char x;
    
    /* Set the baud rate */
    UBRR0H = (unsigned char)(ubrr_val>>8);
    UBRR0L = (unsigned char)ubrr_val;
    
    /* Enable UART receiver and transmitter */
    UCSR0B = ((1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0));
    
    /* Flush receive buffer */
    x = 0;
    UART_RxTail = x;
    UART_RxHead = x;
    UART_TxTail = x;
    UART_TxHead = x;
}

/* Interrupt handlers */
ISR(USART_RX_vect)
{
    char data;
    unsigned char tmphead;
    
    /* Read the received data */
    data = UDR0;
    
    /* Calculate buffer index */
    tmphead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxHead = tmphead;
    
    if (tmphead == UART_RxTail)
    {
        /* ERROR! Receive buffer overflow */
    }
    
    /* Store received data in buffer */
    UART_RxBuf[tmphead] = data;
}

ISR(USART_UDRE_vect)
{
    unsigned char tmptail;
    
    /* Check if all data is transmitted */
    if (UART_TxHead != UART_TxTail)
    {
        /* Calculate buffer index */
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        
        /* Store new index */
        UART_TxTail = tmptail;
        
        /* Start transmission */
        UDR0 = UART_TxBuf[tmptail];
    }
    else
    {
        /* Disable UDRE interrupt */
        UCSR0B &= ~(1<<UDRIE0);
    }
}

char ReceiveByte(void)
{
    unsigned char tmptail;
    
    /* Wait for incoming data */
    while (UART_RxHead == UART_RxTail);
    
    /* Calculate buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxTail = tmptail;
    
    /* Return data */
    return UART_RxBuf[tmptail];
}

void TransmitByte(char data)
{
    unsigned char tmphead;
    
    /* Calculate buffer index */
    tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    /* Wait for free space in buffer */
    while (tmphead == UART_TxTail);
    
    /* Store data in buffer */
    UART_TxBuf[tmphead] = data;
    
    /* Store new index */
    UART_TxHead = tmphead;
    
    /* Enable UDRE interrupt */
    UCSR0B |= (1<<UDRIE0);
}

/*
 * This function returns the number of unread bytes in the receive buffer
 */
unsigned char nUnreadBytes(void)
{
    if(UART_RxHead == UART_RxTail)
        return 0;
    else if(UART_RxHead > UART_RxTail)
        return UART_RxHead - UART_RxTail;
    else
        return UART_RX_BUFFER_SIZE - UART_RxTail + UART_RxHead;
}

/*
 * This function gets a string of characters from the USART.
 * The string is placed in the array pointed to by str.
 *
 * - This function uses the function ReceiveByte() to get a byte
 *   from the UART.
 * - If the received byte is equal to '\n' (Line Feed),
 *   the function returns.
 * - The array is terminated with ´\0´.
 */
void ReceiveString(char *str)
{
    uint8_t t = 0;
    
    while ((str[t] = ReceiveByte()) != '\n')
    {
        t++;
    }
    str[t++] = '\n';
    str[t] = '\0';
}

/*
 * Transmits a string of characters to the USART.
 * The string must be terminated with '\0'.
 *
 * - This function uses the function TransmitByte() to
 *   transmit a byte via the UART
 * - Bytes are transmitted until the terminator
 *   character '\0' is detected. Then the function returns.
 */
void TransmitString(char *str)
{
    while(*str)
    {
        TransmitByte(*str++);
    }
}
´. */ void ReceiveString(char *str) { uint8_t t = 0; while ((str[t] = ReceiveByte()) != '\n') { t++; } str[t++] = '\n'; str[t] = '
/**
* \file
*
* \brief UART Interrupt example
*
* Copyright (C) 2016 Atmel Corporation. All rights reserved.
* Modified by H. Arends for HAN University of Applied Sciences to support
* the ATmega328P microcontroller for the MIC1 lab.
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Support and FAQ: visit
* <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "avr/io.h"
#include "avr/interrupt.h"

#define F_CPU 16000000UL
#include "util/delay.h"

#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 32

#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE - 1)
#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)
    #error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE - 1)
#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)
    #error TX buffer size is not a power of 2
#endif

/* Static Variables */
static char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile char UART_RxHead;
static volatile char UART_RxTail;

static char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile char UART_TxHead;
static volatile char UART_TxTail;

/* Prototypes */
void InitUART(unsigned int ubrr_val);
char ReceiveByte(void);
void TransmitByte(char data);
unsigned char nUnreadBytes(void);
void ReceiveString(char *str);
void TransmitString(char *str);

int main(void)
{
    /* Initialize the UART */
    InitUART(MYUBRR);
    sei();
    
    while(1)
    {
        // CPU is busy doing something else...
        _delay_ms(1000);
        
        // Check for unread bytes in the receive buffer
        unsigned char nBytes = nUnreadBytes();
        
        // If there are unread bytes, receive them all and echo back
        // (Note: Make sure LF is enabled in Terminal Window)
        if(nBytes > 0)
        {
            char str[30];
            ReceiveString(str);
            TransmitString(str);
        }
    }

    return 0;
}

/* Initialize UART */
void InitUART(unsigned int ubrr_val)
{
    char x;
    
    /* Set the baud rate */
    UBRR0H = (unsigned char)(ubrr_val>>8);
    UBRR0L = (unsigned char)ubrr_val;
    
    /* Enable UART receiver and transmitter */
    UCSR0B = ((1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0));
    
    /* Flush receive buffer */
    x = 0;
    UART_RxTail = x;
    UART_RxHead = x;
    UART_TxTail = x;
    UART_TxHead = x;
}

/* Interrupt handlers */
ISR(USART_RX_vect)
{
    char data;
    unsigned char tmphead;
    
    /* Read the received data */
    data = UDR0;
    
    /* Calculate buffer index */
    tmphead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxHead = tmphead;
    
    if (tmphead == UART_RxTail)
    {
        /* ERROR! Receive buffer overflow */
    }
    
    /* Store received data in buffer */
    UART_RxBuf[tmphead] = data;
}

ISR(USART_UDRE_vect)
{
    unsigned char tmptail;
    
    /* Check if all data is transmitted */
    if (UART_TxHead != UART_TxTail)
    {
        /* Calculate buffer index */
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        
        /* Store new index */
        UART_TxTail = tmptail;
        
        /* Start transmission */
        UDR0 = UART_TxBuf[tmptail];
    }
    else
    {
        /* Disable UDRE interrupt */
        UCSR0B &= ~(1<<UDRIE0);
    }
}

char ReceiveByte(void)
{
    unsigned char tmptail;
    
    /* Wait for incoming data */
    while (UART_RxHead == UART_RxTail);
    
    /* Calculate buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxTail = tmptail;
    
    /* Return data */
    return UART_RxBuf[tmptail];
}

void TransmitByte(char data)
{
    unsigned char tmphead;
    
    /* Calculate buffer index */
    tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    /* Wait for free space in buffer */
    while (tmphead == UART_TxTail);
    
    /* Store data in buffer */
    UART_TxBuf[tmphead] = data;
    
    /* Store new index */
    UART_TxHead = tmphead;
    
    /* Enable UDRE interrupt */
    UCSR0B |= (1<<UDRIE0);
}

/*
 * This function returns the number of unread bytes in the receive buffer
 */
unsigned char nUnreadBytes(void)
{
    if(UART_RxHead == UART_RxTail)
        return 0;
    else if(UART_RxHead > UART_RxTail)
        return UART_RxHead - UART_RxTail;
    else
        return UART_RX_BUFFER_SIZE - UART_RxTail + UART_RxHead;
}

/*
 * This function gets a string of characters from the USART.
 * The string is placed in the array pointed to by str.
 *
 * - This function uses the function ReceiveByte() to get a byte
 *   from the UART.
 * - If the received byte is equal to '\n' (Line Feed),
 *   the function returns.
 * - The array is terminated with ´\0´.
 */
void ReceiveString(char *str)
{
    uint8_t t = 0;
    
    while ((str[t] = ReceiveByte()) != '\n')
    {
        t++;
    }
    str[t++] = '\n';
    str[t] = '\0';
}

/*
 * Transmits a string of characters to the USART.
 * The string must be terminated with '\0'.
 *
 * - This function uses the function TransmitByte() to
 *   transmit a byte via the UART
 * - Bytes are transmitted until the terminator
 *   character '\0' is detected. Then the function returns.
 */
void TransmitString(char *str)
{
    while(*str)
    {
        TransmitByte(*str++);
    }
}
'; } /* * Transmits a string of characters to the USART. * The string must be terminated with '
/**
* \file
*
* \brief UART Interrupt example
*
* Copyright (C) 2016 Atmel Corporation. All rights reserved.
* Modified by H. Arends for HAN University of Applied Sciences to support
* the ATmega328P microcontroller for the MIC1 lab.
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Support and FAQ: visit
* <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "avr/io.h"
#include "avr/interrupt.h"

#define F_CPU 16000000UL
#include "util/delay.h"

#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 32

#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE - 1)
#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)
    #error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE - 1)
#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)
    #error TX buffer size is not a power of 2
#endif

/* Static Variables */
static char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile char UART_RxHead;
static volatile char UART_RxTail;

static char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile char UART_TxHead;
static volatile char UART_TxTail;

/* Prototypes */
void InitUART(unsigned int ubrr_val);
char ReceiveByte(void);
void TransmitByte(char data);
unsigned char nUnreadBytes(void);
void ReceiveString(char *str);
void TransmitString(char *str);

int main(void)
{
    /* Initialize the UART */
    InitUART(MYUBRR);
    sei();
    
    while(1)
    {
        // CPU is busy doing something else...
        _delay_ms(1000);
        
        // Check for unread bytes in the receive buffer
        unsigned char nBytes = nUnreadBytes();
        
        // If there are unread bytes, receive them all and echo back
        // (Note: Make sure LF is enabled in Terminal Window)
        if(nBytes > 0)
        {
            char str[30];
            ReceiveString(str);
            TransmitString(str);
        }
    }

    return 0;
}

/* Initialize UART */
void InitUART(unsigned int ubrr_val)
{
    char x;
    
    /* Set the baud rate */
    UBRR0H = (unsigned char)(ubrr_val>>8);
    UBRR0L = (unsigned char)ubrr_val;
    
    /* Enable UART receiver and transmitter */
    UCSR0B = ((1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0));
    
    /* Flush receive buffer */
    x = 0;
    UART_RxTail = x;
    UART_RxHead = x;
    UART_TxTail = x;
    UART_TxHead = x;
}

/* Interrupt handlers */
ISR(USART_RX_vect)
{
    char data;
    unsigned char tmphead;
    
    /* Read the received data */
    data = UDR0;
    
    /* Calculate buffer index */
    tmphead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxHead = tmphead;
    
    if (tmphead == UART_RxTail)
    {
        /* ERROR! Receive buffer overflow */
    }
    
    /* Store received data in buffer */
    UART_RxBuf[tmphead] = data;
}

ISR(USART_UDRE_vect)
{
    unsigned char tmptail;
    
    /* Check if all data is transmitted */
    if (UART_TxHead != UART_TxTail)
    {
        /* Calculate buffer index */
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        
        /* Store new index */
        UART_TxTail = tmptail;
        
        /* Start transmission */
        UDR0 = UART_TxBuf[tmptail];
    }
    else
    {
        /* Disable UDRE interrupt */
        UCSR0B &= ~(1<<UDRIE0);
    }
}

char ReceiveByte(void)
{
    unsigned char tmptail;
    
    /* Wait for incoming data */
    while (UART_RxHead == UART_RxTail);
    
    /* Calculate buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxTail = tmptail;
    
    /* Return data */
    return UART_RxBuf[tmptail];
}

void TransmitByte(char data)
{
    unsigned char tmphead;
    
    /* Calculate buffer index */
    tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    /* Wait for free space in buffer */
    while (tmphead == UART_TxTail);
    
    /* Store data in buffer */
    UART_TxBuf[tmphead] = data;
    
    /* Store new index */
    UART_TxHead = tmphead;
    
    /* Enable UDRE interrupt */
    UCSR0B |= (1<<UDRIE0);
}

/*
 * This function returns the number of unread bytes in the receive buffer
 */
unsigned char nUnreadBytes(void)
{
    if(UART_RxHead == UART_RxTail)
        return 0;
    else if(UART_RxHead > UART_RxTail)
        return UART_RxHead - UART_RxTail;
    else
        return UART_RX_BUFFER_SIZE - UART_RxTail + UART_RxHead;
}

/*
 * This function gets a string of characters from the USART.
 * The string is placed in the array pointed to by str.
 *
 * - This function uses the function ReceiveByte() to get a byte
 *   from the UART.
 * - If the received byte is equal to '\n' (Line Feed),
 *   the function returns.
 * - The array is terminated with ´\0´.
 */
void ReceiveString(char *str)
{
    uint8_t t = 0;
    
    while ((str[t] = ReceiveByte()) != '\n')
    {
        t++;
    }
    str[t++] = '\n';
    str[t] = '\0';
}

/*
 * Transmits a string of characters to the USART.
 * The string must be terminated with '\0'.
 *
 * - This function uses the function TransmitByte() to
 *   transmit a byte via the UART
 * - Bytes are transmitted until the terminator
 *   character '\0' is detected. Then the function returns.
 */
void TransmitString(char *str)
{
    while(*str)
    {
        TransmitByte(*str++);
    }
}
'. * * - This function uses the function TransmitByte() to * transmit a byte via the UART * - Bytes are transmitted until the terminator * character '
/**
* \file
*
* \brief UART Interrupt example
*
* Copyright (C) 2016 Atmel Corporation. All rights reserved.
* Modified by H. Arends for HAN University of Applied Sciences to support
* the ATmega328P microcontroller for the MIC1 lab.
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Support and FAQ: visit
* <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "avr/io.h"
#include "avr/interrupt.h"

#define F_CPU 16000000UL
#include "util/delay.h"

#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 32

#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE - 1)
#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)
    #error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE - 1)
#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)
    #error TX buffer size is not a power of 2
#endif

/* Static Variables */
static char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile char UART_RxHead;
static volatile char UART_RxTail;

static char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile char UART_TxHead;
static volatile char UART_TxTail;

/* Prototypes */
void InitUART(unsigned int ubrr_val);
char ReceiveByte(void);
void TransmitByte(char data);
unsigned char nUnreadBytes(void);
void ReceiveString(char *str);
void TransmitString(char *str);

int main(void)
{
    /* Initialize the UART */
    InitUART(MYUBRR);
    sei();
    
    while(1)
    {
        // CPU is busy doing something else...
        _delay_ms(1000);
        
        // Check for unread bytes in the receive buffer
        unsigned char nBytes = nUnreadBytes();
        
        // If there are unread bytes, receive them all and echo back
        // (Note: Make sure LF is enabled in Terminal Window)
        if(nBytes > 0)
        {
            char str[30];
            ReceiveString(str);
            TransmitString(str);
        }
    }

    return 0;
}

/* Initialize UART */
void InitUART(unsigned int ubrr_val)
{
    char x;
    
    /* Set the baud rate */
    UBRR0H = (unsigned char)(ubrr_val>>8);
    UBRR0L = (unsigned char)ubrr_val;
    
    /* Enable UART receiver and transmitter */
    UCSR0B = ((1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0));
    
    /* Flush receive buffer */
    x = 0;
    UART_RxTail = x;
    UART_RxHead = x;
    UART_TxTail = x;
    UART_TxHead = x;
}

/* Interrupt handlers */
ISR(USART_RX_vect)
{
    char data;
    unsigned char tmphead;
    
    /* Read the received data */
    data = UDR0;
    
    /* Calculate buffer index */
    tmphead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxHead = tmphead;
    
    if (tmphead == UART_RxTail)
    {
        /* ERROR! Receive buffer overflow */
    }
    
    /* Store received data in buffer */
    UART_RxBuf[tmphead] = data;
}

ISR(USART_UDRE_vect)
{
    unsigned char tmptail;
    
    /* Check if all data is transmitted */
    if (UART_TxHead != UART_TxTail)
    {
        /* Calculate buffer index */
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        
        /* Store new index */
        UART_TxTail = tmptail;
        
        /* Start transmission */
        UDR0 = UART_TxBuf[tmptail];
    }
    else
    {
        /* Disable UDRE interrupt */
        UCSR0B &= ~(1<<UDRIE0);
    }
}

char ReceiveByte(void)
{
    unsigned char tmptail;
    
    /* Wait for incoming data */
    while (UART_RxHead == UART_RxTail);
    
    /* Calculate buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    
    /* Store new index */
    UART_RxTail = tmptail;
    
    /* Return data */
    return UART_RxBuf[tmptail];
}

void TransmitByte(char data)
{
    unsigned char tmphead;
    
    /* Calculate buffer index */
    tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    /* Wait for free space in buffer */
    while (tmphead == UART_TxTail);
    
    /* Store data in buffer */
    UART_TxBuf[tmphead] = data;
    
    /* Store new index */
    UART_TxHead = tmphead;
    
    /* Enable UDRE interrupt */
    UCSR0B |= (1<<UDRIE0);
}

/*
 * This function returns the number of unread bytes in the receive buffer
 */
unsigned char nUnreadBytes(void)
{
    if(UART_RxHead == UART_RxTail)
        return 0;
    else if(UART_RxHead > UART_RxTail)
        return UART_RxHead - UART_RxTail;
    else
        return UART_RX_BUFFER_SIZE - UART_RxTail + UART_RxHead;
}

/*
 * This function gets a string of characters from the USART.
 * The string is placed in the array pointed to by str.
 *
 * - This function uses the function ReceiveByte() to get a byte
 *   from the UART.
 * - If the received byte is equal to '\n' (Line Feed),
 *   the function returns.
 * - The array is terminated with ´\0´.
 */
void ReceiveString(char *str)
{
    uint8_t t = 0;
    
    while ((str[t] = ReceiveByte()) != '\n')
    {
        t++;
    }
    str[t++] = '\n';
    str[t] = '\0';
}

/*
 * Transmits a string of characters to the USART.
 * The string must be terminated with '\0'.
 *
 * - This function uses the function TransmitByte() to
 *   transmit a byte via the UART
 * - Bytes are transmitted until the terminator
 *   character '\0' is detected. Then the function returns.
 */
void TransmitString(char *str)
{
    while(*str)
    {
        TransmitByte(*str++);
    }
}
' is detected. Then the function returns. */ void TransmitString(char *str) { while(*str) { TransmitByte(*str++); } }