OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1997|回复: 1

SPI通信,从机能收到主机的发送信息,主机收不到从机的信息,小弟初学SPI,不是很懂,求回复,谢谢!

[复制链接]

9

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2017-6-16
在线时间
46 小时
发表于 2017-6-16 16:00:44 | 显示全部楼层 |阅读模式
2个STM32进行SPI通信,一个作为主机发送和接收   一个作为从机接收和发送。实验现象是从机能收到主机的数据,但是主机收不到从机的数据。主机程序如下:

#include "stm32f10x.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void SPI_Configuration(void);

void USART1_Send_String(u8 *p)
{   
                 while(*p)
                 {         
                     USART_ClearFlag(USART1, USART_FLAG_TC);
                     USART_SendData(USART1,*p++);                         
                     while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
                 }
}

int main(void)
{
        u8 i,j;
        u8 send='A';
        u8 Buffer[20];
        RCC_Configuration();
       GPIO_Configuration();
        SPI_Configuration();
        USART_Configuration();
       
        USART1_Send_String("spi set data start\r\n");
                for(i=0;i<20;i++)
                {
                SPI_I2S_SendData(SPI1,send);
                while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);       //主机发送和接收
                send++;
                while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
                Buffer[i]= SPI_I2S_ReceiveData(SPI1);
                }
                   for(j=0;j<20;j++)
           {
                while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);   //串口打印接收
                USART_SendData(USART1,Buffer[j]);
           }
        USART1_Send_String("spi set data over\r\n");
        while(1);         
}
void GPIO_Configuration(void)      //spi和串口管脚配置
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void RCC_Configuration(void)
{
  RCC_DeInit();   
  RCC_HSEConfig(RCC_HSE_ON);//使能外部高速时钟
  while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
        FLASH_SetLatency(FLASH_Latency_2);
  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        RCC_HCLKConfig(RCC_SYSCLK_Div1);   //HCLK=SYSCLK
        RCC_PCLK2Config(RCC_HCLK_Div1);    //PCLK2=HCLK
        RCC_PCLK1Config(RCC_HCLK_Div2);    //PCLK1=HCLK/2
        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);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);       
}

void SPI_Configuration()
{
        SPI_InitTypeDef        SPI_InitStructure;//声明一个结构体变量       
        SPI_Cmd(SPI1,DISABLE);   
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主spi
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//数据大小:8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//数据下降沿输出
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号有SSI控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//波特率预分频值为4
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;//数据传送从最低位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;
       
        SPI_Init(SPI1,&SPI_InitStructure);
        SPI_Cmd(SPI1,ENABLE);//使能SPI1       
}

void USART_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Cmd(USART1, ENABLE);       
  USART_Init(USART1, &USART_InitStructure);
}


从机程序如下:
#include "stm32f10x.h"
#include "spi.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void SPI_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);

void USART1_Send_Strin(u8 *p)
{   
                 while(*p)
                 {         
                     USART_ClearFlag(USART1, USART_FLAG_TC);
                     USART_SendData(USART1,*p++);                         
                     while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
                 }
}

int main(void)
{
        u8 Buffer[20];
        u8 send='W';
        u8 ReceivedData,i,j;
        RCC_Configuration();
    GPIO_Configuration();
        SPI_Configuration();
        USART_Configuration();
        NVIC_Configuration();

        USART1_Send_Strin("spi get data start\r\n");
        for(i=0;i<20;i++)
        {
                while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);    //从机接收和发送数据
                Buffer[i]= SPI_I2S_ReceiveData(SPI1);
                SPI_I2S_SendData(SPI1,send);
        }       
        for(j=0;j<20;j++)
        {
                while(USART_GetFlagStatus( USART1,  USART_FLAG_TC)==RESET);    //串口打印数据
                USART_SendData(USART1,Buffer[j]);
        }       
        USART1_Send_Strin("spi get data over\r\n");
while(1);        

}
void GPIO_Configuration(void)    //spi和串口管脚配置
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
        //设置主机NSS位
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
        //从机时钟配置
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void RCC_Configuration(void)
{
  RCC_DeInit();  
  RCC_HSEConfig(RCC_HSE_ON);//使能外部高速时钟
  while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
        FLASH_SetLatency(FLASH_Latency_2);
  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        RCC_HCLKConfig(RCC_SYSCLK_Div1);   //HCLK=SYSCLK
        RCC_PCLK2Config(RCC_HCLK_Div1);    //PCLK2=HCLK
        RCC_PCLK1Config(RCC_HCLK_Div2);    //PCLK1=HCLK/2
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        RCC_PLLCmd(ENABLE);
       
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};       

  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  /* Wait till PLL is used as system clock source */
  while(RCC_GetSYSCLKSource()!= 0x08);
  /* Enable GPIOB, GPIOC and AFIO clocks */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);       
}

void SPI_Configuration()
{
        SPI_InitTypeDef        SPI_InitStructure;//声明一个结构体变量       
        SPI_Cmd(SPI1,DISABLE);   
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;//从spi
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//数据大小:8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//数据下降沿输出
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号有SSI控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//波特率预分频值为4
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;//数据传送从最低位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;
       
        SPI_Init(SPI1,&SPI_InitStructure);
//        SPI_I2S_ITConfig( SPI1, SPI_I2S_IT_RXNE, ENABLE );//开启中断
        SPI_Cmd(SPI1,ENABLE);//使能SPI1       
}
void USART_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Cmd(USART1, ENABLE);       
  USART_Init(USART1, &USART_InitStructure);
}

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

        #ifdef VECT_TAB_RAM
           NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
        #else                                       // 此处为中断向量表起始地址
            NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
        #endif

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                          //        NVIC优先级分组2 4个抢占优先级 4个次级优先级

  NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;           // 使能外部中断通道 EXTI13
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;                 //        抢占优先级别为2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                           // 次优先级别为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                         //         使能
  NVIC_Init(&NVIC_InitStructure);

}
//本来打算spi中断接收的 但是配置中断后接收不到数据 所以上面使能中断被注销掉了 可忽略

不知道怎么上传图片就把内容贴上来吧,从机串口信息:“  spi get data start
AUuQu昭QUU資跽賁慤]spi get data over”   忽略乱码的话 从机spi确实收到数据了  

主机串口信息:“spi set data start”     没有执行到后面的这一句        USART1_Send_String("spi set data over\r\n");


求大神们帮忙看看程序哪里有问题,谢谢了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

26

主题

193

帖子

8

精华

金牌会员

Rank: 6Rank: 6

积分
1800
金钱
1800
注册时间
2012-8-23
在线时间
57 小时
发表于 2017-6-16 17:45:15 | 显示全部楼层
https://item.taobao.com/item.htm ... amp;id=545509364910
USB2SPI适配器,支持主机和从机模式,最大时钟频率50M
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-12-23 12:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表