SPI 总线精要
来自Jack's Lab
1 概述
四根线:SS, SCK, MOSI, MISO
总线上的设备分主从模式 (Master and Slaver)
一条总线上可有多个从设备
Master 通过 SS 选择当前与之通信的从设备,因此如果有 10 个从设备,则 Master 需要有 10 条 SS 线
通讯时 Master 拉低 Slaver 对应的 SS 即使能 Slaver
Master 发出的数据总是通过 MOSI,接受数据总是通过 MISO
Slaver 发给 Master 的数据总是通过 MOSI,接受 Master 的数据总是通过 MISO
SCK 是主从通讯的同步信号,Master 将其拉低则发送数据,拉高则读取数据
Master 发送一个字节数据的过程如下:
Master 拉低 SCK 通过 MOSI 发送一位数据(1 则拉高 MOSI,0 则拉低 MOSI) 紧接着再拉高 SCK MISO 读取一位数据
重复上述过程,直到 8 位数据发送完毕
2 软件模拟 SPI 控制器
void spi_init() { CS = 1; SCK = 0; } char spi_transfer(char data) { char i; for(i=0; i<8; i++) { MOSI = (data & 0x80); data = (data << 1); SCK = 1; data |= MISO; SCK = 0; } return (data); } void chip_select() { CS = 0; } void chip_deselect() { CS = 1; }
实际应用的进一步实现:
/* following is independent function */ char spi_read_reg(char reg) { char reg_val; chip_select(); spi_transfer(reg); reg_val = spi_transfer(0); chip_deselect(); return (reg_val); } char spi_write_reg(char reg, char val) { char status; chip_select(); status = spi_transfer(reg); spi_transfer(val); chip_deselect(); return (status); } char spi_read_buf(char reg, char *pbuf, char uchar) { char status, i; chip_select(); status = spi_transfer(reg); for(i=0; i<uchar; i++) pbuf[i] = spi_transfer(0); chip_deselect(); return (status); } char spi_write_buf(char reg, char *pbuf, char uchar) { char status, i; chip_select(); status = spi_transfer(reg); for(i=0; i<uchar; i++) spi_transfer(*pbuf++); chip_deselect(); return (status); }
3 Micro SD