在学习使用定时器TIM3触发DMA将数据从memory向GPIOC发送数据,程序调试时发现DMA的标志TEIF为1,导致DMA数据传输中断,而此时定时器工作仍旧正常。
看了文档中有关DMA的错误管理一节,对于TEIF的说明为:
Transfer error: the transfer error interrupt flag (TEIFx) is set when:
- A bus error occurs during a DMA read or a write access
- A write access is requested by software on a memory address register in Double buffer mode whereas the stream is enabled and the current target memory is the one impacted by the writing into the memory address register
可在我的程序里,并没有使用double buffer;程序除了使用TIM3定时0.5秒执行端口翻转以外,没有其它任何操作,问题会是出在哪里呢?
贴出我的代码,请大家帮忙找找问题吧:
/* Private define ------------------------------------------------------------*/
#define BUFFER_SIZE 32
/* GPIOC DMA Stream definitions */
#define GPIOC_DMA_ADDRESS 0x40020814 //GPIOC_ODR
/* Private variables ---------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
const uint32_t SRC_Const_Buffer[BUFFER_SIZE]= {
0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Configure PC.0~PC.15 pins as Output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7
| GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11
| GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// Initialize LEDs and LCD available on STM322xG-EVAL board
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
// Turn on LEDs available on STM322xG-EVAL
STM_EVAL_LEDOn(LED2);
/* TIM Configuration */
TIM3_Config();
DMA_Config_1();
while(DMA_GetFlagStatus(DMA1_Stream2, DMA_IT_TCIF2) != RESET){};
/* Infinite loop */
while(1)
{
}
}
/**
* @brief Configure the DMA1_Stream2.
* @param None
* @retval None
*/
void DMA_Config_1(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* DMA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);
DMA_DeInit(DMA1_Stream2); //使用TIM3_UP来触发DMA,采用DMA1_Stream2,使用DMA_Channel_5
while (DMA_GetCmdStatus(DMA1_Stream2) != DISABLE)
{
}
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(GPIOC_DMA_ADDRESS) ; //直接将数据输出到GPIOC的GPIOC_ODR寄存器
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)SRC_Const_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE*2;
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_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream2, &DMA_InitStructure);
/* DMA enable*/
DMA_Cmd(DMA1_Stream2, ENABLE);
}
/**
* @brief TIM3初始化配置,用于计数器模式,0.5秒触发一次中断和DMA传输
* @param None
* @retval None
*/
void TIM3_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t PrescalerValue = 0;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Enable the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Compute the prescaler value */
PrescalerValue = (uint16_t) (SystemCoreClock / 6000000) - 1; //得到2MHz
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //配置TIM3,每0.5s数据溢出一次
/* Prescaler configuration */
TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);
/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //打开中断
/* TIM Trigger DMA request enable */
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE); //允许触发DMA请求
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
uint16_t TIM3Counter=0;
/**
* @brief TIM3中断服务程序,翻转LED2
* @param None
* @retval None
*/
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM3Counter++;
if(TIM3Counter>=1000)
{
TIM3Counter=0;
STM_EVAL_LEDToggle(LED2);
}
}
} |
|