AVR SPI관련 자료 - ATmega128, ATMega16, ATMega8 (예제 소스코드)
AVR에서 SPI제어에 관련된 자료 정리
AVR SPI블록도
AVR ATMega128 SPI 핀맵
SPI핀 찾을것 없이 기록해 두면 편리할것 같다
관련 레지스터
SPSR
• Bit 7 – SPIF: SPI Interrupt Flag
읽을수만 있는 레지스터로 SPI인터럽트 발생 여부를 나타낸다.
• Bit 6 – WCOL: Write COLlision flag
오류 발생을 나타내는 비트
• Bit 5..1 – Res: Reserved Bits
사요하지 않는다.
• Bit 0 – SPI2X: Double SPI Speed Bit
SPI 클럭을 두배러 설정하는 비트
SPCR
• Bit 7 – SPIE: SPI Interrupt Enable
SPI인터럽트 사용여부 결정, 1일때 인터럽트 사용
• Bit 6 – SPE: SPI Enable
SPI 모듈 사용여부 결정. 1일때 SPI 사용.
• Bit 5 – DORD: Data Order
1: LSB 먼저 전송.
0: MSB 먼저 전송
• Bit 4 – MSTR: Master/Slave Select
1: Master SPI mode
0: Slave SPI mode
• Bit 3 – CPOL: Clock Polarity (SPI 모드 설정)
• Bit 2 – CPHA: Clock Phase (SPI 모드 설정)
SPI모드 설정
SPI 모드 설정 소스코드
SPI모드는 디바이스에 따라 변경해야 할 경우가 많으므로 아래 코드와 같이 정의해서 사용한다.
• Bits 1, 0 – SPI클럭 설정
클럭 설정 부분도 아래와 같이 정의 해 두면 편리하게 사용할 수 있다.
AVR SPI통신 초기화 함수
AVR ATMega128, ATMega8의 핀맵이 다르므로 아래와 같이 #if 문으로 정의해 두면 MCU에 따라 유용하게 사용할 수 있다.
SPI 데이터 송/수신 전송 함수
좀더 빠른 처리를 위해 define문으로 정의하는것이 좋다.
SPI데이터 수신 함수
보통 SPI Master의 경우 SPI데이터 전송후 수신하는 경우가 많기 때문에 WriteReadByte함수를 만들어 두면 유용하다.
AVR에서 SPI제어에 관련된 자료 정리
AVR SPI블록도
AVR ATMega128 SPI 핀맵
SPI핀 찾을것 없이 기록해 두면 편리할것 같다
관련 레지스터
SPSR
• Bit 7 – SPIF: SPI Interrupt Flag
읽을수만 있는 레지스터로 SPI인터럽트 발생 여부를 나타낸다.
• Bit 6 – WCOL: Write COLlision flag
오류 발생을 나타내는 비트
• Bit 5..1 – Res: Reserved Bits
사요하지 않는다.
• Bit 0 – SPI2X: Double SPI Speed Bit
SPI 클럭을 두배러 설정하는 비트
SPCR
• Bit 7 – SPIE: SPI Interrupt Enable
SPI인터럽트 사용여부 결정, 1일때 인터럽트 사용
• Bit 6 – SPE: SPI Enable
SPI 모듈 사용여부 결정. 1일때 SPI 사용.
• Bit 5 – DORD: Data Order
1: LSB 먼저 전송.
0: MSB 먼저 전송
• Bit 4 – MSTR: Master/Slave Select
1: Master SPI mode
0: Slave SPI mode
• Bit 3 – CPOL: Clock Polarity (SPI 모드 설정)
• Bit 2 – CPHA: Clock Phase (SPI 모드 설정)
SPI모드 설정
SPI 모드 설정 소스코드
SPI모드는 디바이스에 따라 변경해야 할 경우가 많으므로 아래 코드와 같이 정의해서 사용한다.
#define SPI0_CPOL_SET() Sbi(SPCR, BIT3)
#define SPI0_CPHA_SET() Sbi(SPCR, BIT2)
#define SPI0_CPOL_CLR() Cbi(SPCR, BIT3)
#define SPI0_CPHA_CLR() Cbi(SPCR, BIT2)
#define SPI0_MODE0() SPI0_CPOL_CLR();SPI0_CPHA_CLR()
#define SPI0_MODE1() SPI0_CPOL_CLR();SPI0_CPHA_SET()
#define SPI0_MODE2() SPI0_CPOL_SET();SPI0_CPHA_CLR()
#define SPI0_MODE3() SPI0_CPOL_SET();SPI0_CPHA_SET()
#define SPI0_CPHA_SET() Sbi(SPCR, BIT2)
#define SPI0_CPOL_CLR() Cbi(SPCR, BIT3)
#define SPI0_CPHA_CLR() Cbi(SPCR, BIT2)
#define SPI0_MODE0() SPI0_CPOL_CLR();SPI0_CPHA_CLR()
#define SPI0_MODE1() SPI0_CPOL_CLR();SPI0_CPHA_SET()
#define SPI0_MODE2() SPI0_CPOL_SET();SPI0_CPHA_CLR()
#define SPI0_MODE3() SPI0_CPOL_SET();SPI0_CPHA_SET()
• Bits 1, 0 – SPI클럭 설정
클럭 설정 부분도 아래와 같이 정의 해 두면 편리하게 사용할 수 있다.
#define SPI0_CLK_DIV16() Cbi(SPCR, BIT1);Sbi(SPCR, BIT0)
#define SPI0_CLK_DIV64() Sbi(SPCR, BIT1);Cbi(SPCR, BIT0)
#define SPI0_CLK_DIV128() Sbi(SPCR, BIT1|BIT0)
#define SPI0_CLK_DOULBE() Sbi(SPSR, BIT0)
#define SPI0_CLK_DIV64() Sbi(SPCR, BIT1);Cbi(SPCR, BIT0)
#define SPI0_CLK_DIV128() Sbi(SPCR, BIT1|BIT0)
#define SPI0_CLK_DOULBE() Sbi(SPSR, BIT0)
AVR SPI통신 초기화 함수
AVR ATMega128, ATMega8의 핀맵이 다르므로 아래와 같이 #if 문으로 정의해 두면 MCU에 따라 유용하게 사용할 수 있다.
void SPI0_Init(void) // SPI 통신 초기화 함수
{
#if (__MCU_TYPE__ == AVR_TYPE_MEGA128)
// setup SPI I/O pins
Cbi(PORTB, BIT1); // set SCK lo
Sbi(DDRB, BIT1); // set SCK as output
Sbi(DDRB, BIT2); // set MOSI as output
Cbi(DDRB, BIT3); // set MISO as input
Sbi(DDRB, BIT0); // SS must be output for Master mode to work
Sbi(PORTB, BIT0);
#else if (__MCU_TYPE__ == AVR_TYPE_MEGA8)
Sbi(PORTB, BIT5); // set SCK lo
Sbi(DDRB, BIT5); // set SCK as output
Sbi(DDRB, BIT3); // set MOSI as output
Cbi(DDRB, BIT4); // set MISO as input
Sbi(DDRB, BIT2); // SS must be output for Master mode to work
Sbi(PORTB, BIT2);
#endif
SPI0_ENABLE();
SPI0_MASTER_MODE();
SPI0_MODE0();
SPI0_CLK_DOULBE();
SPI0_CLK_DIV4();
}
{
#if (__MCU_TYPE__ == AVR_TYPE_MEGA128)
// setup SPI I/O pins
Cbi(PORTB, BIT1); // set SCK lo
Sbi(DDRB, BIT1); // set SCK as output
Sbi(DDRB, BIT2); // set MOSI as output
Cbi(DDRB, BIT3); // set MISO as input
Sbi(DDRB, BIT0); // SS must be output for Master mode to work
Sbi(PORTB, BIT0);
#else if (__MCU_TYPE__ == AVR_TYPE_MEGA8)
Sbi(PORTB, BIT5); // set SCK lo
Sbi(DDRB, BIT5); // set SCK as output
Sbi(DDRB, BIT3); // set MOSI as output
Cbi(DDRB, BIT4); // set MISO as input
Sbi(DDRB, BIT2); // SS must be output for Master mode to work
Sbi(PORTB, BIT2);
#endif
SPI0_ENABLE();
SPI0_MASTER_MODE();
SPI0_MODE0();
SPI0_CLK_DOULBE();
SPI0_CLK_DIV4();
}
SPI 데이터 송/수신 전송 함수
좀더 빠른 처리를 위해 define문으로 정의하는것이 좋다.
#define SPI0_WriteByte(Data) SPDR = (Data); while(!(SPSR & (1<<SPIF)))
#define SPI0_WaitForReceive() while(!(SPSR & (1<<SPIF)))
#define SPI0_RxData() (SPDR)
#define SPI0_WaitForReceive() while(!(SPSR & (1<<SPIF)))
#define SPI0_RxData() (SPDR)
SPI데이터 수신 함수
보통 SPI Master의 경우 SPI데이터 전송후 수신하는 경우가 많기 때문에 WriteReadByte함수를 만들어 두면 유용하다.
unsigned char SPI0_WriteReadByte(unsigned char Data)
{
SPI0_WriteByte(Data);
return SPI0_RxData();
}
{
SPI0_WriteByte(Data);
return SPI0_RxData();
}
반응형