传输UART时STM32F1丢失了字节

时间:2017-05-15 07:42:30

标签: c embedded stm32 uart adc

我是新手。我在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);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您可以提早停用USART。它具有FIFO缓冲区,因此您需要遵循"启用&禁用" RM中的主题。 (通常是TC - 发送完成位和中断)。 TXE标志仅表示输入寄存器为空,但不表示传输结束。