我是新手。我在STM32F1中断UART中断时遇到问题, 我有2个数据x = ADC1,y = ADC2,我使用移位来减少数字发送字节。在我发送大约4000 -6000 buff之后,我丢失了1-2个字节,其他任何人都解决了我的问题。
// configuration UART interrupt
void USART_Configuration(unsigned int BaudRate)
{
USART_InitStructure.USART_BaudRate = BaudRate;
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_Init(USART1, &USART_InitStructure);
/* Enable USART1 */
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable USARTz Receive and Transmit interrupts */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
// configuaration ADC DMA
void ADC_Configuration(void)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* DMA Configure */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &ADCValue; // address of
array data
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &ADC1->DR;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
so phan
tu cua
ADCValue 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;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* DMA1_Stream0 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC Common Init */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2; //so kenh ADC chuyen doi
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
/* Enable ADC DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while (ADC_GetResetCalibrationStatus(ADC1))
;
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1))
;
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
// configuration timer 500hz
void TIM2base_Configuration(void)
{
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 360 - 1; // 36MHz/360 = 100khz
TIM_TimeBaseStructure.TIM_Period = 200 - 1; // 1khz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOB, GPIO_Pin_1);
x = ADCValue[0];
y = ADCValue[1];
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
}
// Send interrupt function
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
USB_Buffer[0] = '@';
USB_Buffer[1] = '1'; // unsigned char
USB_Buffer[2] = '2';
USB_Buffer[3] = '3'; // unsigned char
USB_Buffer[4] = '4';
USART_SendData(USART1, USB_Buffer[i]);
i++;
if (i == 5)
{
i = 0;
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}
答案 0 :(得分:2)
您可以提早停用USART。它具有FIFO缓冲区,因此您需要遵循"启用&禁用" RM中的主题。 (通常是TC - 发送完成位和中断)。 TXE标志仅表示输入寄存器为空,但不表示传输结束。