STM32F030 使用硬件 SPI
前言
以前玩过一点 STM32 单片机(主要是 STM32F103 系列),去年(2017)STM32F1 涨到不知哪里去了,今年好像降下来了。F0 系列相比 F1 系列少了一些功能,最高主频只到 48M(F1 是 72M),但是价格便宜啊,刚好最近工作需要重新接触了 STM32F030,记录一下。PS:研究了几天觉得 STM32 的各个组成部分还是很精妙的,虽然繁杂但是库函数化解了这个问题。
步骤
SPI 初始化
STM32F030 默认的 SPI1 接口如下,其中 CSN 由软件控制,所以可以改为其他 IO 口
#define SPI1_PORT GPIOA
#define PIN_SPI1_CSN GPIO_Pin_4
#define PIN_SPI1_SCK GPIO_Pin_5
#define PIN_SPI1_MISO GPIO_Pin_6
#define PIN_SPI1_MOSI GPIO_Pin_7
#define SPI1_CSN_L (SPI1_PORT->BRR = PIN_SPI1_CSN)
#define SPI1_CSN_H (SPI1_PORT->BSRR = PIN_SPI1_CSN)
初始化
void SPI1_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //中速
GPIO_InitStructure.GPIO_Pin = PIN_SPI1_SCK | PIN_SPI1_MOSI | PIN_SPI1_MISO;
GPIO_Init(SPI1_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource5, GPIO_AF_0);
GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource6, GPIO_AF_0);
GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource7, GPIO_AF_0);
GPIO_InitStructure.GPIO_Pin = PIN_SPI1_CSN; //配置 CSN
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //高速
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_Init(SPI1_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(SPI1); //将寄存器重设为缺省值
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主机模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8 位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //通信空闲时 SCK 为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个时钟沿捕获
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件控制 NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //SPI 速度 8 分频
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 校验
SPI_Init(SPI1, &SPI_InitStructure);
SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF); //重要,把应答数据位设置为 8 位
SPI_Cmd(SPI1, ENABLE);
}
传输数据
读取和发送数据需要检查标志位
void SPI1_WriteByte(uint8_t TxData)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //检查发送是否完成
SPI_SendData8(SPI1, TxData);
}
uint8_t SPI1_ReadByte(void)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查接收标志位
return(SPI_ReceiveData8(SPI1));
}
uint8_t SPI1_Transfer(uint8_t data)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_SendData8(SPI1, data);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_ReceiveData8(SPI1);
}
例子
用 SPI 与 NRF24L01 模块通信
void NRF24L01_Write_Register(uint8_t reg, uint8_t data)
{
SPI1_CSN_L;
SPI1_Transfer(reg);
SPI1_Transfer(data);
SPI1_CSN_H;
}
uint8_t NRF24L01_Read_Register(uint8_t reg)
{
uint8_t tmp;
SPI1_CSN_L;
SPI1_Transfer(reg);
tmp = SPI1_Transfer(0);
SPI1_CSN_H;
return tmp;
}
STM32F030 使用硬件 SPI的更多相关文章
- linux enc28j60网卡驱动移植(硬件spi和模拟spi)
本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是 ...
- 关于STM8S使用硬件SPI收发问题
源: 关于STM8S使用硬件SPI收发问题
- STM32 关于HAL库硬件SPI要注意的问题总结
利用STM32CUbeMx编写程序,大大方便了开发,最近做的项目利用到了 STM32CUbeMx的硬件SP,这里对SPI的使用做一个总结. HAL库里的硬件SPI主要有以下几个库函数: /* hspi ...
- 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (十一): 软件SPI和硬件SPI驱动ST7567液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI
1.AD7799介绍 AD7799结构图如下所示: 其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示: 注意: 如果REG_CONFIG的 ...
- spi子系统之驱动SSD1306 OLED
spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...
- 基于TQ2440的SPI驱动学习(OLED)
平台简介 开发板:TQ2440 (NandFlash:256M 内存:64M) u-boot版本:u-boot-2015.04 内核版本:Linux-3.14 作者:彭东林 邮箱:pengdongl ...
随机推荐
- 问题:只能在执行 Render() 的过程中调用 RegisterForEventValidation;结果:只能在执行 Render() 的过程中调用 RegisterForEventValidation
只能在执行 Render() 的过程中调用 RegisterForEventValidation 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 Register ...
- ssh框架搭建实例代码教程步骤
http://blog.csdn.net/u010539352/article/details/49255729
- java中的自动转型的学习理解
java当中的继承是和c++中的继承类似,只是java中的继承时的父类只能有一位. 我们今天在这里讲的是关于java中的自动转型的理解:顾名思义,自动转型值得就是使用时自动的将自身的类型进行转化. 自 ...
- 【265】shell文件创建链接
优点:可以在其他文件夹内运行对应的*.sh文件,例如通过putty会默认进入的文件夹,可以将链接文件放在那里,就可以直接调用了! 方法:很简单 1. 在文件上点击右键>创建链接 2. 可以对下面 ...
- day17-jdbc 4.DriverManager详解
我们找的不是J2EE的API,因为JDBC不在web程序用也可以,纯java也能玩.所以jdbc的api在java se那里,或者说是在jdk那里. DriverManger它底层有一个集合是一个Ve ...
- php学习笔记-关联数组
传统的数组定义方法如下: <?php $names[0]= 'chinese'; $names[1]= 'math'; $names[2]= 'english'; echo $names[2]; ...
- Bootstrap 的 Dropdown
一.简介 Dropdown 就是下拉列表,这里 有一个例子. Dropdown 的完整代码如下: <div id="dropdownWrapper"> <butt ...
- C++面试笔记--继承和接口
整个C++程序设计全面围绕面向对象的方式进行.类的继承特性是C++的一个非常重要的机制.继承特性可以使一个新类获得其父类的操作和数据结构,程序员只需在新类中增加原有类没有的成分. 在面试过程中,各大企 ...
- idea中解决Error:java: Compilation failed: internal java compiler error的问题
项目中,使用gradle做项目构建,当我们想更改JDK的版本时,报以下错误: Information:Using javac 1.8.0_111 to compile java sourcesInfo ...
- WebGoat系列实验Authentication Flaws
WebGoat系列实验Authentication Flaws Forgot Password Web应用经常给用户提供取回密码的功能,但是许多应用的实现策略实现的很差,用于验证用户的信息非常简单. ...