STM8使用SPI通信需要注意的几个问题

发布者:tanjunhui最新更新时间:2019-05-07 来源: eefocus关键字:STM8  SPI通信 手机看文章 扫描二维码
随时随地手机看文章

概述:

     在使用STM8L101F3单片机,SPI通信读取三轴传感器ADXL362数据时,出现了一系列的问题,在这里做个笔记,也希望可以给大家一个小的参考。


问题一:

      在SPI初始化过程中,没有初始化MISO,MOSI,SCLK三个引脚,导致在通信过程中写数据读数据出现问题。所以在这里贴出测试后可以正常运行的SPI初始化代码。(STM8L101F3,使用官方标准库)


#include "stm8l10x.h"

#include "stm8l10x_spi.h"

#include "stm8l10x_gpio.h"

 

/***************************SPI相关定义**************************/

#define SPI_GPIO_PORT           GPIOB

#define SPI_CS_PIN              GPIO_Pin_4

#define SPI_SCLK_PIN            GPIO_Pin_5

#define SPI_MOSI_PIN            GPIO_Pin_6

#define SPI_MISO_PIN            GPIO_Pin_7

 

/*以下设置为符合我三轴传感器对应配置*/

#define SPI_FIRSTBIT_TYPE       SPI_FirstBit_MSB

#define SPI_SPEED_PRESC         SPI_BaudRatePrescaler_4

#define SPI_MODE                SPI_Mode_Master

#define SPI_CPOL                SPI_CPOL_Low

#define SPI_CPHA                SPI_CPHA_1Edge

#define SPI_DATA_MODE           SPI_Direction_2Lines_FullDuplex

#define SPI_CS_CTRL             SPI_NSS_Soft

 

 

/*SPI初始化*/

void spi_init(void)

{

  //开启SPI外设时钟

  CLK_PeripheralClockConfig(CLK_Peripheral_SPI, ENABLE);

  //SPI重置

  SPI_DeInit();

  //SPI相关GPIO初始化

  GPIO_Init(SPI_GPIO_PORT, SPI_CS_PIN, GPIO_Mode_Out_PP_High_Fast);

  GPIO_Init(SPI_GPIO_PORT, SPI_SCLK_PIN, GPIO_Mode_Out_PP_High_Fast);

  GPIO_Init(SPI_GPIO_PORT, SPI_MOSI_PIN, GPIO_Mode_Out_PP_High_Fast);

  //此设置很关键,作为主设备一定要将其设置为输入

  GPIO_Init(SPI_GPIO_PORT, SPI_MISO_PIN, GPIO_Mode_In_PU_No_IT);

  //SPI初始化

  SPI_Init(SPI_FIRSTBIT_TYPE, SPI_SPEED_PRESC, SPI_MODE, SPI_CPOL, SPI_CPHA,           

  SPI_DATA_MODE, SPI_CS_CTRL);

  //SPI启动

  SPI_Cmd(ENABLE);

}

问题二:

     数据写入与数据读取问题,我在使用过程中,官方库提供了两个函数,一个是写入数据一个是接收数据。因为在我的应用中是需要先写两个字节命令及地址数据,然后再去读后面的数据。故在使用中即先使用SPI_SendData()函数写入数据就并未去读取对应的接收数据。(其实SPI通信读取数据,就是要先写入才能读取,只有写入从设备才有时钟。)然后开始读取数据,发现读取到的数据总是不对,后来通过仪器分析,发现回应的数据中有我需要的数据,但我读到的第一个数据其实是我写入时第一个字节回应的数据,也就是说在写入数据时,如果我们不把对应的数据读出,后面写入数据后再去读取数据,其实还是读取到的第一个字节写入时返回的数据,后面的数据并不会覆盖更新。这里贴一下,更改过后的代码。


/*此部分为写入读取数据部分代码,在读取写入数据前后要记得打开及关闭片选信号*/

 

void spi_write(uint8_t data)

{

    while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);

    SPI_SendData(data);

    //一定不可省略不写,若不接收对应数据,马上去读数据就会造成读到的数据不对。

    while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET);

    u8 dd = SPI_ReceiveData();

}

 

uint8_t spi_read()

{

    //选择一个无效数据发送(自定义,只是为了给从设备提供时钟),然后读取到对应数据

    uint8_t data = 0xff;

    while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);

    SPI_SendData(data);

    while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET);

    uint8_t rxdata  = SPI_ReceiveData();

    return rxdata;

}

 

//写入数据并读取需要的数据

void spi_write2read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen)

{

    uint8_t i;

    if (wdata == NULL || rdata == NULL) {

        return;

    }

    //写数据

    for (i = 0; i < wlen; i++) {

        spi_write(wdata[i]);

    }

    //读数据

    for (i = 0; i < rlen; i++) {

        rdata[i] = spi_read();

    }

}

     总结:

              对于单片机上使用SPI又多了一点认识,哈哈。


关键字:STM8  SPI通信 引用地址:STM8使用SPI通信需要注意的几个问题

上一篇:ADC采样频率计算与时钟频率选择
下一篇:FLASH和EEPROM的区别

推荐阅读最新更新时间:2024-11-13 12:38

IAR FOR STM8 简单使用教程
一、创建工程 1.先创建一个workplace.选择File New Workplace 2.创建一个新的工程,选择Project Creat New Project,如果用的是IAR FOR STM8 就默认无需更改。保存并输入Project名字,在workplace窗口中显示如下 3.在添加文件到工程之前,先保存Workplace。并输入保存的名字,Workplace的扩展名是eww。 4.添加文件到工程. (1)右击工程名 ADD ADD FILES添加 .c文件 (2)添加头文件文件夹路径:右击工程名 Options C/++compiler PreProcessor中加入头文件所在文件夹的路径 例如: $
[单片机]
IAR FOR <font color='red'>STM8</font> 简单使用教程
stm8位带操作
stm8和stm32这里不同,51学来用惯了led=!led;到了stm32有原子哥得位带操作加宏也过得去, 但是到了stm8这玩意儿不支持位带操作,于是乎,百度一番。 大致有两个方法: 一.stvd环境 volatile _Bool PA_ODR_0 @PA_ODR:0; #define LED PA_ODR_0 LED = 1; LED = 0; 这些语句能通过编译少不了stvd环境得原因,我用的iar就过不了编译。 http://bbs.elecfans.com/jishu_453404_1_1.html 二.iar环境 个人觉得iar得库更偏向于使用寄存器,也懒得去啃一
[单片机]
STM8定时器实现精准延时(阻塞)
定时器选择: stm8定时器与stm32定时器略有不同,stm32定时器是24位--16,777,216,按照72M时钟8分频计算,周期达到1.86s左右,而stm8定时器是16/8--位65535/255,自身时钟为16M,即使16分频周期也远小于1s。 当前选择TIM2定时器,1分频,最大周期65536/16 约等于 4096us。 初始化 void TIM_Delay_Init() { /* 自动重装载值范围TIM4为0~255,TIM2为0~65535*/ TIM2_TimeBaseInit(TIM2_PRESCALER_1,65535); //65535*(1/16)≈4095us TIM2_Cmd(
[单片机]
vscode 使用 IAR_STM8 工具链 编译调试 STM8 项目
本文介绍如何在 EIDE 上使用 IAR_STM8 工具链完成项目编译,并使用 STM8-Debug 完成调试 本文以 STM8S105K4T6 为例 1. 使用 EIDE 创建一个 8/16 Bit MCU 项目 2. 项目目录下创建一个文件夹,将 STM8S 标准外设库复制到该目录下 3. 添加宏,本例是:STM8S105 4. 将 STM8S_StdPeriph_Driver 目录添加到项目,并排除 无用和不支持 的外设 排除该 芯片 不支持的外设,和不需要使用的外设 5. 切换到 IAR_STM8 工具链,打开配置,填写要使用的 链接脚本 名称 所有可用的 链接脚本 位置: IAR 安装路径
[单片机]
vscode 使用 IAR_STM8 工具链 编译调试 <font color='red'>STM8</font> 项目
STM8之外部中断长按键识别相关内容
  STM8常用中断指令   开总中断   _asm(“rim”);   禁止中断   _asm(“sim”);   进入停机模式   _asm(“halt”);   中断返回   _asm(“iret”);   等待中断   _asm(“wfi”);   软件中断   _asm(“trap”);   STM8S常用中断映射   如使用中断函数时,可以通过在上图中查找相对应的中断向量号,而中断函数的名字可以自定义   外部中断长按键识别相关配置   ??STM8S为外部中断事件专门分配了五个中断向量:   PortA 口的5个引脚:PA[6:2]   PortB 口的8个引脚:PB[7:0]   PortC 口的8
[单片机]
<font color='red'>STM8</font>之外部中断长按键识别相关内容
STM8 FOR IAR 中实现绝对地址跳转
//使用函数指针来实现 typedef void(*PFUN)(void); pFun =(PFUN)0x8000; (*pFun)(); #define GotoHere(a) ((void (*)(void))a)() GotoHere(0X8000); asm( JP $8000 );
[单片机]
STM8操作LCD5110总结
附上一小段代码: void LCD_init(void) { // 产生一个让LCD复位的低电平脉冲 //LCD_RST = 0; GPIO_WriteLow(LCD_PORTG, LCD_RST); delay_1us(); //LCD_RST = 1; GPIO_WriteHigh(LCD_PORTG, LCD_RST); // 关闭LCD //LCD_CE = 0; GPIO_WriteLow(LCD_PORTG, LCD_CE); delay_1us(); // 使能LCD // LCD_CE = 1; GPIO_WriteHigh(LCD_PORTG, LCD_CE); delay_1us(); LCD_write_by
[单片机]
<font color='red'>STM8</font>操作LCD5110总结
STM8 时钟
时钟控制器功能强大而且灵活易用。其目的在于使用户在获得最好性能的同时,亦能保证消耗的功率最低。用户可独立地管理各个时钟源,并将它们分配到CPU或各个外设。主时钟和CPU时钟均带有预分频器。具有安全可靠的无故障时钟切换机制,可在程序运行中将主时钟从一个时钟源切换到另一个时钟源。抗电磁干扰时钟配置寄存器,STM8为了避免由电磁干扰造成的对应用程序误写操作或系统挂起,大多数关键的时钟配置寄存器都有一个互补寄存器与之相对应。系统将会自动检测这些关键寄存器与其互补寄存器之间是否匹配。如果不匹配,则产生一个EMS复位,从而使应用程序恢复到正常操作。详情请参见时钟寄存器描述。 主时钟源: 1-24MHz高速外部晶体振荡器(HSE)
[单片机]
<font color='red'>STM8</font> 时钟
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved