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++);
}
}