stm32uartdma实现未知数据长度接收文档格式.docx
- 文档编号:22931325
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:7
- 大小:17.30KB
stm32uartdma实现未知数据长度接收文档格式.docx
《stm32uartdma实现未知数据长度接收文档格式.docx》由会员分享,可在线阅读,更多相关《stm32uartdma实现未知数据长度接收文档格式.docx(7页珍藏版)》请在冰豆网上搜索。
整体的思路是这样的,一开始设置好DMA接收,可以把缓冲区长度设置为帧最大长度,我们可以把RX连接到定时器的管脚输入端,并且一开始设置输入并且使能引脚下降沿中断,当帧的第一个字节发送时,因为起始位为低电平,空闲时UART为高电平,满足条件,进入中断,禁止中断,并且在中断中开启定时器,该定时器工作在复位模式,上升沿复位,并且设置好定时器输出比较值为超时时间,比如20ms,这样,在传输后面字节时,肯定会有高低电平出现,即便是传输的是0x00,0xFF,虽然UART数据区不变,但是都为1,或都为0,但是因为起始位为低电平,停止位是高电平,所以肯定会有上升沿,定时器会一直复位,输出定时器的计数器一直到达不了输出比较值,当一帧传输结束后,定时在最后一个字节复位后,由于没有数据继续到达,无法复位,则计数器就能计到输出比较值,这时发出中断,在定时器中断中可以计算出接收数据的长度,并且通知外部数据已经接收完毕。
4、功能实现
实现的步骤:
1、硬件连接:
UART的RX线在连接外部的同时,还需要连接到一个定时器的输入端TIMx_CHx,定时器可以为任意定时器,但是CHx,只能为CH1或CH2,具体的需要看STM32的定时器逻辑图,以STM32F101CB为例,我们暂定把UART1的RX在连接RS232的同时,还连接到TIM4_CH2。
2、软件设置
a)IO、中断设置:
在把UART功能口设置好后,还需要设置TIM4_CH2为输入上拉,并且使能该引脚外部中断/**
*@briefConfiguresthedifferentGPIOports.
*@paramNone
*@retval:
None
*/
voidGPIO_Configuration(void)
{
/*ConfigureUSART1_Rxasinputfloating*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&
amp;
GPIO_InitStructure);
/*ConfigureUSART1_Txasalternatepush-pull*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
/*GPIOB.7Configuration:
TIM4Channel2asinputfloatinng*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&
}/**
*@briefConfiguresthesystemEXIT.
*@retvalNone
voidEXTI_Configuration(void)
EXTI_InitTypeDefEXTI_InitStructure;
/*ConnectEXTI8LinetoPB.07pin*/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource7);
/*ConfigureEXTI8line*/
EXTI_InitStructure.EXTI_Line=EXTI_Line7;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&
EXTI_InitStructure);
/*ClearsEXTIlinependingbits.*/
EXTI_ClearITPendingBit(EXTI_Line7);
*@briefConfiguresNVICandVectorTablebaselocation.
voidNVIC_Configuration(void)
NVIC_InitTypeDefNVIC_InitStructure;
/*ConfiguretheNVICPreemptionPriorityBits*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/*SettheVectorTablebaselocationat0x08000000*/
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
/*EnabletheDMA1_Channel_RxInterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&
NVIC_InitStructure);
/*ConfigureDMA1_Channel_Txinterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
/*ConfigureTIM1updateinterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=5;
/*EnableandsetEXTI9_5Interrupttothelowestpriority*/
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=6;
}
把DMA接收的数据缓冲区设置为你认为最大的帧长度,(如果最长不能确定,也可以随便指定一个长度,后面再讲怎么实现)。
b)定时器设置
因为使用的是TIM4_CH2,所以需要配置TIM4,并且配置为复位模式,把超时时间定为20ms,为了方便TIM4时钟定输入为1KHZ
/*
*Thisfunctioniscalledbytimer_init()toperformthenon-genericportion
*oftheinitializationofthetimermodule.
*/
voidtimer_init_non_generic(void)
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
TIM_ICInitTypeDefTIM_ICInitStructure;
/*TIM4configuration----------------------------------------------------*/
TIM_TimeBaseStructure.TIM_Period=65535;
TIM_TimeBaseStructure.TIM_Prescaler=SystemCoreClock/1000000*1000-1;
TIM_TimeBaseStructure.TIM_ClockDivision=0;
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4,&
TIM_TimeBaseStructure);
/*OutputCompareModeconfiguration:
Channel1*/
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse=20;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OC1Init(TIM4,&
TIM_OCInitStructure);
/*TIM4Channel2InputCaptureConfiguration*/
TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter=0;
TIM_ICInit(TIM4,&
TIM_ICInitStructure);
/*TIM4Inputtriggerconfiguration:
ExternalTriggerconnectedtoTI2*/
TIM_SelectInputTrigger(TIM4,TIM_TS_TI2FP2);
/*TIM4configurationinslaveresetmodewherethetimercounteris
re-initialiedinresponsetorisingedgesonaninputcapture(TI2)*/
TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset);
/*TIM4ITCC1enable*/
TIM_ITConfig(TIM4,TIM_IT_CC1,ENABLE);
c)工作过程如下
在串口传输起始位的时候,首先产生外部中断,在外部中断中开启定时器,禁止外部中断,只要串口上一直有数据,定时器肯定会不停的复位,到达不了定时时间,当串口上没有数据的时候,到超时时间后,定时器产生中断,此时可以读出接收的数据长度,然后开启外部中断,进入下一个周期。
4.jpg)总结:
本方法的缺点是程序开始的初始化麻烦些,但是优点是非常明显的,彻底解放了CPU,这样在计算串口超时的时候,就不需要定时器不停的中断,并且串口接收数据使用DMA方式,也不需要CPU参与,只是在接收结束的时候通知CPU取数据,CPU的利用率会更高。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- stm32uartdma 实现 未知 数据 长度 接收