历史上的今天
今天是:2024年10月12日(星期六)
2019年10月12日 | 【stm32f103】USART RX实现(寄存器版)
2019-10-12 来源:eefocus
本讲主要实现usart RX的实现,主要分几部分的应用
1.USART 1 RX polling的实现
2.USART1 RX DMA的实现
3.USART1 RX DMA中断的实现
4.配合着TIMER进行RX DMA中断实现实现(用途很大)
本文章不在对寄存器贴图,直接上代码以及运行图,有兴趣的可以去调试下看看寄存器,以下历程都必须调用Init函数,Init函数源码
void USART1_Init()
{
/* 1. ENABLE USART1 GPIOA CLOCK */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
/* 2. ENABLE USART1 IN APB2 BUS CLOCK */
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
/* 3. CONFIG GPIOA PA9 AF MODE */
GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
GPIOA->CRH |= GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1;
GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_CNF10_1;
/* 4. CONFIG USART1 BAUD RATE 115200 */
USART1->BRR |= 0x271;
/* 5. ENBALE TRANSPORT AND ENABLE USART1 */
USART1->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
}
例1:USART1 RX Polling实现
代码:
void USART1_RX_Polling()
{
int index = 0;
while(1)
{
if((USART1->SR & USART_SR_RXNE) != 0)
{
if(index > 50)
break;
buffer[index++] = USART1->DR;
}
}
printf("receive :%s",buffer);
}
运行效果图,直到收到index >50,会整个打印出来

例2:USART1 RX DMA的实现,源码:
void USART1_RX_DMA()
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAR;
/* 6. CONFIG DMA */
DMA1_Channel5->CMAR = (uint32_t)buffer;
DMA1_Channel5->CPAR = (uint32_t)&USART1->DR;
DMA1_Channel5->CNDTR = 20;
DMA1_Channel5->CCR |= DMA_CCR5_PL | DMA_CCR5_MINC | DMA_CCR5_EN;
while(DMA1_Channel5->CNDTR != 0);
printf("RX :%sn",buffer);
}
运行效果图,DMA搬运20个数据,等待搬运完成,就会打印出来
例3:USART1 RX DMA中断的实现
程序源码:
void DMA1_Channel5_IRQHandler(void)
{
TIM2->EGR = TIM_EGR_UG;
TIM2->SR &= ~TIM_SR_UIF;
NVIC_ClearPendingIRQ(TIM2_IRQn);
if (DMA1->ISR & DMA_ISR_HTIF5)
{
DMA1->IFCR = DMA_IFCR_CHTIF5;
printf("HTIF: %dn", DMA1_Channel5->CNDTR);
}
if (DMA1->ISR & DMA_ISR_TCIF5)
{
DMA1->IFCR = DMA_IFCR_CTCIF5;
printf("TCIF: %dn", DMA1_Channel5->CNDTR);
}
}
void USART1_RX_DMA_IRPT()
{
NVIC_SetPriorityGrouping(4);
NVIC_SetPriority(DMA1_Channel5_IRQn, 1);
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAR;
/* 6. CONFIG DMA */
DMA1_Channel5->CMAR = (uint32_t)buffer;
DMA1_Channel5->CPAR = (uint32_t)&USART1->DR;
DMA1_Channel5->CNDTR = 20;
DMA1_Channel5->CCR |= DMA_CCR5_PL | DMA_CCR5_MINC | DMA_CCR5_EN | DMA_CCR5_HTIE | DMA_CCR5_TCIE;
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
while(1);
}
运行图,从串口发送数据,不光发送多少个,发送10个时候,会触发发送一半中断,发送到20个的时候,会触发发送完成中断

例4:配合着TIMER进行RX DMA中断实现实现
源码:
void TIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_SR_UIF;
printf("timeout! CNDTR=%dn", DMA1_Channel5->CNDTR);
}
void Time2_Enable(int arr,int psc)
{
RCC->APB1ENR = RCC_APB1ENR_TIM2EN; // 72M clock
TIM2->ARR = arr;
TIM2->PSC = psc;
TIM2->EGR = TIM_EGR_UG;
TIM2->CR1 = TIM_CR1_URS;
TIM2->DIER = TIM_DIER_UIE;
TIM2->CR1 |= TIM_CR1_CEN;
NVIC_SetPriority(TIM2_IRQn, 1);
NVIC_EnableIRQ(TIM2_IRQn);
}
void DMA1_Channel5_IRQHandler(void)
{
TIM2->EGR = TIM_EGR_UG;
TIM2->SR &= ~TIM_SR_UIF;
NVIC_ClearPendingIRQ(TIM2_IRQn);
if (DMA1->ISR & DMA_ISR_HTIF5)
{
DMA1->IFCR = DMA_IFCR_CHTIF5;
printf("HTIF: %dn", DMA1_Channel5->CNDTR);
}
if (DMA1->ISR & DMA_ISR_TCIF5)
{
DMA1->IFCR = DMA_IFCR_CTCIF5;
printf("TCIF: %dn", DMA1_Channel5->CNDTR);
}
}
void USART1_RX_DMA_IRPT()
{
NVIC_SetPriorityGrouping(4);
NVIC_SetPriority(DMA1_Channel5_IRQn, 1);
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->CR3 |= USART_CR3_DMAR;
/* 6. CONFIG DMA */
DMA1_Channel5->CMAR = (uint32_t)buffer;
DMA1_Channel5->CPAR = (uint32_t)&USART1->DR;
DMA1_Channel5->CNDTR = 20;
DMA1_Channel5->CCR |= DMA_CCR5_PL | DMA_CCR5_MINC | DMA_CCR5_EN | DMA_CCR5_HTIE | DMA_CCR5_TCIE;
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
while(1);
}
运行效果图,timer每2S触发一次中断,打印DMA还需要传输多少数据才能完成,知道串口发送完20byte数据
史海拾趣
|
有青岛各高校的同学吗?海大、山科、青大、青科、理工、农大。。。。 本帖最后由 paulhyde 于 2014-9-15 09:41 编辑 论坛上有青岛高校的吗?大家报个名,相互交流下,谈谈09国赛的准备情况,有什么看法,有什么疑惑,大家都讨论下! 路过也要吱一声。 … 查看全部问答> |
|
我的硬件平台: cpu arm9200, 2m 现存,外扩的1355 lcd 控制器, 触摸屏 软件: linux 2.4.27 + minigui 1.3 我启动了minigui的应用程序,这个界面上有按钮和文字,当我点击文字的时候,发现文字会变模糊,敲击越多越明显,这是怎么回事啊,是驱 ...… 查看全部问答> |
|
不做电子了,手头上有不少芯片以及电子相关的料件,整理了部分: 1. AD623BR SOP8 数量25 价格10/PCS 2.CS4345 10-pin, 24-Bit, 192 kHz Stereo D/A Converter 数量2209 价格1/PCS 3.UTC 78L05L SOP8数量20 整出价格10 4.ON 78L05A SOP8数量180 ...… 查看全部问答> |
|
富士的FRAM(铁电存储器)具有像E2PROM一样的非易失性,在系统断电的情况下,可以自动保存数据,用于工业现场或者一些需要记忆工作状态的情况。尤其是具有串行接口(I2C,SPI)和并行接口,还据高速和并行数据传送的时候省电的功能,这给我们的应用 ...… 查看全部问答> |




