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 ...
随机推荐
- Excel向数据库插入数据(执行一次只需连接一次)-batch简单使用
由于前端时间向数据库插入excel中的数据时,每插入一条数据,就得连接一次数据库:后来发现这种做法不好,如果excel中有很多条数据,就得连接很多次数据库,这样就很浪费资源而且不安全,有时数据库也会报 ...
- python爬虫框架(3)--Scrapy框架安装配置
1.安装python并将scripts配置进环境变量中 2.安装pywin32 在windows下,必须安装pywin32,安装地址:http://sourceforge.net/projects/p ...
- C++知识点总结(6)
1.double和float的存储方式 float遵从的是IEEE R32.24 ,而double 遵从的是R64.53.无论是单精度还是双精度在存储中都分为三个部分: 符号位(Sign) : 0代表 ...
- 修改 linux 时区时间和 php 时区
问题:客户美国服务器时间不对第一步,先修改硬件时区. vim /etc/sysconfig/clock将 ZONE="America/New_York" 注释,加多一行 ZONE= ...
- activeMQ功能Demo
1. 请阐述ActiveMQ的作用 2. 请描述ActiveMQ的工作原理 1. 解决服务之间耦合 2. 使用消息队列,增加系统并发处理量 3. 使用Java程序编写生产者发送10条“你好,activ ...
- ARC102D All Your Paths are Different Lengths
传送门 题目大意 让你构造一个有向图,使得从1到n有L条不同路径且长度分别是0~L-1. 分析 我们不难想到每一对相邻点之间连一条权值为0的边,之后二进制分解,将每一对点之间连一个权值为2^i的边,但 ...
- 1027C Minimum Value Rectangle
传送门 题目大意 有n个木棍,让你选4根使得组成的矩形的周长的平方除以面积最小. 分析 这个题看起来就是一个需要证明的贪心,下面我们来证明一下: 所以我们只需要枚举一边所有的a的可能值,然后b就是比a ...
- svg 标签
SVG中的’defs’ and ‘use’-可复用的图元定义 在下一个示例中,我使用了defs中的元素之前,定义了如何去展现图元. <?xml version="1.0" s ...
- Python中list常用的10个基本方法----list的灰魔法
########################list 的常用的10个基本方法################################## list 类 列表# 1 列表的基本格式#2 可以 ...
- WebGoat系列实验Authentication Flaws
WebGoat系列实验Authentication Flaws Forgot Password Web应用经常给用户提供取回密码的功能,但是许多应用的实现策略实现的很差,用于验证用户的信息非常简单. ...