Skip to content

Instantly share code, notes, and snippets.

@ti-nspire
Last active January 22, 2020 07:03
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/a8615e77882c8bd1fa10fc075f85e54c to your computer and use it in GitHub Desktop.
Save ti-nspire/a8615e77882c8bd1fa10fc075f85e54c to your computer and use it in GitHub Desktop.
SPI_library_for_ATmega328P_ver2
#include <avr/io.h>
#include "mySPIv2.h"
void mySPIClass::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 mySPIClass::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 mySPIClass::tradeByte(uint8_t byte){
SPDR = byte;
loop_until_bit_is_set(SPSR, SPIF);
}
void mySPIClass::tradeWord(uint16_t word){
tradeByte((uint8_t)(word >> 8));
tradeByte((uint8_t)(word));
}
void mySPIClass::tradeBytes(uint16_t n, uint8_t *buff){
for(uint16_t i=0; i<n; i++){
tradeByte(buff[i]);
}
}
void mySPIClass::enable(uint8_t div, uint8_t mode, uint8_t order){
setFreqDiv(div);
setMode(mode);
setOrder(order);
SPCR |= (1 << SPE); // SPIを有効化
}
void mySPIClass::disable(){
SPCR &= ~(1 << SPE); // SPIを無効化
}
void mySPIClass::setPins(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 mySPIClass::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 mySPIClass::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 mySPIClass::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ファースト
}
}
// コンストラクタ。何もしていないので省略可。
mySPIClass::mySPIClass(){}
// 実装ファイルの中で先に実体化しておく。何もしていないので省略可。
mySPIClass mySPI;
#ifndef mySPIv2_H
#define mySPIv2_H
class mySPIClass{
private:
void setFreqDiv(uint8_t div);
void setMode(uint8_t mode);
void setOrder(uint8_t order);
public:
void setPins(uint8_t port, uint8_t pin);
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 tradeBytes(uint16_t n, uint8_t *buff);
void enable(uint8_t div, uint8_t mode, uint8_t order);
void disable();
// コンストラクタ。何もしていないので省略可。
mySPIClass();
};
// インスタンスの外部参照宣言
extern mySPIClass mySPI;
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment