【stm32f103】USART RX实现(寄存器版)

2019-10-12来源: eefocus关键字:stm32f103  USART  RX  寄存器

本讲主要实现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数据


关键字:stm32f103  USART  RX  寄存器 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic476927.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32F1xx使用FIFO实现USART串口发送中断
下一篇:stm32后生成编译文件大小探索之二

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F0 ADC学习
开始时候使用的是stdlib的库,最近发现cube库用的越来越广泛了,遂开始使用cube库来完成ADC的多通道采集实验。ADC 的driver 在STM32F0XX_HAL_DRIVER当中,有stm32f0xx_hal_adc.c文件中,我们可以在stm32f0xx_hal_conf.h中开启 宏定义 ADC 模块。ADC有三种工作模式,polling interruptDMA我这里使用了polling的方式来获取多通道的数据。首先是要声明两个参数设置的结构体ADC_HandleTypeDef             AdcHandle
发表于 2019-10-09
STM32F030 使用内部时钟和外部时钟
p;  /* Wait till PLL is ready */  while((RCC->CR & RCC_CR_PLLRDY) == 0)  {  }   /* Select PLL as system clock source */  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;       /* Wait till PLL is
发表于 2019-10-09
STM32F030F4P6单片机由外部时钟改为内部时钟的步骤
一.看程序运行的时候初始化时钟部分: 二.查看systeminit定义如下: 这就是打开的函数内容这就是使用外部时钟的配置,也就是库函数的默认配置):static void SetSysClock(void){  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;    /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*//* Enable HSE */ //打开外部时钟开关&nbs
发表于 2019-10-09
STM32F030F4P6单片机由外部时钟改为内部时钟的步骤
STM32F4(Flash读保护)
1,目的在实际的产品发布中,如果不对储存在单片机Flash中的程序做一些保护的话,就有可能被一些不法公司,通过仿真器(J-Link,ST-Link等)把Flash中的程序读取回来,得到bin文件或hex文件,然后去山寨产品。所以我们需要对程序进行保护,一种比较简单可靠的方法就是把Flash设置成读保护。2,开发环境1,适用芯片:STM32F4全部芯片2,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.03,IDE:MDK5173,程序源码/**************************************************************** * Function
发表于 2019-10-09
stm32F103 DMA通道
发表于 2019-10-09
stm32F103 DMA通道
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved