STM32F103做从机SPI通信SPI3中断异常

发布者:WhisperingWave最新更新时间:2018-12-03 来源: eefocus关键字:STM32F103  从机  SPI通信  中断异常 手机看文章 扫描二维码
随时随地手机看文章

在做AM335D板子与STM32F103使用SPI通信时,需要用到STM32的从机模式,所以特别对于ST的从机模式进行了研究,由于硬件上使用的是STM32F103的SPI3,所以过程中遇到了一点麻烦,这里记录一下过程,以备查阅:


使用SPI3通信时,从机时钟产生不了中断,经过查阅资料,是因为spi3的nss口与JTAG有共用引脚,所以配置错误会导致SPI3无法使用。需要注意以下两点就可以了:


1.开启GPIO时钟的同时,开启AFIO时钟,如下:


RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );    


2.关闭JTAG功能,使能SWD 如下:


GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ;


其他的SPI口正常配置,因为板子重启后默认为JTAG模式,所以注意千万不要使用GPIO_Remap_SWJ_Disable ,一旦这样就不能下载程序了,要使用ST的那个工具专门烧录。


以下是具体的代码:


extern u8 SPI3_Buffer_Rx[];

extern u8 RxIdx ;

u16 net_spi_Write(void);

 

void SPI3_Slave_Init(void)

{


GPIO_InitTypeDef GPIO_InitStructure;

    //GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );             

    //RCC_APB2Periph_AFIO很重要

RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI3, ENABLE );


GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ; //disable掉JTAG复用,很重要

 

/* MISO设置为推挽输出 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

 

/* SCK和MOSI设置为下拉输入 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

GPIO_Init(GPIOB, &GPIO_InitStructure);

 

SPI3_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 

SPI3_InitStructure.SPI_Mode = SPI_Mode_Slave;

SPI3_InitStructure.SPI_DataSize = SPI_DataSize_8b;


SPI3_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI3_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;


SPI3_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI3_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //

SPI3_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI3_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI3, &SPI3_InitStructure);  //


SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, ENABLE); 

 

SPI_Cmd(SPI3, ENABLE); 


//SPI1_ReadWriteByte(0xff);  

}   

 

  

void SPI3_SetSpeed(u8 SpeedSet)

{

SPI3_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;

    SPI_Init(SPI3, &SPI3_InitStructure);

SPI_Cmd(SPI3,ENABLE);

 

 

u8 SPI3_ReadWriteByte(u8 TxData)

{

u8 retry=0;

while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) //发送缓存标志位

    {

retry++;

if(retry>200)return 0;

}   

SPI_I2S_SendData(SPI3, TxData); //发送数据

retry=0;

 

while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)//接收缓存标志位

{

retry++;

if(retry>200)return 0;

}       

return SPI_I2S_ReceiveData(SPI3); //返回接收到的数据     

}

 

void SPI_net_Init(void)

{

SPI3_Slave_Init();    

 

void NVIC_config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

 

void SPI3_IRQHandler(void) 

{

volatile uint8_t data;

if(SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_RXNE) == SET)

while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)

{

}

SPI3_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI3);

while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)

{

}

SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_RXNE);

}

 

void net_spi_read_loop(void)

{

u8 i;

while (1)

  {

     if(RxIdx>=10)

     {

        SPI_Cmd(SPI3, DISABLE);

        RxIdx=0;

printf("rcv full:\n");

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

           printf("0x%02X ",SPI3_Buffer_Rx[i]);

printf("\r\n ");

memset(SPI3_Buffer_Rx,0,10);

    SPI_Cmd(SPI3, ENABLE);

 

     }

  }



}

 


关键字:STM32F103  从机  SPI通信  中断异常 引用地址:STM32F103做从机SPI通信SPI3中断异常

上一篇:STM32的中断优先级设定
下一篇:STM32F10x系列UART中断异常调试经历

推荐阅读最新更新时间:2024-03-16 16:19

通过库函数使用STM32f103串口中断的心得
STM32使用USART中断主要有一下几步: 1,定义中断结构体,和串口结构体 2,使能时钟 3,编写中断函数 4,使能中断 关于发送中断,笔者当时有个疑惑: 上图是关于状态寄存器(USART_SR)中的两位。 上图是控制寄存器1(USART_CR1)中的两位。 笔者当时的疑惑是,这两位都可以控制中断啊,DR数据被移走触发中断,DR数据被移走也会使TC为置一,也会产生中断,这尼玛不冲突了?笔者当时陷入了死循环。 后来笔者想通了,要进入发送中断,用库函数:USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 这个函数时用来打开CR1中的响应位的,比如上一句
[单片机]
通过库函数使用<font color='red'>STM32f103</font>串口<font color='red'>中断</font>的心得
STM32F103RB 实作笔记(七)- 外来中断试验
关于中断和 计时寄存器的有关理论, 有兴趣的朋友可以看我一年前写的笔记 :“STM32F072RB 实作笔记(五)- 计时器加上中断EXTI_IRQHandler(一)” 和 “(二)” 两篇笔记。 这一篇笔记就直接解析实验的程式内容 main.c 和前几篇一样,进入“实验5 外部中断实验” 的 USER 资料夹点开 MDK 的项目档案。执行编译。 以下是 main.c 的内容: #include key.h #include beep.h #include usart.h #include exti.h /************************************************/ in
[单片机]
<font color='red'>STM32F103</font>RB 实作笔记(七)- 外来<font color='red'>中断</font>试验
Cortex-M3 中异常中断返回 EXC_RETURN
在进入异常服务程序后,硬件自动更新LR的值为特殊的EXC_RETURN。 当程序从异常服务程序返回,把这个EXC_RETURN值送往PC时,就会启动处理器的异常中断返回序列。 因为LR的值EXC_RETURN是由硬件自动设置的,所以只要没有特殊需求,就不要改动它。 RETURN的高28位全为1,只有bit 的值有特殊含义。位段如下: 合法的EXC_RETURN值共有3个,如下: 如果主程序在线程模式下运行,并且在使用MSP时被中断,则在服务程序中LR=0xFFFFFFF9(主程序被打断前LR已被自动入栈)。 如果主程序在线程模式下运行,并且在使用PSP时被中断,则在服务程序中LR=0xFFFFFFFD(主程序被打断前LR已
[单片机]
LCD电极读数的单片接口技术
   摘要 以测量仪表中常见的时分割驱动法驱动的段式LCD显示器为例,分析LCD显示器的电极连接结构和驱动信号波形;介绍单片机读取仪表LCD读数的接口电路。此接口电路应用于笔者开发的自动血压监控仪的研制及临床应用项目中,由8031单片机读取血压计的收缩压、舒张压、心率以及充气和放气时瞬时压强。实验证明,此接口电路工作稳定、可靠。    关键词 LCD电极 读数 时分割驱动法 接口设计   通过测量仪表拾取被测信号是单片机前向通道设计中常用的数据采集方式。通常,接口电路从仪表电路中取得相关的模拟信号,经过A/D转换或V/F 转换送入单片机;或者取得一个频率信号,经整形后送入单片机 。然而,有些测量仪表电路中可能找不到这样的信号。
[单片机]
stm32f103读取红外接收HS0038A2
软件: IAR 7.4 STM32CubeMX 4.14.0 硬件: STM32F103VBT6 原理图,和手册建议的基本一致,只是上拉电阻不是手册建议的10K以上,这里的面板距离控制器比较远,可能是考虑到线阻。 HAL配置,使用Cubemx。 HS0038A2的输出,带有上拉电阻,接着一个led灯,因此TIM3的IC脚浮空。 设计者恰好把IR设计在TIM3的通道4上。如果使用了通道1/2, 就可以使用PWM输入方式来捕捉红外脉冲,可以拿到每个脉冲的数据。 IC模式使用下降沿。 红外控制这里是常用的NEC协议。遥控器输出高电平,而HS0038A2转换低电平输出。 如,一个9ms高+4.5ms的低,组成一个h
[单片机]
<font color='red'>stm32f103</font>读取红外接收HS0038A2
MSP430的HART控制器的设计
引言 现代工业生产活动的正常进行离不开现场设备和与之配套的控制主机,为了充分发挥现场设备的性能,控制主机和现场设备之间必须要有一套高效可靠的通信协议。传统工业控制领域多使用4~20 mA模拟信号来完成现场设备与控制主机之间的通信,但是模拟信号传输数据具有传输方向单一、传输数据量少等诸多不足。为了解决这些问题,在20世纪80年代中期,美国Rosemount公司提出了高速可寻址远程传感器协议(Highway Addressable Remote Transducer,HART)用来增强现场设备与控制主机之间的通信能力。 HART协议是一种用于现场智能设备与控制主机或监测系统之间的通过模拟线路传输数字信号的通信协议,在20世纪90年代初
[单片机]
MSP430的HART<font color='red'>从</font><font color='red'>机</font>控制器的设计
STM32F103模拟IIC
在用STM32F103模拟IIC时,SDA的配置很有意思,既要读数据,又要写数据,这两者之间的切换通过GPIO的配置寄存器来实现。 #define SDA_IN() {GPIOB- CRL&=0X0FFFFFFF;GPIOB- CRL|=8 28;} #define SDA_OUT() {GPIOB- CRL&=0X0FFFFFFF;GPIOB- CRL|=3 28;} 就是这两句话,GPIO配置寄存器分为端口配置低寄存器(GPIOx_CRL) (x=A..E)和端口配置高寄存器(GPIOx_CRH) (x=A..E);在这里用到的是PB7模拟IIC的SDA,所以切换配置时,先将原配置清零,GPIOB- CRL&=0X0FFFFF
[单片机]
<font color='red'>STM32F103</font>模拟IIC
stm32f103的RTC驱动程序
具体问题 这段时间在弄自己的一个《宝宝的气象站》的项目,使用了ESP8266的WiFi模块,使其能够将数据传输到OneNET后台并显示。网络通信使用的是OneNET提供的EDP通信组件,但是RTC遇到了问题。从NTP服务器获取的时间与本地RTC获取的时间有差异。NTP使用的是1970年1月1日作为起始时间点。本地RTC的起始点是2000年1月1日。这样就需要将NTP获取的秒减去两个时间的间隔。 代码 mip_rtc.h /** ***************************************************************************** * @文 件: mip_rtc.h *
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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