Skip to content

Instantly share code, notes, and snippets.

@ti-nspire
Last active January 12, 2020 21:22
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 ti-nspire/cf3653b077acddca2ac17bf589f02708 to your computer and use it in GitHub Desktop.
Save ti-nspire/cf3653b077acddca2ac17bf589f02708 to your computer and use it in GitHub Desktop.
SPI_library_for_ATmega328P
#include <avr/io.h>
#include "mySPI.h"
void selectSlave(uint8_t port, uint8_t pin){
switch(port){
case 'B': PORTB &= ~(1 << pin); break;
case 'C': PORTC &= ~(1 << pin); break;
case 'D': PORTD &= ~(1 << pin); break;
default : PORTB &= ~(1 << PB2); break;
}
}
void deselectSlave(uint8_t port, uint8_t pin){
switch(port){
case 'B': PORTB |= (1 << pin); break;
case 'C': PORTC |= (1 << pin); break;
case 'D': PORTD |= (1 << pin); break;
default : PORTB |= (1 << PB2); break;
}
}
void tradeByte(uint8_t byte){
SPDR = byte;
loop_until_bit_is_set(SPSR, SPIF);
}
void tradeWord(uint16_t word){
tradeByte((uint8_t)(word >> 8));
tradeByte((uint8_t)(word));
}
void enableSPI(uint8_t div, uint8_t mode, uint8_t order){
setFreqDiv(div);
setMode(mode);
setOrder(order);
SPCR |= (1 << SPE);
}
void disableSPI(){
SPCR &= ~(1 << SPE);
}
void setSPIpins(uint8_t port, uint8_t pin){
PORTB |= (1 << PB2); // マスターモードのときはとにかくまずPB2をプルアップしておく。
switch(port){
case 'B': DDRB |= (1 << pin); PORTB |= (1 << pin); break;
case 'C': DDRC |= (1 << pin); PORTC |= (1 << pin); break;
case 'D': DDRD |= (1 << pin); PORTD |= (1 << pin); break;
default : DDRB |= (1 << PB2); PORTB |= (1 << PB2); break;
}
DDRB |= (1 << PB3); // PB3をMOSI端子(OUT)として使う。
PORTB |= (1 << PB4); // PB4をMISO端子(IN)として使う。内部プルアップしておく。
DDRB |= (1 << PB5); // PB5をSCK端子(OUT)として使う。
SPCR |= (1 << MSTR); // AVRをマスターにする。
}
void setFreqDiv(uint8_t div){
switch(div){
case 4: SPSR &= ~(1 << SPI2X); SPCR &= ~(1 << SPR1); SPCR &= ~(1 << SPR0); break;
case 16: SPSR &= ~(1 << SPI2X); SPCR &= ~(1 << SPR1); SPCR |= (1 << SPR0); break;
case 64: SPSR &= ~(1 << SPI2X); SPCR |= (1 << SPR1); SPCR &= ~(1 << SPR0); break;
case 128: SPSR &= ~(1 << SPI2X); SPCR |= (1 << SPR1); SPCR |= (1 << SPR0); break;
case 2: SPSR = (1 << SPI2X); SPCR &= ~(1 << SPR1); SPCR &= ~(1 << SPR0); break;
case 8: SPSR = (1 << SPI2X); SPCR &= ~(1 << SPR1); SPCR |= (1 << SPR0); break;
case 32: SPSR = (1 << SPI2X); SPCR |= (1 << SPR1); SPCR &= ~(1 << SPR0); break;
//case 64: SPSR = (1 << SPI2X); SPCR |= (1 << SPR1); SPCR |= (1 << SPR0); break;
default : SPSR &= ~(1 << SPI2X); SPCR |= (1 << SPR1); SPCR |= (1 << SPR0); break; // 128分周*/
}
}
void setMode(uint8_t mode){
switch(mode){
case 0 : SPCR &= ~(1 << CPOL); SPCR &= ~(1 << CPHA); break; // mode(0,0)
case 1 : SPCR &= ~(1 << CPOL); SPCR |= (1 << CPHA); break; // mode(0,1)
case 2 : SPCR |= (1 << CPOL); SPCR &= ~(1 << CPHA); break; // mode(1,0)
case 3 : SPCR |= (1 << CPOL); SPCR |= (1 << CPHA); break; // mode(1,1)
default: SPCR &= ~(1 << CPOL); SPCR &= ~(1 << CPHA); break; // mode(0,0)
}
}
void setOrder(uint8_t order){
switch(order){
case 'M': SPCR &= ~(1 << DORD); break; // MSBファーストで転送する。デフォルト。
case 'L': SPCR |= (1 << DORD); break; // LSBファーストで転送する。
default : SPCR &= ~(1 << DORD); break; // MSBファースト
}
}
#ifndef mySPI_H
#define mySPI_H
void selectSlave(uint8_t port, uint8_t pin);
void deselectSlave(uint8_t port, uint8_t pin);
void tradeByte(uint8_t byte);
void tradeWord(uint16_t word);
void enableSPI(uint8_t div, uint8_t mode, uint8_t order);
void disableSPI();
void setSPIpins(uint8_t port, uint8_t pin);
void setFreqDiv(uint8_t div);
void setMode(uint8_t mode);
void setOrder(uint8_t order);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment