
430的SPI用过,但是没用过SD卡。
下面是我写的SPI的驱动程序
/
文件名称: SPIc
作 者:启岩 QQ:516409354
版 本:v11 日期:20110727
文件描述: msp430x1x系列单片机SPI *** 作,接收和查询均采用查询方式兼容片上SPI功能和
IO模拟功能,通过配置SPI_MODE来确定模式选择
函数列表:
修改历史:
版本 日期 作者 改动内容和原因
----------------------------------------------------
10 20110727 xmx 使用MSP430的SPI模式完成基本的功能完成
11 20110809 xmx 兼容片内SPI和总线模拟SPI时序
/
#include <msp430x14xh>
/SPI模式,0-总线模拟,1-内部UART的SPI模式/
#define SPI_MODE 0x00
/ IO模拟时序时的端口定义 /
#define SPI_SIMO BIT1
#define SPI_SOMI BIT2
#define SPI_SCLK BIT3
#define SPI_SIMO_OUT() (P3DIR |= SPI_SIMO)
#define SPI_SOMI_IN() (P3DIR &= ~SPI_SOMI)
#define SPI_SCLK_OUT() (P3DIR |= SPI_SCLK)
#define SPI_SCLK_SET() (P3OUT |= SPI_SCLK)
#define SPI_SCLK_CLR() (P3OUT &= ~SPI_SCLK)
#define SPI_SIMO_SET() (P3OUT |= SPI_SIMO)
#define SPI_SIMO_CLR() (P3OUT &= ~SPI_SIMO)
#define SPI_SOMI_BIT() (P3IN & SPI_SOMI)
/
函 数 名: SPI_Init
功能描述: SPI初始化。
函数说明: SMCLK=2MHz,SPI时钟源SMCLK/2=1MHz。3线SPI master 模式。
调用函数: 无
全局变量: 无
输 入: 无
返 回: 无
/
void SPI_Init(void)
{
#if SPI_MODE > 0
P3SEL |= 0x0E; // P31-P33设置为SPI接口
U0CTL |= SWRST; // 允许软件复位
//U0CTL |= LISTEN; // 回环模式,测试用
U0CTL |= CHAR + SYNC + MM; // 8-bit,spi mode,usart is master
U0TCTL |= STC; // 3-pin SPI mode
U0TCTL |= SSEL1 + SSEL0; // UCLK时钟源SMCLK 2MHZ
U0TCTL |= CKPH; // UCLKt延时1个半周期
U0TCTL &= ~CKPL; // 上升沿写数据,下降沿读数据
U0TCTL |= TXEPT; // U0TXBUF和TX移位寄存器清空
U0BR0 = 0x02; // 2分频,SPI时钟频率为SMCLK/2
U0BR1 = 0x00;
U0MCTL = 0x00; // SPI模式下设置为000H
ME1 |= USPIE0; // 允许USART0为SPI模式
U0CTL &= ~SWRST; // 禁止软件复位
IE1 &= ~(UTXIE0 + URXIE0); // 禁止收发中断
#else
SPI_SIMO_OUT();
SPI_SOMI_IN();
SPI_SCLK_OUT();
#endif
}
/
函 数 名: SPI_WriteRead
功能描述: SPI读写函数。
函数说明: 向SPI写一个字节并读出一个字节。读写位顺序:MSB--------LSB
调用函数: 无
全局变量: 无
输 入: wByte:要写入SPI的数据
返 回: 读取到的数据。
/
unsigned char SPI_WriteRead(unsigned char wByte)
{
unsigned char rByte;
#if SPI_MODE > 0
U0TXBUF = wByte; // 向SPI发送寄存器写入数据
while(!(IFG1 & UTXIFG0)); // 等待发送完成
IFG1 &= ~UTXIFG0;
while(!(IFG1 & URXIFG0)); // 等待接收到数据
rByte = U0RXBUF; // 读取SPI接收寄存器的值
#else
unsigned char i;
for(i = 0; i < 8; i++)
{
SPI_SCLK_CLR(); // 拉低时钟
if(wByte & 0x80) // 取得发送字节最高位
{
SPI_SIMO_SET(); // 若最高位为1则输出1
}
else
{
SPI_SIMO_CLR();
}
SPI_SCLK_SET(); // 上升沿写数据
wByte <<= 1; // 发送字节左移一位
rByte <<= 1; // 将接收字节左移一位
if(SPI_SOMI_BIT()) // 若时钟线为高
{
rByte |= 0x01;
}
SPI_SCLK_CLR(); // 下降沿读数据
}
#endif
return rByte;
}
/
函 数 名: SPI_WriteByte
功能描述: SPI写函数。
函数说明: 向SPI写一个字节。
调用函数: SPI_WriteRead
全局变量: 无
输 入: wByte:要写入SPI的数据
返 回: 无
/
void SPI_WriteByte(unsigned char wByte)
{
SPI_WriteRead(wByte);
}
/
函 数 名: SPI_WriteByte
功能描述: SPI读函数。
函数说明: 从SPI读取一个字节。
调用函数: SPI_WriteRead
全局变量: 无
输 入: 无
返 回: 读取到的数据。
/
unsigned char SPI_ReadByte(void)
{
return SPI_WriteRead(0xFF); // 写入一个伪数据
}
注意:因为TWI0和SPI0为同一地址,TWI0已经被G-Sensor使用,所以我们使用SPI1
注意:
注意:52832的nrf_drv_spi_transfer函数限制了每次读写不能超过251字节,所以要特殊处理一下。读可以任意地址读,写不能跨页写,正常一页256字节每次都需要分成251+5两次写
考虑到单片机系统没有文件系统管理,每次读写文件异常麻烦,所以我们移植一个小型嵌入式文件系统(带断电恢复以及磨损平衡)。
Github地址: >
最简情况下:
I2C:SDA数据线、SCL时钟线。
SPI:DI输入线、DO输出线、CS片选先、CLK时钟线。
可能不能写到一个驱动中。
但是好在一般很少用到这么简单的情况,厂家会对其扩展和改进。
比如 W25Q128FB/W25R128FV 系列闪存,支持 SPI、Dual SPI、Quad SPI 和 QPI。就拿 Quad SPI 来说,有 6 个引脚:
Quad SPI:D0-D3 输入输出线、CS片选先、CLK时钟线。
其中 输入为一位串行输入 D0,输出为四位串行输出 D0-D3。(四位仍少于一个字节,可姑且称为串行)
Winbond华邦 这么做是为了加快闪存读取速度(四位串行相比一位串行提高了四倍)。
因此关键在于 要进行怎样的 IO。至于是否将二者写到一个驱动看来并不重要。
以上就是关于兄弟,玩过430没得430的USART的SPI模式驱动SD卡,一次只能发送一个字,但是SD卡初始化要发送6个字,全部的内容,包括:兄弟,玩过430没得430的USART的SPI模式驱动SD卡,一次只能发送一个字,但是SD卡初始化要发送6个字,、Noridc 52832 SPI Flash 驱动+应用+文件系统、如何将i2c驱动和spi驱动写到一个驱动中等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)