新手上路
- 积分
- 38
- 金钱
- 38
- 注册时间
- 2017-11-7
- 在线时间
- 6 小时
|
10金钱
配置完SPI和DMA了,主发从,能接到,但是主机在发完进入完发送中断后,会立刻进入主机的接收中断,尽管从机没有数据发送回来,我做了实验排除了几个问题,从机是没有发送数据回来的,我直接把线拔了,也把接收缓存用串口显示,也没有数据,我把开发板的所有线拔了,排除外部干扰,我做了延时发送,排除初始化完立刻进入中断的可能,也就是说,我是在主机发送完之后,主机立刻进入的接收中断
#define SPI1_Tx_Buf_number 10
#define SPI1_Rx_Buf_number 10
[mw_shl_code=c,true]
int main(void)
{
/********************************Ïμí3ê±ÖóÅäÖÃ***********************************************/
SystemInit();
Delay_Ms(1000);
/******************************½ûóÃJTAGμ÷êÔÅäÖÃ*********************************************/
DISABLE_JTAG();
/****************************3õê¼»ˉÖD¶ÏÏò῱íÅäÖÃ*******************************************/
Init_NVIC();
/**********************************IO¿úÅäÖÃ*************************************************/
Init_IO(); //°åÔØLED 3õê¼»ˉ
/***************************UART1′®¿úIO¿ú3õê¼»ˉÅäÖÃ*****************************************/
Init_Usart1(); //óÃóúμ÷êÔ′®¿ú′òó¡êy¾Y
Usart1_Configuration(115200);
Init_SPI_IO();
Init_SPI1();
Init_SPI1_DMA();
Delay_Ms(200);
/*==============================================================================================================================*/
while(1)
{
main_temp_a++;
SPI1_Tx_Buf[0]=(u8)main_temp_a;
SPI1_Tx_Buf[1]=0x12;
SPI1_Tx_Buf[2]=0x12;
DMA_SPI1_Send_Data(SPI1_Tx_Buf_number);
printf("%d\n\n",main_temp_b);
for(main_temp_i=0;main_temp_i<SPI1_Rx_Buf_number;main_temp_i++)
{
printf("%2x ",SPI1_Rx_Buf[main_temp_i]);
}
printf("\n\n");
Delay_Ms(500);
} //while(1)
} //main
[/mw_shl_code]
[mw_shl_code=c,true]
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //定义一个NVIC向量表结构体变量
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组 为2
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
}
void Init_IO(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); //使能各个端口时钟,重要!!!
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用输出推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
GPIO_Init(GPIOD, &GPIO_InitStructure); //根据参数初始化GPIOD寄存器
}
[/mw_shl_code]
[mw_shl_code=c,true]#include "DMA_SPI1.h"
void Init_SPI_IO(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO初始化结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); //GPIO、AFIO时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
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_AF_PP; //将SCK和MOSI管脚设置为复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //将SCK和MOSI管脚设置为复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //将SCK和MOSI管脚设置为复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Init_SPI1(void)
{
SPI_InitTypeDef SPI_InitStructure; //SPI初始化结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE); //使能SPI2时钟
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
}
void Init_SPI1_DMA(void)
{
extern u8 SPI1_Tx_Buf[SPI1_Tx_Buf_number];
extern u8 SPI1_Rx_Buf[SPI1_Rx_Buf_number];
DMA_InitTypeDef DMA_InitStructure; //DMA初始化结构体
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA1时钟
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI1_Tx_Buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = SPI1_Tx_Buf_number;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_GL3); // 清除DMA所有标志
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); //使能DMA1通道5中断,注意一定要是“DMA_IT_TC”,否则会出现进不了中断的问题。
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI1->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI1_Rx_Buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = SPI1_Rx_Buf_number;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_GL2); // 清除DMA所有标志
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); //使能DMA1通道5中断,注意一定要是“DMA_IT_TC”,否则会出现进不了中断的问题。
DMA_Cmd(DMA1_Channel2, ENABLE);
}
void DMA1_Channel2_IRQHandler(void)
{
extern u8 main_temp_b;
main_temp_b++;
if(DMA_GetITStatus(DMA1_IT_TC2)==SET)
{
//DMA1_Channel2->CNDTR =SPI1_Rx_Buf_number;
//DMA_Cmd(DMA1_Channel2,DISABLE);
DMA_Cmd(DMA1_Channel2,ENABLE);
DMA_ClearITPendingBit(DMA1_IT_TC2);
}
}
void DMA1_Channel3_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_FLAG_TC3))
{
DMA_Cmd(DMA1_Channel3,DISABLE);
DMA_ClearFlag(DMA1_FLAG_GL3); // 清除标志
}
}
void DMA_SPI1_Send_Data(u32 size)
{
DMA1_Channel3->CNDTR =size;
DMA_Cmd(DMA1_Channel3, ENABLE);
}
[/mw_shl_code]
|
|