本帖最后由 airwill 于 2014-4-11 20:44 编辑
我的配置如下,为什么程序进不了DMA中断呢,设置buffersize大小为6,调试中监控DMA通道2和通道3的剩余数据数目一直为6
#define SPI1_DR_Addr ( (u32)0x40013000 )
u16 ReceivedD[6] = {0,0,0,0,0,0};
u16 SendD[6] = {0,0,0,0,0,0};
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
/* RCC system reset(for debug purpose) */
RCC_DeInit(); //时钟控制寄存器全部恢复默认值
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON); //外部高速时钟源开启(8M晶振)
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部时钟就绪
if(HSEStartUpStatus == SUCCESS) //如果时钟启动成功
{
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1); //定义AHB设备时钟为系统时钟1分频
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1); //定义APB2设备时钟为HCLK时钟1分频
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2); //定义APB1设备时钟为HCLK时钟2分频
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2); //设定内部FLASH的的延时周期为2周期
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能FLASH预存取缓冲区
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟为外部高速时钟的9倍频,8MHz * 9 = 72 MHz
/* Enable PLL */
RCC_PLLCmd(ENABLE); //使能PLL时钟
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟设置完成准备就绪
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //使用PLL时钟作为系统时钟源
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08) //返回系统所用时钟源确认为外部高速晶振,8M晶振。
{
}
}
/* 设备时钟控制 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能由APB2时钟控制的PB端口
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);
/* 设备时钟控制 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能由APB2时钟控制的PA端?
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //使能SPI1
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
} //使能由APB1时钟控制的TIM2、TIM3端口
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*配置LED对应位IO口*/
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7; //选择IO端口的第6和第7位
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //时钟速度为50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //端口模式为输入方?
GPIO_Init(GPIOB, &GPIO_InitStructure); //用以上几个参数初始化PC口
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1; //选择IO端口的第6和第7位
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //时钟速度为50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //端口模式为输入方式?
GPIO_Init(GPIOA, &GPIO_InitStructure); //用以上几个参数初始化PC口
/* 配置SPI1引脚配置: SCK, MISO and MOSI ---------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //IO端口第6位
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //端口模式为推免复用输出方式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //用以上几个参数初始化PA口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7; //IO端口的第4位
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //端口模式为输入方?
GPIO_Init(GPIOA, &GPIO_InitStructure); //用以上几个参数初始化PA口
//GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);
//GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures NVIC.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 选择中断分组 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择中断分组2(主优先级2位,从优先级2位)
/* 配置TIM4中断线 */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //选择定时器4中断线
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //用以上参数初始化TIM4
/* 配置TIM5中断线 */
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //选择定时器4中断线
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //主优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //用以上参数初始化TIM5
/*配置SPI1通接收中断*/
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn; //SPI1接收中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //主优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //用以上参数初始化TIM5
/*配置DAM中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; //DMA通道2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //主优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //用以上参数初始化TIM5
/*配置DAM中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; //DMA通道3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //主优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure); //用以上参数初始化TIM5
}
/*******************************************************************************
* Function Name : TIM_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
/* TIM4 configuration */
TIM_DeInit(TIM4);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //设置定时器重载值,计算时应加1
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; //无分频,计算时应加1
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分割,用于滤波器
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //选择向上计数模式
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重载次数计数器,计数到0便产生中断事件
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //以上参数初始化TIM4
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //以上参数初始化TIM8
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //编码器接口初始化
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6; //6
TIM_ICInit(TIM4, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
//Reset counter
TIM4->CNT = 0; //0
TIM_Cmd(TIM4, ENABLE); //使能TIM4
TIM_EncoderInterfaceConfig(TIM5, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //编码器接口初始化
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6; //6
TIM_ICInit(TIM5, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(TIM5, TIM_FLAG_Update);
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
//Reset counter
TIM5->CNT = 0; //0
TIM_Cmd(TIM5, ENABLE); //使能TIM5
TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除更新事件标志位(防止启动便中断)
/* 开中断 */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //打开重载更新中断
TIM_ClearFlag(TIM5, TIM_FLAG_Update); //清除更新事件标志位(防止启动便中断)
/* 开中断 */
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); //打开重载更新中断
}
/*******************************************************************************
* Function Name : SPI_Configuration
* Description : Configures the SPI.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 Config -------------------------------------------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置为双向双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; //从模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //16位数据格式
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //SCK在空闲时为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //在SCK时钟的第一个边沿接收数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; //NSS硬件控制模式
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //总线时钟8分频为SPI时钟,72/8=9
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //传输数据低位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC7校验
SPI_Init(SPI1, &SPI_InitStructure); //用以上参数初始化SPI1
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE); //打开SPI1
//SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE); //使能SPI1接收中断
//SPI_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE); //清除中断标志位
}
/*******************************************************************************
2 * Function Name : SPI1_DMA_Configuration
3 * Description : ??SPI1_RX?DMA??2,SPI1_TX?DMA??3
4 * Input : None
5 * Output : None
6 * Return : None
7 * Attention :
8 *******************************************************************************/
void SPI1_DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = SPI1_DR_Addr;
// DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SRC_Buffer;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ReceivedD;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = buffersize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址允许后移
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure); //不设置为内存到内存传输
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); //开启接收完成中断
/* Enable SPI1 DMA RX request */
//SPI1->CR2 |= 1<<0; //接收缓冲区DMA使能
DMA1_Channel2->CCR |= 1 << 0 ; //开启DMA通道2
DMA_Cmd(DMA1_Channel2, ENABLE);
CurrdataCounter=DMA_GetCurrDataCounter(DMA1_Channel2);
/* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
DMA_DeInit(DMA1_Channel3);
//DMA_InitStructure.DMA_PeripheralBaseAddr = SPI1_DR_Addr; //SPI地址(0x40013000)
DMA_InitStructure.DMA_PeripheralBaseAddr = SPI1_DR_Addr;
// DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer; //?? SRAM ????(???)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendD;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = buffersize; //?? SPI1数据宽度
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); //开启发送完成中断
//DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE); //开启发送错误中断
/* Enable SPI1 DMA TX request */
//SPI1->CR2 |= 1<<1; //发送缓冲区DMA使能
DMA1_Channel3->CCR |= 1 << 0 ; //开启DMA通道3
DMA_Cmd(DMA1_Channel3, ENABLE); //使能DMA
}
/*******************************************************************************
* Function Name : TIM4_IRQHandler
* Description : TIM4 interrupt.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
if(TIM4->CR1 & 0x0010)
CNT1_High16 --;
else
CNT1_High16++;
}
}
/*******************************************************************************
* Function Name : TIM5_IRQHandler
* Description : TIM5 interrupt.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM5_IRQHandler(void)
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
if(TIM5->CR1 & 0x0010)
CNT2_High16 --;
else
CNT2_High16 ++;
}
}
/*******************************************************************************
* Function Name : SPI1_IRQnHandler
* Description : SPI1 interrupt.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI1_IRQnHandler(void)
{
if( SPI_I2S_GetITStatus( SPI1, SPI_I2S_IT_RXNE ) == RESET ) //接收数据
{
ReceivedD[spicount] = SPI_I2S_ReceiveData(SPI1);
spicount++;
}
if( spicount >= 6 )
{
spicount = 0;
}
//SPI_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);
}
/*******************************************************************************
* Function Name : DMA1_Channel2_IRQn
* Description : DMA1 interrupt.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel2_IRQnHandler(void)
{
/*u8 i=0;
for(i=0;i<6;i++)
{
SPI_I2S_SendData(SPI1,SendD);
}*/
DMA_ClearITPendingBit(DMA1_IT_TC2); /*清除DMA全局中断挂起标志*/
}
/*******************************************************************************
* Function Name : DMA1_Channel2_IRQn
* Description : DMA1 interrupt.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel3_IRQnHandler(void)
{
/* u8 i=0;
for(i=0;i<6;i++)
{
ReceivedD = SPI_I2S_ReceiveData(SPI1);
}*/
DMA_ClearITPendingBit(DMA1_IT_TC3); /*清除DMA全局中断挂起标志*/
}
|
|