STM32 M0之SPI
从M3到M0,可能SPI的接口函数大致类似,但是细节略有不同
仔细观察寄存器描述,虽然个别存在差异,但是真心不知道竟然有太多的“玄机”
这次的问题主要出在了数据宽度上:
1. M3/M4的数据宽度支持8/16,是SPI_CR1中DFF: Data frame format控制的,实际使用中,只要我配置好数据宽度,直接操作DR寄存器即可。
2. M0的看起来更加强大,在SPI_CR2中DS [3:0]: Data size控制,支持4..16个bits的数据。
所以开始的时候我使用M3的操作方式,直接把驱动函数移了过来,下面为初始化代码
/*
*********************************************************************************************************
* Function Name: bsp_spi_init
* Description : SPI初始化
* Input : None
* Output : None
* Return : None
*********************************************************************************************************
*/
static void
bsp_spi_init(void)
{
SPI_InitTypeDef SPI_InitStructure; BSP_SPI_FRAM_CS(); /* SPI_CS初始化 */
SPI_StructInit(&SPI_InitStructure);
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_Init(BSP_SPI_FRAM, &SPI_InitStructure);
/** Enable the SPI */
SPI_Cmd(BSP_SPI_FRAM, ENABLE);
}
本以为这样就OK了,后来发现二者还是有区别的:
M3的话你直接写DR寄存器,会自动根据你的配置数据长度8/16发送数据
M0的话,你直接写DR寄存器,他不会根据你写的数据长度发送,依旧发送的是16bits
后来观察ST官方给的驱动代码:
M3的接口函数没有区分,都是直接操作DR
// M3的发送代码
/**
* @brief Transmits a Data through the SPIx/I2Sx peripheral.
* @param SPIx: where x can be
* - 1, 2 or 3 in SPI mode
* - 2 or 3 in I2S mode
* @param Data : Data to be transmitted.
* @retval None
*/
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
{
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); /* Write in the DR register the data to be sent */
SPIx->DR = Data;
}
M0的官方代码比较复杂:
/**
* @brief Transmits a Data through the SPIx/I2Sx peripheral.
* @param SPIx: where x can be 1 or 2 in SPI mode to select the SPI peripheral.
* @param Data: Data to be transmitted.
* @retval None
*/
void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
{
uint32_t spixbase = 0x00; /* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); spixbase = (uint32_t)SPIx;
spixbase += 0x0C; *(__IO uint8_t *) spixbase = Data;
} /**
* @brief Transmits a Data through the SPIx/I2Sx peripheral.
* @param SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
* the SPI peripheral.
* @param Data: Data to be transmitted.
* @retval None
*/
void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
{
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); SPIx->DR = (uint16_t)Data;
}
虽然都是操作的DR,但是M0这里把DR强转成8bits宽度的指针,之后操作。
因为我只是发送8bits的数据,所以这样算是OK了
至于其他的非8/16的宽度如何操作,暂时就不去纠结了。。。。
我最后的做法简单粗暴,直接对DR强行转换:
(*((volatile unsigned char*)(&BSP_SPI_FRAM->DR) ))= dat;
这样免得调用他那个发送的库,各个平台的代码归档起来也方便一些。
至于这样设计的原因,我考虑还是M0的字节对齐问题吧?
STM32 M0之SPI的更多相关文章
- STM32学习笔记——SPI串行通讯(向原子哥学习)
一.SPI 简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在 EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...
- 怎样从Cortex-m向STM32移植使用SPI接口协议
/*************************************************************************************************** ...
- STM32—4线SPI驱动SSD1306 OLED
文章目录 一.OLED简介 二.驱动SSD1306所需知识 1.引脚介绍 2.通信时序 3.显存GRAM 4.字库 5.SSD1306基本命令 三.代码讲解 1.相关引脚配置 2.模拟SPI通信 3. ...
- STM32—SPI详解
目录 一.什么是SPI 二.SPI协议 物理层 协议层 1.通讯时序图 2.起始和停止信号 3.数据有效性 4.通讯模式 三.STM32中的SPI 简介 功能框图 1.通讯引脚 2.时钟控制逻辑 3. ...
- STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]
SPI是我最常用的接口之一,连接管脚仅为4根:在常见的芯片间通信方式中,速度远优于UART.I2C等其他接口.STM32的SPI口的同步时钟最快可到PCLK的二分之一,单个字节或字的通信时间都在us以 ...
- [stm32] 一个简单的stm32vet6驱动的天马4线SPI-1.77寸LCD彩屏DEMO
书接上文<1.一个简单的nRF51822驱动的天马4线SPI-1.77寸LCD彩屏DEMO> 我们发现用16MHz晶振的nRF51822驱动1.77寸的spi速度达不到要求 本节主要采用7 ...
- 嵌入式单片机STM32应用技术(课本)
目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...
- SPI接口扫盲 SPI定义/SPI时序(CPHA CPOL)
SPI接口扫盲 douqingl@gmail.com 为何要写这篇文档?百度上找出来的SPI接口中文描述都说的太过简略,没有一篇文档能够详尽的将SPI介绍清楚的.wikipedia英文版[注释 ...
- 【转】spi测试自发自收(中断通信方式)
1.初始化spi时钟 void spiRccinit(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2Peri ...
随机推荐
- 03_已解决 [salt.master :2195][ERROR ][6219] Failed to allocate a jid. The requested returner 'mysql' could not be loaded.
总结: 对于python2.7环境下的salt来说,要安装pip install mysql-python 对于python3环境下的salt来说,pip install mysqlclient的时候 ...
- 牛客练习赛51 D题
链接:https://ac.nowcoder.com/acm/contest/1083/D来源:牛客网 有一个草原可以用一个1~400的数轴表示.有n头羊和q个查询.每头羊的编号分别是1,2,3…n. ...
- 五十九.大数据、Hadoop 、 Hadoop安装与配置 、 HDFS
1.安装Hadoop 单机模式安装Hadoop 安装JAVA环境 设置环境变量,启动运行 1.1 环境准备 1)配置主机名为nn01,ip为192.168.1.21,配置yum源(系统源) 备 ...
- 面向对象(OOP)笔记
1.本质:以类的方式组织代码,以对象的方式组织(封装)数据 2.对象:是具体的事物 3.类:是对对象的抽象(抽象 抽出象的部分) 先有具体的对象,然后抽象各个对象之间象的部分,归纳出类 通过类再认识其 ...
- IdentityServer4入门一
这几天学习IdentityServer4,感觉内容有点乱,也可能自己水平有限吧.但为了巩固学习的内容,也打算自己理一下思路. 首先IdentityServer解决什么问题? 下图是我们的一个程序的组织 ...
- SpringMVC返回Map类型转换成JSON失败
错误信息:WARN DefaultHandlerExceptionResolver:380 - Failed to write HTTP message: org.springframework.ht ...
- UML期末复习题——2.3:UML State Diagram
第三题 状态图 重要概念: 1.定义:事件.状态和转换: 事件:指一件值得注意的事情的发生. 状态:指对象在事件发生之间某时刻所处的情形. 转换:两个状态之间的关系.它表明当某事件发生时,对象从先前 ...
- java android 将小数度数转换为度分秒格式
/** * 将小数度数转换为度分秒格式 * @param numStr (主要用于图片中存储经纬度) * @return */ public static String convertToSexage ...
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_19-页面静态化-模板管理-模板存储
因为没有界面,所以手动的通过操作数据库的方式来存储 比如说要存一个轮播图的模板 把自增的_id去掉 先用测试程序把文件存储到gridFS得到一个gridId,然后拿着这个文件的id 这样就添加好了这一 ...
- Tomcat 80端口被占用
1.“运行”中输入cmd2.在命令行中输入netstat -ano,得到端口号对应的PID 3.打开任务管理器,点击“查看“菜单,选择“选择列”,给进程列表中添加”PID“列,然后找到PID对应的进程 ...