STM8单片机SPI通讯原理、标准库函数、驱动代码详解

STM8单片机教程10   SPI通讯

 

注意:本文案需要配合无际单片机编程-STM8单片机教程视频学习。

注意:本文案需要配合无际单片机编程-STM8单片机教程视频学习。

 

SPI通讯

一  本节课的目标

  • 学习了解SPI 通讯原理
  • 完成STM8单片机的SPI的驱动
  • 获取SX1278的软件版本号

 

二 硬件介绍:

打开“lora门磁&遥控器“的主板原理图,如图所示:

本章节涉及的电路,如下图所示:

通过上图,可以看出射频芯片SX1278和单片机通过SPI接口来通讯的。 本节课就是通过单片机的SPI接口来完成SX1278芯片的SPI接口通讯。

 

三 SPI通讯原理简单介绍(理解)

典型的连线图:

简单的原理分析:

SCK : 决定数据的速率

据: 1高电平  0 低电平

 

SPI的四种通讯模式:

spi协议时序图和四种模式实际应用详解 (qq.com)  大家可以看一下这个资料:

 

首先我们要了解两个特殊寄存器  分别是 CPOL (Clock POlarity)和 CPHA (Clock PHAse)。

CPOL:配置SPI总线的极性

CPHA:  配置SPI总线的相位

 

SPI总线极性的概念: 空闲的时候时钟信号是高电平还是低电平

CPOL = 1;  SCK 空闲是高电平

CPOL = 0;  SCK 空闲是低电平

 

SPI总线的相位的概念:

一个时钟周期有2个跳变沿,相位决定从那个跳变开始采集数据

CPHA = 0; 表示从第一个跳变 开始采集

CPHA = 1; 表示从第二个跳变 开始采集

 

SPI的单线 和双线 模式

单线:一般用于OLED屏幕灯单向通讯

双向:一般用于芯片之间的双向通讯

 

特别说明: 一般情况下,我们不用刻意去学习四种模式的具体细节,一般芯片资料里面都会告诉你芯片支持的模式:

例如:SX1278 收据手册中77页面。

 

四 官方提供例程(跳过)

 

五 SPI通信 标准库函数简单介绍(了解)

void SPI_DeInit(void);

void SPI_Init(SPI_FirstBit_TypeDef SPI_FirstBit, SPI_BaudRatePrescaler_TypeDef

              SPI_BaudRatePrescaler, SPI_Mode_TypeDef SPI_Mode, SPI_CPOL_TypeDef

              SPI_CPOL, SPI_CPHA_TypeDef SPI_CPHA, SPI_DirectionMode_TypeDef

              SPI_DirectionMode, SPI_NSS_TypeDef SPI_NSS);

void SPI_Cmd(FunctionalState NewState);

void SPI_ITConfig(SPI_IT_TypeDef SPI_IT, FunctionalState NewState);

void SPI_NSSInternalSoftwareCmd(FunctionalState NewState);

void SPI_BiDirectionalLineConfig(SPI_Direction_TypeDef SPI_Direction);

void SPI_SendData(uint8_t Data);

uint8_t SPI_ReceiveData(void);

FlagStatus SPI_GetFlagStatus(SPI_FLAG_TypeDef SPI_FLAG);

ITStatus SPI_GetITStatus(SPI_IT_TypeDef SPI_IT);

void SPI_ClearFlag(void);

void SPI_ClearITPendingBit(void);

 

六 驱动代码实现(掌握)

1.驱动代码编辑:

复制标准工程并命名为  “测试例程-SPI通讯“  如下图所示:

打开工程,修改测试例程中的编辑main.c 函数:

 

2  main.c 源代码

#include “stm8l10x.h”

#define RF_RST_PORT    GPIOC

#define RF_RST_PIN     GPIO_Pin_0

#define RF_RST_HIGH    GPIO_SetBits(RF_RST_PORT,RF_RST_PIN)

#define RF_RST_LOW    GPIO_ResetBits(RF_RST_PORT,RF_RST_PIN)

//输入

#define MISO_PORT GPIOB

#define MISO_PIN GPIO_Pin_7

#define MISO_DATABIT GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)

//输出

#define MOSI_PORT GPIOB

#define MOSI_PIN GPIO_Pin_6

#define MOSI_HIGH GPIO_SetBits(MOSI_PORT,MOSI_PIN)

#define MOSI_LOW GPIO_ResetBits(MOSI_PORT,MOSI_PIN)

#define SCK_PORT GPIOB

#define SCK_PIN GPIO_Pin_5

#define SCK_HIGH GPIO_SetBits(SCK_PORT,SCK_PIN)

#define SCK_LOW GPIO_ResetBits(SCK_PORT,SCK_PIN)

//CS

#define CS_PORT GPIOB

#define CS_PIN GPIO_Pin_4

#define CS_HIGH GPIO_SetBits(CS_PORT,CS_PIN)

#define CS_LOW GPIO_ResetBits(CS_PORT,CS_PIN)

//输入

#define RF_IRQ_DIO0_PORT    GPIOB

#define RF_IRQ_DIO0_PIN GPIO_Pin_0

#define RF_IRQ_DIO0_DATABIT  GPIO_ReadInputDataBit(RF_IRQ_DIO0_PORT,RF_IRQ_DIO0_PIN)

unsigned char SpiInOut(unsigned char outData)

{

unsigned char rxData = 0;

while(SPI_GetFlagStatus(SPI_FLAG_TXE ) == RESET );

SPI_SendData(outData);

while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET );

rxData=SPI_ReceiveData();

return rxData;

}

void sx1278WriteBuffer(unsigned char addr,unsigned char *buffer,unsigned char size)

{

unsigned char i;

CS_LOW;

SpiInOut(addr | 0x80 );

for( i = 0; i < size; i++ )

{

SpiInOut(buffer[i] );

}

CS_HIGH;

}

///SX1278 写寄存器操作   STM8L101F3  SPI 只有

void sx1278ReadBuffer(unsigned char addr,unsigned char *buffer,unsigned char size)

{

unsigned char i;

CS_LOW;

SpiInOut(addr & 0x7F);

for( i = 0; i < size; i++ )

{

buffer[i] = SpiInOut(0);

}

CS_HIGH;

}

static void hal_Sx1278_GpioInt(void)

{

GPIO_Init(RF_RST_PORT,RF_RST_PIN , GPIO_Mode_Out_PP_Low_Slow);

GPIO_Init(SCK_PORT,SCK_PIN , GPIO_Mode_Out_PP_Low_Fast);

GPIO_Init(MISO_PORT,MISO_PIN , GPIO_Mode_In_PU_No_IT);

GPIO_Init(MOSI_PORT,MOSI_PIN , GPIO_Mode_Out_PP_Low_Fast);

GPIO_Init(CS_PORT,CS_PIN , GPIO_Mode_Out_PP_Low_Fast);

GPIO_Init(RF_IRQ_DIO0_PORT,RF_IRQ_DIO0_PIN,GPIO_Mode_In_PU_No_IT);

CS_HIGH;

RF_RST_HIGH;

}

void hal_spi_Config(void)

{

//SPI 时钟配置

CLK_PeripheralClockConfig(CLK_Peripheral_SPI, ENABLE);

/////SPI 相关的 GPIO 配置

hal_Sx1278_GpioInt();

//SPI参数初始化

SPI_Init(SPI_FirstBit_MSB, SPI_BaudRatePrescaler_2, SPI_Mode_Master,SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_2Lines_FullDuplex,SPI_NSS_Soft);

//使能SPI

SPI_Cmd(ENABLE);

}

void main(void)

{

static uint8_t versionvalue = 0;

///设置系统时钟   16M

CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1);

//SPI 初始化

hal_spi_Config();

////多读取几次,确保通讯正常

sx1278ReadBuffer(0x42, &versionvalue,1); //读操作

sx1278ReadBuffer(0x42, &versionvalue,1);

sx1278ReadBuffer(0x42, &versionvalue,1);

sx1278ReadBuffer(0x42, &versionvalue,1);

sx1278ReadBuffer(0X01, &versionvalue,1);

versionvalue = 8;

sx1278WriteBuffer(0X01,&versionvalue,1);  ////写操作

sx1278ReadBuffer(0X01, &versionvalue,1);

sx1278ReadBuffer(0X01, &versionvalue,1);

sx1278ReadBuffer(0x42, &versionvalue,1);

sx1278ReadBuffer(0x42, &versionvalue,1);

while (1)

{

}

}

 

七 实验需要的器材和硬件连接方式

1.实验需要的器材:

2.连接图如下:

连接方式: 

  • ST-LINK 和门磁主板的烧录接口P3的丝印要一一对应。 如上图蓝色所示:
    • VCC  —-  3.3V
    • GND  —-  GND
    • SWIM —-  SWIM
    • REST —-    RST
  • 电池供电 3.7V 锂电池插到J1 接口,如上图黄色所示。
  • ST LINK 插到电脑USB接口。 如上图红色所示。
  • 建议大家都可以自行购买一个USB Hub。  这样测试更加方便,也可以避免电脑的USB插拔次数过多而老化。

 

八 功能测试

功能测试正常。

本小节结束

给TA买糖
共{{data.count}}人
人已赞赏
单片机百科单片机自学指南

STM8单片机串口工作原理、库函数、驱动代码详解

2023-5-25 15:16:09

单片机百科单片机自学指南

STM8内部EEPROM读写、程序、功能测试详解

2023-5-25 16:26:26

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧