下面給出了模擬SPI總線在模式1下進行讀寫的僞代碼,用以說明如何使用GPIO實現SPI通訊:
#define SS 252 //定義SS所對應的GPIO接口編號
#define SCLK 253 //定義SCLK所對應的GPIO接口編號
#define MOSI 254 //定義SCLK所對應的GPIO接口編號
#define MISO 255 //定義MISO所對應的GPIO接口編號
#define OUTP 1 //表示GPIO接口方向爲輸出
#define INP 0 //表示GPIO接口方向爲輸入
/* SPI端口初始化 */
void spi_init()
{
set_gpio_direction(SS, OUTP);
set_gpio_direction(SCLK, OUTP);
set_gpio_direction(MOSI, OUTP);
set_gpio_direction(MISO, INP);
set_gpio_value(SCLK, 0); //CPOL=0
set_gpio_value(MOSI, 0);
}
/*
從設備使能
enable:爲1時,使能信號有效,SS低電平
爲0時,使能信號無效,SS高電平
*/
void ss_enable(int enable)
{
if (enable)
set_gpio_value(SS, 0); //SS低電平,從設備使能有效
else
set_gpio_value(SS, 1); //SS高電平,從設備使能無效
}
/* SPI字節寫 */
void spi_write_byte(unsigned char b)
{
int i;
for (i=7; i>=0; i--) {
set_gpio_value(SCLK, 0);
set_gpio_value(MOSI, b&(1<<i)); //從高位7到低位0進行串行寫入
delay(); //延時
set_gpio_value(SCLK, 1); // CPHA=1,在時鐘的第一個跳變沿採樣
delay();
}
}
/* SPI字節讀 */
unsigned char spi_read_byte()
{
int i;
unsigned char r = 0;
for (i=0; i<8; i++) {
set_gpio_value(SCLK, 0);
delay(); //延時
set_gpio_value(SCLK, 1); // CPHA=1,在時鐘的第一個跳變沿採樣
r = (r <<1) | get_gpio_value(MISO); //從高位7到低位0進行串行讀出
delay();
}
}
/*
SPI寫操做
buf:寫緩衝區
len:寫入字節的長度
*/
void spi_write (unsigned char* buf, int len)
{
int i;
spi_init(); //初始化GPIO接口
ss_enable(1); //從設備使能有效,通訊開始
delay(); //延時
//寫入數據
for (i=0; i<len; i++)
spi_write_byte(buf[i]);
delay();
ss_enable(0); //從設備使能無效,通訊結束
}
/*
SPI讀操做
buf:讀緩衝區
len:讀入字節的長度
*/
void spi_read(unsigned char* buf, int len)
{
int i;
spi_init(); //初始化GPIO接口
ss_enable(1); //從設備使能有效,通訊開始
delay(); //延時
//讀入數據
for (i=0; i<len; i++)
buf[i] = spi_read_byte();
delay();
ss_enable(0); //從設備使能無效,通訊結束
}
在上面的代碼中,spi_read和spi_write這兩個函數能夠實現GPIO對SPI的模擬讀寫。