stm32 spi 为什么CS总是会自动拉高呢

新点燃 2015-07-12 06:03:21

这是逻辑分析仪测出来的。
这是我的程序。
只用的spi的单向发送送模式。

/* INCLUDES */
#include "User_Define.h"
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_spi.h"
#define LCD_CS_SET GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define LCD_CS_RESET GPIO_ResetBits(GPIOA,GPIO_Pin_4)

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void SPI1_Configuration(void);
void SPI1_Writebyte(u8 data);

void delay(unsigned char temp)
{
int a,j;
for(a=0;a<temp;a++)
for(j=0;j<100;j++);
}

int main(void)
{

RCC_Configuration();
GPIO_Configuration(); //端口初始化
//NVIC_Configuration(); //中断源配置
SPI1_Configuration();
//__enable_irq();


while(1){
delay(10);
SPI1_Writebyte(0xaa);

}
}

void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ; //SPI CS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ; //SPI MISO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 // SPI MOSI
| GPIO_Pin_5; //SPI CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

}
void RCC_Configuration(void)
{
//--------------------------- CLK INIT, HSE PLL ----------------------------
ErrorStatus HSEStartUpStatus;
//RCC reset
RCC_DeInit();
//开启外部时钟 并执行初始化
RCC_HSEConfig(RCC_HSE_ON);
//等待外部时钟准备好
HSEStartUpStatus = RCC_WaitForHSEStartUp();
//启动失败 在这里等待
while(HSEStartUpStatus == ERROR);
//设置内部总线时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
//外部时钟为8M 这里倍频到72M
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);

//----------------------------- CLOSE HSI ---------------------------
//关闭内部时钟HSI
RCC_HSICmd(DISABLE);


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA
| RCC_APB2Periph_SPI1 //SPI1
, ENABLE);
}
void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //双工模式
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8bit数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //CLK空闲时为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CLK上升沿采样,因为上升沿是第二个边沿动作,所以也可以理解为第二个边沿采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //片选用软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //SPI频率
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
//SPI_InitStructure.SPI_CRCPolynomial = 7; //crc7,stm32spi带硬件ecc
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}

void SPI1_Writebyte(u8 data)
{
LCD_CS_RESET ;
//while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI1, data);
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
LCD_CS_SET;

}

...全文
2484 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
猫鼬桑 2019-07-09
  • 打赏
  • 举报
回复
我也遇到同样的问题,只调用发送函数不调用接收函数的话就会,发送一个字节然后走下一个步程序,然后剩下的数据依旧继续发送,无论这个发送函数调用几次,不知道为什么,但是只要调用发送函数的时候调用了接收函数就能解决。
新点燃 2015-07-12
  • 打赏
  • 举报
回复
搞了半天,果然是判断部分的错误。多谢启动哥同学。也谢谢worldy同学,指出了大概错误的地方。

通信模式改为全双工,单向发送搞不出来。放弃了。。。。。
然后发送函数改成这样
void SPI1_Writebyte(u8 data)
{
LCD_CS_RESET ;
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI1, data);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
LCD_CS_SET;
}
新点燃 2015-07-12
  • 打赏
  • 举报
回复
我用的是3.5的库函数。 没动过函数 /** * @brief Transmits a Data through the SPIx/I2Sx peripheral. * @param SPIx: where x can be * - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode * @param Data : Data to be transmitted. * @retval None */ void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) { /* Check the parameters */ assert_param(IS_SPI_ALL_PERIPH(SPIx)); /* Write in the DR register the data to be sent */ SPIx->DR = Data; }
worldy 2015-07-12
  • 打赏
  • 举报
回复
初步感觉,你的检查 SPI_I2S_SendData(SPI1, data); 这个函数,是否有拉高CS的动作

27,509

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧