【转】spi测试自发自收(中断通信方式)
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测试自发自收(中断通信方式)的更多相关文章
- 树莓派_Linux串口编程_实现自发自收
串口是计算机上一种很通用设备通信的协议,经常使用PC机上包括的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用. Linux对全部设备的訪问是通过设备文件来进行的,串口也是这样,为了訪问 ...
- 嵌入式linux串口通信自发自收测试程序
/*串口自收自发程序主函数*/#include"uart_api.h"int main(){ int fd; char buff[BUFFER_SIZE]; char buff2 ...
- android sdk manager无法更新(2014-11-6测试OK)--自己收藏用
问题描述: Android SDK Manager 无法下载更新,或者更新速度超慢,或者待安装包列表不显示. 解决方法: 第一,我们先修改下hosts文件.该文件的位置在系统盘(一般为C盘), ...
- 树莓派4B串口测试与开发
参考文档: https://shumeipai.nxez.com/2021/08/09/raspberry-pi-4-activating-additional-uart-ports.html 树莓派 ...
- Modbus Poll :Byte Missing Error或CRC Error
原因: 1.通信线路受干扰或是路线接触不良: 用显示器测量物理电平信号 2.从机工作不正常: 检测电源不正常或查程序bug 3.PC主机串口不正常: PC串口2.3脚答短接用串口调试器测 ...
- [转]使用Beaglebone Black的SPI
分类: Beaglebone Black2013-11-24 18:21 678人阅读 评论(6) 收藏 举报 beaglebone blackbeagleboneSPIdevice tree 目 ...
- 工作笔记——CPLD与MCU通过SPI通信
一.需求描述 MCU需要接收来自CPLD的升级固件数据 CPLD对MCU只进行发送数据,不接收MCU的数据 CPLD无法告知数据传输的开始和结束,需要MCU自行判断(CPLD只是数据透传,不做数据判断 ...
- 三,ESP8266 SPI
重点是说SPI通信协议,,,, 不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议既然能成为规范让所有人所接受,那么必然有它的优势和优点,必然值得学习,, 害怕协议的人是因为当初碰到 ...
- 【转载】app测试的过程和重点关注内容
针对 app测试的过程和重点关注内容,做以下梳理和总结: 1 . 首先是测试资源确认及准备 ( 1 ) 产品需求文档.产品原型图.接口说明文档以及设计说明文档等应齐全: ( 2 ) 测试设备及工具 ...
随机推荐
- FFT&NTT
https://winniechen.cn/?p=377 内容有些多,我就不复制了...
- 大数据入门第十七天——storm上游数据源 之kafka详解(三)其他问题
一.kafka文件存储机制 1.topic存储 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序 ...
- EasyUI-Tree的使用
在web开发中,树是比较常见的东西.以前用过zTree,也用过EasyUI-Tree,过了好久后发现都忘记怎么用了. 这几天重新回顾了EasyUI-tree的使用,在此将相关知识点记录 ...
- 总结:C# 委托的全面理解
在说事件之前得先了解委托. 委托,外表看来和C/C++中函数指针没什么区别,但是本质上你才发现他其实就是个类!也就是说理解委托得从 这个两个方面去理解(单从一个方面去理解感觉就怪怪的呵呵!) 理解委托 ...
- CF891C Envy
题面 题解 首先要知道两个性质: 对于任意权值,最小生成树上该权值的边数是相同的. 对于任意一个最小生成树,当加完所有权值小于一个任意值的边之后,当前图的连通性是一样的. 于是我们按照权值分开处理,对 ...
- 问题解决:IDEA右键选择new新文件的时候没有JSP文件选项解决
参考: https://blog.csdn.net/tomorrow_fine/article/details/74090308 用上面的方法就可以解决了, 但是如果把web目录设置成了额外的,那id ...
- 解决 div 设为 inline-block 后标题不对齐
vertical-align 属性设置元素的垂直对齐方式.该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐.允许指定负长度值和百分比值.这会使元素降低而不是升高.在表单元格中,这个属性会设置 ...
- [CF1039D]You Are Given a Tree[贪心+根号分治]
题意 给你\(n\)个点的树,其中一个简单路径的集合被称为\(k\)合法当且仅当树的每个节点最多属于一条路径,且每条路径包含\(k\)个节点.对于每个\(k(k \in [1,n])\),输出最多的\ ...
- EOS 权限管理之-权限的使用
首先,跟大家说声抱歉,由于之前一直在准备EOS上线的一些工作,所以,很长时间没有更新内容.今天正好有时间,也想到了一些题材,就来说一下这个话题.本文完全是个人见解,如有不当之处,欢迎指出. 前提回顾: ...
- sqlserver-表分区
最近对公司数据库性能方面改造.现已初建成效. 公司原先数据库问题颇多,简单列举下: 1.数据表文档缺失. 2.数据库900多张表,接近一半都是备份和一些报表,没有分库处理 3.大数量的表按照年份人工导 ...