우리는 atmel atmega328 MCU를 사용하여 다른 IC와 통신하기 위해 SPI를 사용하려고합니다. 대상 IC는 명령 (코드의 헤더)을 가져온 다음 요청 된 레지스터에 저장된 정보를 다시 제공합니다 (또는 명령이 쓰기 인 경우 해당 주소에 씁니다). 그러나, 우리는 여기에 두 가지 문제가 발생하는 :atmega328의 SPI가 작동하지 않습니다.
아무것도 SPI에서 온다, 유일한 변화는 (우리가 제어하는)가 CS 라인에 있습니다. SPI 클럭 없음, 데이터 라인에 데이터 없음.
헤더를 쓸 때 for 루프의 첫 번째 반복은 프로그램이 while 루프에 들어 가지 않습니다 (포트 6의 LED는 켜지지 않음).
아래의 코드는 도움이 될 것입니다.
#define DDR_SPI DDRB
#define DD_MISO DDB4
#define DD_MOSI DDB3
#define DD_SCK DDB5
#define DD_SS DDB6
void SPI_MasterInit(void)
{
/* Set MOSI, SCK and CS output, all others input */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
/* Enable SPI, Master, set clock rate = System clock/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
int readfromspilow(uint16 headerLength, const uint8 *headerBuffer, uint32 readLength, uint8 *readBuffer)
{
PORTB &= ~(1 << PORTB6); // Set CS low
for(int i=0; i<headerLength; i++)
{
SPDR = headerBuffer[i]; //Send entry i of the header to the spi register
sleep_us(5); // Give the flag time to reset, might be unnecessary
PORTD |= (1 << PORTD5); //LED for diagnostics
while(!(SPSR & (1<<SPIF))){ //Wait for SPIFinished flag
PORTD |= (1 << PORTD6); //LED for diagnostics
}
PORTD &= ~(1 << PORTD3); //LED for diagnostics
//readBuffer[0] = SPDR; // Dummy read as we write the header
}
for(int i=0; i<readLength; i++)
{
SPDR = 0xFF; // Dummy write as we read the message body
sleep_us(5); // Give the flag time to reset, might be unnecessary
while(!(SPSR & (1<<SPIF))); //Wait for SPIFinished flag
readBuffer[i] = SPDR ; //Store the value in the buffer
}
PORTB |= (1 << PORTB6); // Set CS high
return;
}
편집 : 초기화
나중에 코드를 어떻게 사용합니까? DDR_SPI 및 기타는 무엇입니까? 비트가 일치합니까? while 루프는 SPI가 끝나기를 기다리는 동안 멈 춥니 다? – tilz0R
우리는 단순히 필요한 명령을 헤더 (주소와 우리가 읽고 자하는 레지스터에 대한 것)와 예상되는 응답의 길이와 함께 readfromspilow를 읽기 길이로, 버퍼가 읽기 대답을 저장하는 지점으로 호출합니다. SPI에 대한 정의를 편집과 함께 추가했는데, "비트 일치"란 무엇을 의미하는지 확신 할 수 없습니다. while은 첫 번째 반복을 건너 뜁니다 (이유는 알지 못합니다). 그러나 다음 iteration에 걸렸습니다 (아마도 SPI가 신호를 보내지 않았기 때문일 수 있습니다) – Sebastian