1、初始化spi时钟

 void spiRccinit(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
}

2、配置spi的GPIO引脚

 void spiGPIOInit(void)
{
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Pin = GPIO_Pin_4; //片选
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &gpio_init); gpio_init.GPIO_Pin = GPIO_Pin_5; //时钟
gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio_init); gpio_init.GPIO_Pin = GPIO_Pin_7; //MOSI
GPIO_Init(GPIOA, &gpio_init); gpio_init.GPIO_Pin = GPIO_Pin_6; //MISO
GPIO_Init(GPIOA, &gpio_init);
}

3、配置并使能spi

 void spiConfigure(void)
{
SPI_InitTypeDef spi_Init;
spi_Init.SPI_CPHA = SPI_CPHA_2Edge;
spi_Init.SPI_CPOL = SPI_CPOL_Low;
spi_Init.SPI_DataSize = SPI_DataSize_8b;
spi_Init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
spi_Init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi_Init.SPI_FirstBit = SPI_FirstBit_MSB;
spi_Init.SPI_Mode = SPI_Mode_Master;
spi_Init.SPI_NSS = SPI_NSS_Soft;
spi_Init.SPI_CRCPolynomial = ; SPI_Init(SPI1, &spi_Init);
SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
SPI_Cmd(SPI1,ENABLE);
}

4、配置spi中断

 void spiNivcConfiguration(void)
{
NVIC_InitTypeDef nvic_init; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
nvic_init.NVIC_IRQChannel = SPI1_IRQn;
nvic_init.NVIC_IRQChannelPreemptionPriority = ;
nvic_init.NVIC_IRQChannelSubPriority = ;
nvic_init.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init);
}

5、实现中断处理函数

 void SPI1_IRQHandler(void)
{
if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != RESET)
{
if(send[++sendCount] != '\0')
{
SPI_I2S_SendData(SPI1, send[sendCount]);
}
else
{
SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_TXE, DISABLE);
}
}
if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET)
{
recv[recvCount] = SPI_I2S_ReceiveData(SPI1);
if(recv[recvCount] == '*')
{
recv[recvCount + ] = '\0';
printf("recv data: %s\r\n", recv);
recvCount = ;
}
else
{
recvCount++;
if(recvCount == )
27        {
recvCount = ;
}
}
}
}

注:中断函数里用到的变量均为全局变量:

 u8 recv[] = {'\0'};
u8 send[] = {'\0'};
volatile u16 recvCount = ;
volatile u16 sendCount = ;

6、实现简单的发送函数:

 void spiWrite(const char *p)
{
strcpy(send, p);
sendCount = ;
// while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, send[sendCount]);
SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_TXE, ENABLE);
// while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
// recv[0] = SPI_I2S_ReceiveData(SPI1);
// recv[1] = '\0';
// printf("recv ok! ");
// printf(recv);
}

7、总结:

  • 仔细阅读stm32 datasheet关于spi的部分
  • 配置spi时钟(一定要先初始化时钟)
  • 配置spi的gpio引脚
  • 配置spi
  • 配置中断
  • 实现中断处理函数
  • 简单实现发送函数

8、遗留问题:   

  采用中断发送的方式,发现在关闭掉SPI中断后(SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_TXE, DISABLE)),还是能进入到发送中断中,所以sendCount的清零要注意,最好不要在中断中。

  原因:猜测是stm32执行SPI_I2S_ITConfig函数时要花费一定的时间,而spi的发送中断在此期间会不断进入。

来源

【转】spi测试自发自收(中断通信方式)的更多相关文章

  1. 树莓派_Linux串口编程_实现自发自收

    串口是计算机上一种很通用设备通信的协议,经常使用PC机上包括的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用. Linux对全部设备的訪问是通过设备文件来进行的,串口也是这样,为了訪问 ...

  2. 嵌入式linux串口通信自发自收测试程序

     /*串口自收自发程序主函数*/#include"uart_api.h"int main(){ int fd; char buff[BUFFER_SIZE]; char buff2 ...

  3. android sdk manager无法更新(2014-11-6测试OK)--自己收藏用

    问题描述: Android SDK Manager 无法下载更新,或者更新速度超慢,或者待安装包列表不显示. 解决方法:     第一,我们先修改下hosts文件.该文件的位置在系统盘(一般为C盘), ...

  4. 树莓派4B串口测试与开发

    参考文档: https://shumeipai.nxez.com/2021/08/09/raspberry-pi-4-activating-additional-uart-ports.html 树莓派 ...

  5. Modbus Poll :Byte Missing Error或CRC Error

    原因: 1.通信线路受干扰或是路线接触不良:    用显示器测量物理电平信号   2.从机工作不正常: 检测电源不正常或查程序bug   3.PC主机串口不正常: PC串口2.3脚答短接用串口调试器测 ...

  6. [转]使用Beaglebone Black的SPI

    分类: Beaglebone Black2013-11-24 18:21 678人阅读 评论(6) 收藏 举报 beaglebone blackbeagleboneSPIdevice tree   目 ...

  7. 工作笔记——CPLD与MCU通过SPI通信

    一.需求描述 MCU需要接收来自CPLD的升级固件数据 CPLD对MCU只进行发送数据,不接收MCU的数据 CPLD无法告知数据传输的开始和结束,需要MCU自行判断(CPLD只是数据透传,不做数据判断 ...

  8. 三,ESP8266 SPI

    重点是说SPI通信协议,,,, 不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议既然能成为规范让所有人所接受,那么必然有它的优势和优点,必然值得学习,, 害怕协议的人是因为当初碰到 ...

  9. 【转载】app测试的过程和重点关注内容

    针对 app测试的过程和重点关注内容,做以下梳理和总结:   1 . 首先是测试资源确认及准备 ( 1 ) 产品需求文档.产品原型图.接口说明文档以及设计说明文档等应齐全: ( 2 ) 测试设备及工具 ...

随机推荐

  1. 20155328 《网络对抗》 实验九 Web安全

    20155328 <网络对抗> 实验九 Web安全 基础 实验过程记录 在实验开始之前先把webgoat的jar包放到home目录下.打开终端,用命令java -jar webgoat-c ...

  2. R绘图 第六篇:绘制线图(ggplot2)

    线图是由折线构成的图形,线图是把散点从左向右用直线连接起来而构成的图形,在以时间序列为x轴的线图中,可以看到数据增长的趋势. geom_line(mapping = NULL, data = NULL ...

  3. 设计模式 笔记 工厂方法 Factory Methon

    //---------------------------15/04/09---------------------------- //factory method 工厂方法-------对象创建型模 ...

  4. <转>性能测试浅谈

    本文主要针对WEB系统的性能测试.不涉及具体的执行操作,只是本人对性能测试的一点理解和认识. 性能测试的目的,简单说其实就是为了获取待测系统的响应时间.吞吐量.稳定性.容量等信息.而发现一些具体的性能 ...

  5. Jmeter(八)-发送JDBC请求

    下午花了两个小时研究了一下Jmeter发送JDBC请求,现在把基本操作流程分享一下. 做JDBC请求,首先需要两个jar包:mysql驱动-mysql-connector-java-5.1.13-bi ...

  6. 解决SSH登录用户执行的命令部分环境变量参数不生效的问题

    问题概况 linux机器在/etc/profile配置完成环境变量后,SSH到目标机器执行命令,但是获取不到已配置的环境变量值. 例如场景: 在/etc/profile配置了http代理 export ...

  7. 机器视觉及图像处理系列之一(C++,VS2015)——搭建基本环境

    自<人脸识别>系列发布至今,已一年多矣,期间除答复些许同好者留言外,未再更新文,盖因项目所迫,不得已转战它途,无暇.无料更博耳.其时,虽人已入项目中,然终耿怀于人脸识别方案之谬.初,写此文 ...

  8. DevOps on AWS之Cloudformation概念介绍篇

    Cloudformation的相关概念 AWS cloudformation是一项典型的(IAC)基础架构即代码服务..通过编写模板对亚马逊云服务的资源进行调用和编排.借助cloudformation ...

  9. 如何将maven项目打包上传到私服

    比如我们想要把项目通过maven生产源码包和文档包并发布到自己的私服上,有两个maven插件可以做到这些工作,一个是maven-source-plugin,另一个是maven-javadoc-plug ...

  10. PAT甲题题解-1035. Password (20)-水

    题意:给n个用户名和密码,把密码中的1改为@,0改为%,l改为L,O改为o. 让你输出需要修改密码的用户名个数,以及对应的用户名和密码,按输入的顺序.如果没有用户需要修改,则输出对应的语句,注意单复数 ...