SPI 总线精要
来自Jack's Lab
(版本间的差异)
(以“四根线:SS, SCK, MOSI, MISO 总线上的设备分主从模式 (Master and Slaver) 一条总线上可有多个从设备 Master 通过 SS 选择当前与之通...”为内容创建页面) |
(→软件模拟 SPI 控制器) |
||
| (未显示1个用户的4个中间版本) | |||
| 第1行: | 第1行: | ||
| + | == 概述 == | ||
| + | |||
四根线:SS, SCK, MOSI, MISO | 四根线:SS, SCK, MOSI, MISO | ||
| 第33行: | 第35行: | ||
重复上述过程,直到 8 位数据发送完毕 | 重复上述过程,直到 8 位数据发送完毕 | ||
| + | <br><br> | ||
| + | |||
| + | == 软件模拟 SPI 控制器 == | ||
| + | |||
| + | <source lang=c> | ||
| + | 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; } | ||
| + | </source> | ||
| + | |||
| + | |||
| + | 实际应用的进一步实现: | ||
| + | |||
| + | <source lang=bash> | ||
| + | /* 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); | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == Micro SD == | ||
| + | |||
| + | [[文件:Sd-card-pin-and-function.png]] | ||
| − | + | <br> | |
<br><br><br> | <br><br><br> | ||
<br><br><br> | <br><br><br> | ||
<br><br><br> | <br><br><br> | ||
2015年11月30日 (一) 11:12的最后版本
[编辑] 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
