Skip to content

Instantly share code, notes, and snippets.

@vnaskos
Last active June 10, 2016 12:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vnaskos/5a9e3166dc3332fbe9cfaefa5b162428 to your computer and use it in GitHub Desktop.
Save vnaskos/5a9e3166dc3332fbe9cfaefa5b162428 to your computer and use it in GitHub Desktop.
Simple demonstration of SPI for atmega16 as master
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define ACK 0xF8
void spi_init_master(void);
uint8_t spi_tranceiver(uint8_t data);
void led_blink(uint16_t i);
//Initialize SPI Master Device
void spi_init_master(void)
{
DDRB = (1<<PB7)|(1<<PB5)|(1<<PB4); //Set MOSI, SCK, SS as Output
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master
//Prescaler: Fosc/16, Enable Interrupts
}
//Function to send and receive data
uint8_t spi_tranceiver(uint8_t data)
{
SPDR = data; //Load data into the buffer
while(!(SPSR & (1<<SPIF) )); //Wait until transmission complete
return(SPDR); //Return received data
}
//Function to blink LED
void led_blink(uint16_t i)
{
//Blink LED "i" number of times
for (; i>0; --i)
{
PORTA|=(1<<0);
_delay_ms(100);
PORTA=(0<<0);
_delay_ms(100);
}
}
int main(void)
{
spi_init_master(); //Initialize SPI Master
DDRA |= 0x01; //PA0 as Output
uint8_t data; //Received data stored here
uint8_t x = 0x00; //Index value of led to light
while(1)
{
data = 0x00; //Reset ACK in "data"
data = spi_tranceiver(1<<x++); //Send number, receive ACK in "data"
//if index is on the last position, return to the first LED
if(x>=8) x=0;
//If received data is not the same as ACK, blink LED 3 times
if(data != ACK) led_blink(3);
_delay_ms(500);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment