本文实现上哟你GPIO模拟实现9bit的spi 读写功能。
参考如下时序图,SPI读时序需要先发送一个0bit,然后再发送8bit的地址,间隔一个周期,再接收8bit的数据。
SPI写时序先发送一个为1的bit,然后再发送8bit的地址,紧接着发送8bit的数据。
根据以上时序图,实现代码如下:
#define SPI_SCK GPIO_Pin_0 //ok
#define SPI_CS GPIO_Pin_1 //ok
#define SPI_MOSI GPIO_Pin_2
#define SPI_MISO GPIO_Pin_3
extern void udelay(uint32_t delay);
static void mosi_set(uint8_t val)
{
if(val)
GPIO_SetBits(SPI_MOSI);
else
GPIO_ResetBits(SPI_MOSI);
}
static void sck_set(uint8_t val)
{
if(val)
GPIO_SetBits(SPI_SCK);
else
GPIO_ResetBits(SPI_SCK);
}
/*
* brief: send a byte by SPI interface
* param:
* byte[INPUT]: the byte will be sent
* ret: none
*/
void spi_read_byte( uint8_t addr, uint8_t *val )
{
uint8_t data = 0;
sck_set(0);
GPIO_ResetBits(SPI_CS);
//read:0
mosi_set(0);
udelay(1);
sck_set(1);
udelay(1);
for(int i = 7; i >= 0; i--)
{
sck_set(0);
mosi_set(!!(addr & (1<<i)));
udelay(1);
sck_set(1);
udelay(1);
}
sck_set(0);
udelay(1);
sck_set(1);
udelay(1);
for(int i = 7; i >= 0; i--)
{
sck_set(0);
udelay(1);
data |= ((GPIO_ReadInputDataBit(SPI_MISO))<<i);
sck_set(1);
udelay(1);
}
GPIO_SetBits(SPI_CS);
*val = data;
}
void spi_write_byte( uint8_t addr, uint8_t val)
{
printf("val:%02x\n", val);
sck_set(0);
GPIO_ResetBits(SPI_CS);
//write:1
mosi_set(1);
udelay(1);
sck_set(1);
udelay(1);
for(int i = 7; i >= 0; i--)
{
sck_set(0);
mosi_set(!!(addr & (1<<i)));
udelay(1);
sck_set(1);
udelay(1);
}
printf("\r\n");
for(int i = 7; i >= 0; i--)
{
sck_set(0);
mosi_set(!!(val & (1<<i)));
udelay(1);
sck_set(1);
udelay(1);
}
sck_set(0);
udelay(1);
GPIO_SetBits(SPI_CS);
sck_set(1);
printf("\r\n");
}