初级会员

- 积分
- 71
- 金钱
- 71
- 注册时间
- 2020-10-27
- 在线时间
- 19 小时
|
3金钱
我用F103作为主机,F407作为从机,从机采用SPI中断接收,主机第一次发送数据时,收到的第一个字节为0,第二次发送数据时,第一个字节为上一次发送数据的最后一个字节。如下图所示:
路过的朋友还望帮忙看看,谢谢!
主从机SPI配置函数、main函数及中断函数如下所示:
主机:
int main(void)
{
int i, key;
int sum=0;
/* 上电初始化 */
LED_Init();
delay_init(); //延时函数初始化
bsp_SPI2_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
KEY_Init(); //按键初始化
printf("start\n");
printf("%d \n",SPI2->SR);
while(1)
{
key = KEY_Scan(0);
if(key==KEY0_PRES) //KEY0按下
{
CS0 = 0;
while (ucTxIdx < BufferSize)
{
/* 等待发送缓冲区为空 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, ucSPI2_Buffer_Tx[ucTxIdx++] + cnt); // ucSPI2_Buffer_Tx[BufferSize] = { 0x06, 0x07, 0x08, 0x09 };
/* 等待接收缓冲区非空 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
ucSPI2_Buffer_Rx[ucRxIdx++] = SPI_I2S_ReceiveData(SPI2);
}
ucTxIdx=0;
ucRxIdx=0;
delay_us(10);
CS0 = 1;
printf("F103发送数据为:");
for(i=0; i<BufferSize; i++)
printf("%d ",ucSPI2_Buffer_Tx + cnt);
printf("\n");
printf("接收数据为:\n");
for(i=0; i<BufferSize; i++)
{
printf("%d ",ucSPI2_Buffer_Rx);
}
printf("\n");
cnt++;
}
}
}
void bsp_SPI2_Init(void)
{
/* 定义SPI结构体变量 */
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* SPI的IO口和SPI外设打开时钟 */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE);
/* SPI的CLK口设置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* SPI的MISO口设置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* SPI的MOSI口设置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//把PB12作为CS0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.12
/* SPI的基本配置 */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI工作模式:设置为从SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2, ENABLE); // 使能SPI2外设
LED0 = 0;
}
从机:
int main(void)
{
u8 key,cnt=0;
int i=0;
u8 res;
int sum=0;
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
SPI1_Init(); //SPI1初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置系统中断优先级分组2
printf("start\n");
while(1)
{
delay_ms(1000);
key = KEY_Scan(0);
printf("F403发送数据为:");
for(i=0; i<BufferSize; i++)
printf("%d ",ucSPI1_Buffer_Tx);
printf("\n");
printf("接收数据为:\n");
for(i=0; i<BufferSize; i++)
{
printf("%d ",ucSPI1_Buffer_Rx);
sum = sum + ucSPI1_Buffer_Rx;
}
printf("\n");
printf("sum = %d \n",sum);
printf("ss = %d \n",ss);
sum=0;
}
}
void SPI1_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 开启时钟 */
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE);
/* 设置引脚复用 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
/* 配置引脚: SCK */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 配置引脚: MISO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 配置引脚: MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
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;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SPI1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2 ; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
/* SPI配置:从模式、全双工 */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; // 设置SPI工作模式:设置为从SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; // NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
/* SPI1使能 */
SPI_Cmd(SPI1, ENABLE);
}
void SPI1_IRQHandler(void)
{
SPI1->DR = ucSPI1_Buffer_Tx[cntc]; //ucSPI1_Buffer_Tx[BufferSize] = { 0x01, 0x02, 0x03, 0x04};
while( SPI1->SR & 0x1 )
{
ucSPI1_Buffer_Rx[cntc] = SPI1->DR;
}
cntc++;
ss++;
if(cntc>=BufferSize)
{
cntc = 0;
}
LED0= !LED0;
}
|
|