SPI 总线精要

来自Jack's Lab
(版本间的差异)
跳转到: 导航, 搜索
(软件模拟 SPI 控制器)
 
(未显示1个用户的3个中间版本)
第34行: 第34行:
  
 
重复上述过程,直到 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>
 
<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

Sd-card-pin-and-function.png











个人工具
名字空间

变换
操作
导航
工具箱