能否帮我看看我这段串口+DMA代码

2019-10-15 05:49发布

我需要用STM32F103C8作为下位机,用串口接收以串口触摸屏为上位机的触摸数据,该触摸屏因为支持5个触点,串口数据长度是46个字节,现在我找一块STM32F429IG的开发板作为上位机,每10ms发送48个字节,来测试STM32F103C8采用串口空闲中断+DMA能否经得起这样的考验,按照波特率为115200,理论上它应该是能够经受得住,但实际上遇到问题。
具体测试思路:
上位机我用定时器每隔10ms发送从0x90至0xbf这48个字节,下位机配置了USART1与DMA,DMA缓存设为128b,在串口的空闲中断读取DMA的缓存,然后用for循环来比对缓存去的前48个字节来判断接收是否完整,然后再将缓存区的前48个字节重置0,为了避免会有误判。

测试发现下位机第一次接收到48个字节,都是完整的,之后则只接受了1个字节,到现在也没找到问题所在,希望帮忙看看这个问题。另外我用电脑去接收10秒的上位机发出的数据,都是没问题的,所以我怀疑问题是在下位机的代码上。

下位机代码如下:
串口配置,USART1 用于接收上位机数据,USART2用于打印信息
[mw_shl_code=c,true]
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
USART_DeInit(USART1);
USART_DeInit(USART2);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

USART_InitStructure.USART_BaudRate = bound;
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_Init(USART1, &USART_InitStructure);

USART_InitStructure.USART_BaudRate = bound;
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_Tx;
USART_Init(USART2, &USART_InitStructure);
#if EN_USART1_RX

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

//USART_ITConfig(USART1, USART_IT_TC, DISABLE);
//USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
#endif
//USART_Cmd(USART1, ENABLE);
}

void USART1_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
i = USART1->SR;
i = USART1->DR;
DMA_Cmd(DMA1_Channel5, DISABLE);
DATA_LEN = UART_BUFFER_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5);
printf("DATA_LEN:%d. ", DATA_LEN);
#if 1
if (DATA_LEN > 0)
{
for (i = 0; i < 48; i++)
{
printf("%x ", USART1_RECEIVE_DATA);
USART1_RECEIVE_DATA = 0;
}
}
#endif
DMA_SetCurrDataCounter(DMA1_Channel5, UART_BUFFER_SIZE);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
}
[/mw_shl_code]

DMA配置
[mw_shl_code=c,true]
void MYDMA_Config(DMA_Channel_TypeDef *DMA_CHx, u32 cpar, u32 cmar, u32 dma_dir, u32 dma_mode, u8 *irqChannel, u16 cndtr)
{
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA_CHx);
    DMA1_MEM_LEN = cndtr;
    DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;
    DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
    DMA_InitStructure.DMA_DIR = dma_dir;
    DMA_InitStructure.DMA_BufferSize = cndtr;
    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;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA_CHx, &DMA_InitStructure);
    //DMA_ITConfig(DMA_CHx, DMA_IT_TC, ENABLE);
    //DMA_ITConfig(DMA_CHx, DMA_IT_TE, ENABLE);

        if (irqChannel != NULL)
                NVIC_IRQChannel_ENABLE(irqChannel, 2, 0);
}
[/mw_shl_code]

main函数
[mw_shl_code=c,true]
extern u8 USART1_RECEIVE_DATA[UART_BUFFER_SIZE];

int main(void)
{
    delay_init();
    NVIC_Configuration();
    uart_init(115200);
        /*
    irqChannel = DMA1_Channel4_IRQn;
    MYDMA_Config(DMA1_Channel4, (u32)&USART1->DR, (u32)USART1_SEND_DATA, DMA_DIR_PeripheralDST, DMA_Mode_Circular, NULL, UART_BUFFER_SIZE);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(DMA1_Channel4, DISABLE);
        */
    irqChannel = DMA1_Channel5_IRQn;
    MYDMA_Config(DMA1_Channel5, (u32)&USART1->DR, (u32)USART1_RECEIVE_DATA, DMA_DIR_PeripheralSRC, DMA_Mode_Normal, NULL, UART_BUFFER_SIZE);
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(DMA1_Channel5, ENABLE);
    USART_Cmd(USART1, ENABLE);
        USART_Cmd(USART2, ENABLE);
    while (1)
    {
    }
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
正点原子
1楼-- · 2019-10-15 10:55
帮顶、
apple5555
2楼-- · 2019-10-15 13:58
按我的理解,它只有接收完48个字节后,才会报空闲中断,但实际上是串口接收到1个字节就报了空闲中断,很不理解,为什么RESET后的第一次接收能把48个字节全部接收完,后面就不停地报空闲中断?各位看官你们都没有遇到这种情况吗?还是说我买了个假的STM32F103C8开发板?

一周热门 更多>