项目场景:
提示:这里简述项目相关背景:
使用STM32F103C8T6的SPI与外设通信遇到的一些问题和经验教训
问题描述
项目中的问题:
STM32F103C8T6的SPI与外设DAC进行数据通信时遇到一些问题,导致无法控制外设执行相应的功能。遇到的问题如下: 1、SPI1_SCK时钟引脚始终无法输出时钟信号 2、SPI2_SCK设置SPI2默认空闲状态下是高电平,时钟信号可以输出,但是时钟为低电平时无法拉低到0V反而是在1V左右;
原因分析:
针对问题1:
可以看到这里的SPI1_SCK引脚和芯片的调试管脚是同一个,芯片上电默认该引脚为调试引脚,电平为高电平,导致芯片的SPI1_SCK是无法拉低的。该问题在stm32芯片手册上有提及: 找到芯片的复用重映射和调试I/O配置寄存器(AFIO_MAPR)的24:26位,可以看到相关解释说明:即通过修改这3位的配置可以关闭调试引脚配置,释放响应的IO口。实际使用中通过开启AFIO辅助时钟,将SWJ_CFG配置为2或者3即可当做普通IO使用,但如想作为SPI1时钟引脚,还需在MAPR寄存器开启SPI1的重映射!
开启SPI1的重映射才会有时钟信号输出!
针对问题2:
SPI2_SCK低电平无法拉低的问题,是由于SPI2的相连接的外设DAC的时钟引脚和片选引脚之间有个焊锡给连接起来了,导致了电平无法拉低。
解决方案:
提示:针对问题1:
配置SPI1时关闭调试引脚PB3,开启SPI1的重映射功能即可:
RCC->APB2ENR |= 1<<0; //开启AFIO辅助时钟 AFIO->MAPR |= 2<<24; //关闭JTAG,启用SW模式 AFIO->MAPR |= 1<<0; //开启重映射: 注意不建议配置为JTAG-DPDP,关闭SW-DP,那会导致芯片锁死,无法进行程序下载和程序调试!! 如芯片不小心被锁死可以通过以下方法尝试解决: 1、首先将电路板供电断开,包括3.3V电源供电和JLINK调试线供电等所有供电电源关闭; 2、找到芯片的BOOT0引脚,将BOOT0拉高。可以通过导线连接到一个3.3V的引脚,注意不要接入高于3.3V电压,否则烧坏板子! 3、BOOT0拉高以后,保持住这个高电平,打开电源,重新给板子上电。 4、接上JLink或者STLink,下载程序。下载完成以后,断开BOOT0,恢复低电平。 详细方法和解释可以参考: 原文链接:https://blog.csdn.net/Ace_Shiyuan/article/details/60139865
附SPI的一般初始化配置 void SPI1_Init(void) {
RCC->APB2ENR |= 1<<0; //开启AFIO辅助时钟
AFIO->MAPR |= 2<<24; //关闭JTAG
AFIO->MAPR |= 1<<0; //开启重映射
RCC->APB2ENR|=1<<3; //PORTB时钟使能,根据LMH6518的SCK\SDI连接线实际使用的IO口确定
RCC->APB2ENR|=1<<12; //SPI1时钟使能
//SPI口初始化配置
GPIOB->CRL&=0XFF0F0FFF; //寄存器对应位清空
GPIOB->CRL|=0X00B0B000; //PB3\PB5复用推挽模式,最大速度50M,对应SCK\SDO
SPI1->CR1|=0<<11; //8bit数据格式
SPI1->CR1|=0<<10; //全双工模式
SPI1->CR1|=1<<9; //软件nss管理
SPI1->CR1|=1<<8;
SPI1->CR1|=1<<2; //SPI主机
SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1
SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1
//对SPI1属于APB2的外设.时钟频率最大为36M.
SPI1->CR1|=7<<3; //Fsck=Fpclk1/8
SPI1->CR1|=0<<7; //MSBfirst
SPI1->CR1|=1<<6; //SPI设备使能
SPI1_ReadWriteByte(0xff);//启动传输,提供SCK时钟
|