前言

以前玩过一点 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的更多相关文章

  1. linux enc28j60网卡驱动移植(硬件spi和模拟spi)

    本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是 ...

  2. 关于STM8S使用硬件SPI收发问题

    源: 关于STM8S使用硬件SPI收发问题

  3. STM32 关于HAL库硬件SPI要注意的问题总结

    利用STM32CUbeMx编写程序,大大方便了开发,最近做的项目利用到了 STM32CUbeMx的硬件SP,这里对SPI的使用做一个总结. HAL库里的硬件SPI主要有以下几个库函数: /* hspi ...

  4. 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  5. 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  6. 联盛德 HLK-W806 (十一): 软件SPI和硬件SPI驱动ST7567液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  7. STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI

    1.AD7799介绍 AD7799结构图如下所示: 其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示: 注意: 如果REG_CONFIG的 ...

  8. spi子系统之驱动SSD1306 OLED

    spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...

  9. 基于TQ2440的SPI驱动学习(OLED)

    平台简介 开发板:TQ2440 (NandFlash:256M  内存:64M) u-boot版本:u-boot-2015.04 内核版本:Linux-3.14 作者:彭东林 邮箱:pengdongl ...

随机推荐

  1. linux命令-passwd

    修改密码 #passwd 新密码 重新输入密码 #passwd dennywang  ////命令+用户名 ////////////////////////////////////////////// ...

  2. VS2015 MSVC编译FFMPEG

    1.下载安装msys2 http://www.msys2.org/下载msys2 下载安装完成后,在msys2的shell中安装编译FFMPEG必要的命令行工具 pacman -S make gcc ...

  3. 记录下Linux难记实用的命令

    看文件大小:du -sm * | sort -n 合并多个文件,可以跨文件夹合并:cat *_.txt >> news.txt 给文件改编码:iconv -f GBK -t UTF-8 原 ...

  4. MyBatis总结四:配置文件xml详解

    XML 映射配置文件 MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配置 ...

  5. 【整理】使用AIDL跨进程传递复杂对象的实践例子

    首先定义对象类,并实现Parcelable接口,实现接口内的几个方法,看代码,Person.java package com.example.u3.aidltest; import android.o ...

  6. Node 中的 stream (流)

    流的概念 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流 ...

  7. Tensorflow fetch和feed

    import tensorflow as tf #Fetch input1 = tf.constant(1.0)input2 = tf.constant(3.0)input3 = tf.constan ...

  8. Linux共享对象之编译参数 -fPIC

    转载自:https://www.cnblogs.com/cswuyg/p/3830703.html     在Linux系统中,动态链接文件称为动态共享对象(DSO,Dynamic Shared Ob ...

  9. c语言学习笔记 const变量

    在c语言的编程过程中经常会遇到有常数参加运算的运算,比如这种. int a=100*b; 这个100我们叫常数或者叫常量,但是程序中我们不推荐这种直接写常数的方法,有两个缺点. 第一是程序可读性差. ...

  10. 算法Sedgewick第四版-第1章基础-010一检查括号是否成对出现

    /****************************************************************************** * Compilation: javac ...