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 ...
随机推荐
- MySQL建立索引的原则
1.表的主键.外键必须有索引; 2.数据量超过300的表应该有索引; 3.经常与其他表进行连接的表,在连接字段上应该建立索引; 4.经常出现在Where子句中的字段,特别是大表的字段,应该建立索引; ...
- List 中 forEach 的用法
1.forEach List list = new ArrayList<String>(); list.add("small"); list.add("sun ...
- 彻底搞懂prototype和__proto__
prototype是函数特有的属性,是Function的静态属性:__proto__是对象特有的属性. 因为函数本身是一种对象,所以函数既有prototype属性也有__proto__属性. 当函数使 ...
- How to change the default browser to debug with in Visual Studio 2008?
http://stackoverflow.com/questions/297298/how-to-change-the-default-browser-to-debug-with-in-visual- ...
- vue中使用ckeditor,支持wps,word,网页粘贴
由于工作需要必须将word文档内容粘贴到编辑器中使用 但发现word中的图片粘贴后变成了file:///xxxx.jpg这种内容,如果上传到服务器后其他人也访问不了,网上找了很多编辑器发现没有一个能直 ...
- (WA)BZOJ 1503: [NOI2004]郁闷的出纳员
二次联通门 : BZOJ 1503: [NOI2004]郁闷的出纳员 /* BZOJ 1503: [NOI2004]郁闷的出纳员 考虑这样一个事实 无论是加或减 都是针对全体人员的 那么只需要记录一个 ...
- seq2seq聊天模型(二)——Scheduled Sampling
使用典型seq2seq模型,得到的结果欠佳,怎么解决 结果欠佳原因在这里 在训练阶段的decoder,是将目标样本["吃","兰州","拉面" ...
- 关于pycharm+opencv没有代码提示的问题解决方法记录
代码可以看出实际我们引入的应该是cv2.cv2下面. 所以我们代码只需要import cv2.cv2 as cv 即可. 记着要重新启动下pycharm哦. 可以参考: https://blog.cs ...
- ImportError: No module named pytz
xxx@hostname:/opt/xx/cc$ python manage.py runserver Traceback (most recent call last): File , in < ...
- 2019-2020 ICPC, NERC, Northern Eurasia Finals (Unrated, Online Mirror, ICPC Rules, Teams Preferred)
这是一场三人组队赛来的,单人带电子模板不限时单挑试一下.按照难度排序. B - Balls of Buma 题意:玩祖玛,射入任意颜色的球一个,当某段长度变长了且长度变长后>=3则这段就会消除, ...