【stm32f103】USART TX发送实现(寄存器版)

发布者:RadiantSerenity最新更新时间:2019-01-31 来源: eefocus关键字:stm32f103  USART  TX发送 手机看文章 扫描二维码
随时随地手机看文章

本讲主要实现usart TX的实现,主要分几部分的应用


1.USART 1 Tx polling的实现(附带printf的实现)


2.USART1 Tx DMA的实现


3.USART1 TX DMA中断的实现


话不多说,开始


一.硬件原理图

USART1在APB2总线上

二.寄存器图


寄存器可以参考  参考手册,在这里不做详细讨论


三.具体实现

1.      USART 1 Tx polling的实现(附带printf的实现)

1)  编程步骤:


->使能PA9的时钟


->使能USART1的时钟


->配置PA9为推挽复用输出


->配置USART1的波特率为115200(因为USART1在APB2上,计算方法为APB2 clock/波特率)


->使能USART1和TX和USART1


->Polling方式往USART1的DR寄存器填数据


->printf需要重定向fputc


2)  程序调试


->程序调用


USART1_Init();

USART1_TX_Polling(100);

->使能PA9,USART1的时钟


/* 1.ENABLE USART1 GPIOA CLOCK */

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

/* 2. ENABLE USART1 IN APB2 BUS CLOCK */

RCC->APB2ENR |=RCC_APB2ENR_USART1EN;


->配置PA9为推挽复用输出


/* 3.CONFIG GPIOA PA9 AF MODE */

GPIOA->CRH &= ~(GPIO_CRH_MODE9 |GPIO_CRH_CNF9);

GPIOA->CRH |=GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1;

此处需要注意一个特别重要的细节:因为CRH默认的value是:

所以如果没有清除到bit4-bit7,直接进行或运算就会造成错误,成为开漏模式,CRL寄存器同样道理,正常运行如图:


->配置波特率为115200



USART1->BRR |= 0x271;

运行效果图


->使能USART1和USART1 TX



USART1->CR1 |= USART_CR1_UE | USART_CR1_TE |USART_CR1_RE;

-> Polling方式往USART1的DR寄存器填数据


voidUSART1_TX_Polling(int loop_cnt)

{

    int index = 0;

    for(;index < loop_cnt;index++)

    {

        while ((USART1->SR &USART_SR_TXE) == 0);

        USART1->DR= 'a';            

    }

    while(1);

}


运行图

->printf fputc重定向


int fputc(int ch, FILE *fp)

{

    if (fp == stdout)

    {

        if (ch == '\n')

        {

            while((USART1->SR & USART_SR_TXE) == 0);

            USART1->DR ='\r';

        }

        while ((USART1->SR &USART_SR_TXE) == 0);

        USART1->DR = ch;

    }

    return ch;

}


2.      USART1 Tx DMA的实现

1)  编程步骤


->使能PA9的时钟


->使能USART1的时钟


->配置PA9为推挽复用输出


->配置USART1的波特率为115200(因为USART1在APB2上,计算方法为APB2 clock/波特率)


->使能USART1和TX和USART1


->设置DMA,请参照DMA文章:


http://blog.csdn.net/xiaoxiaopengbo/article/details/77434744


程序源码


unsigned char buffer[52] = "DMA DATA TEST";

void USART1_TX_DMA()

{

    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    USART1->CR3 |= USART_CR3_DMAT;

    

    /* 6. CONFIG DMA */

    DMA1_Channel4->CMAR = (uint32_t)buffer;

    DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;

    DMA1_Channel4->CNDTR = strlen(buffer);

    DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;

    

    while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);

    DMA1->IFCR = DMA_IFCR_CTCIF4;

    DMA1_Channel4->CCR &= ~DMA_CCR4_EN;

    

    while(1);

}


程序调试图:


3.      USART1 TX DMA中断的实现

1)  编程步骤


->设置USART1


->设置DMA以及NVIC中断


->编写DMA中断函数


2)  程序源码


void USART1_TX_DMA_IRPT()

{

    NVIC_SetPriorityGrouping(4);

    

    NVIC_SetPriority(DMA1_Channel4_IRQn, 1);

    

    

    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    USART1->CR3 |= USART_CR3_DMAT;

    

    /* 6. CONFIG DMA */

    DMA1_Channel4->CMAR = (uint32_t)buffer;

    DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;

    DMA1_Channel4->CNDTR = strlen(buffer);

    DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_TCIE | DMA_CCR5_HTIE | DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;

    NVIC_EnableIRQ(DMA1_Channel4_IRQn);

    

    while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);

    DMA1->IFCR = DMA_IFCR_CTCIF4;

    DMA1_Channel4->CCR &= ~DMA_CCR4_EN;

    

    

    while(1);

}


3)  程序调试

四. 整个程序源码

#include

#include

 

unsigned char buffer[52] = "DMA DATA TEST";

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;

    

}

 

void USART1_TX_Polling(int loop_cnt)

{

    int index = 0;

    for(;index < loop_cnt;index++)

    {

             while ((USART1->SR &USART_SR_TXE) == 0);

             USART1->DR = 'a';            

    }

    while(1);

}

 

void USART1_TX_DMA()

{

    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    USART1->CR3 |= USART_CR3_DMAT;

    

    /* 6. CONFIG DMA */

    DMA1_Channel4->CMAR = (uint32_t)buffer;

    DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;

    DMA1_Channel4->CNDTR = strlen(buffer);

    DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;

    

    while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);

    DMA1->IFCR = DMA_IFCR_CTCIF4;

    DMA1_Channel4->CCR &= ~DMA_CCR4_EN;

    

    while(1);

}

 

void DMA1_Channel4_IRQHandler(void)

{

    

    if (DMA1->ISR & DMA_ISR_HTIF4)

    {

             DMA1->IFCR = DMA_IFCR_CHTIF4;

             //printf("HTIF: %d\n",DMA1_Channel4->CNDTR);

    }

    

    if (DMA1->ISR & DMA_ISR_TCIF4)

    {

             DMA1->IFCR = DMA_IFCR_CTCIF4;

             //printf("TCIF: %d\n",DMA1_Channel4->CNDTR);

    }

}

 

void USART1_TX_DMA_IRPT()

{

    NVIC_SetPriorityGrouping(4);

    

    NVIC_SetPriority(DMA1_Channel4_IRQn, 1);

    

    

    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    USART1->CR3 |= USART_CR3_DMAT;

    

    /* 6. CONFIG DMA */

    DMA1_Channel4->CMAR = (uint32_t)buffer;

    DMA1_Channel4->CPAR =(uint32_t)&USART1->DR;

    DMA1_Channel4->CNDTR = strlen(buffer);

    DMA1_Channel4->CCR |= DMA_CCR4_PL |DMA_CCR4_TCIE | DMA_CCR5_HTIE | DMA_CCR4_DIR | DMA_CCR4_MINC | DMA_CCR4_EN;

    NVIC_EnableIRQ(DMA1_Channel4_IRQn);

    

    while ((DMA1->ISR & DMA_ISR_TCIF4) ==0);

    DMA1->IFCR = DMA_IFCR_CTCIF4;

    DMA1_Channel4->CCR &= ~DMA_CCR4_EN;

    

    

    while(1);

}

 

int fputc(int ch, FILE *fp)

{

    if (fp == stdout)

    {

             if (ch == '\n')

             {

                       while ((USART1->SR& USART_SR_TXE) == 0);

                       USART1->DR = '\r';

             }

             while ((USART1->SR &USART_SR_TXE) == 0);

             USART1->DR = ch;

    }

    return ch;

}

 

 

int main()

{

    USART1_Init();

    

    // USART1_TX_Polling(100);

    // USART1_TX_DMA();

    //USART1_TX_DMA_IRPT();    

    while(1);

    

}


关键字:stm32f103  USART  TX发送 引用地址:【stm32f103】USART TX发送实现(寄存器版)

上一篇:【stm32f103】stm32 外部中断(寄存器版)
下一篇:【stm32f103】SysTick实现延时(寄存器版)

推荐阅读最新更新时间:2024-03-16 16:23

STM32F103ZET XXX.map的可执行映像分析
可执行映像文件的逻辑结构,总共分7大部分: 一、Section Cross References 交叉引用部分 二、Removing Unused input sections from the image.从映像文件中删除输入段中未使用段的统计信息,对应参数-remove 三、Image Symbol Table 映像符号表:域符号映射和全局、局部符号及生成符号映射统计信息,对应参数-symbol 四、Memory Map of the image 印象文件的信息图,对应参数-map,该信息中包含映像文件中的每个加载域、运行域和输入段的大小和地址(工程每个文件的对象obj在存储器中的映射) PS:要生成此文件,需要设置一下,
[单片机]
<font color='red'>STM32F103</font>ZET XXX.map的可执行映像分析
atmega8 例程:USART串口通信
/***************************************************************** * 函数库说明:ATMEGA8 串口通信 * 版本: v1.0 * 说明: 查询发送、中断接收 * ****************************************
[单片机]
STM32 USART DMA发送 中断接收
文件(usart.h): #ifndef _USART__H #define _USART__H #define EMPTY 0xFFFF extern vu32 uart2_transfer_complete; typedef enum { BSP_UART_STOPBITS_1=1, BSP_UART_STOPBITS_2=2 }BSP_UART_StopBits; typedef enum { BSP_UART_PARITY_NO=0, BSP_UART_PARITY_ODD=1, BSP_UART_PARITY_EVEN=2 }BSP_UART_Parity; typedef enu
[单片机]
STM32的USART发送数据时如何使用TXE和TC标志
在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器(下图中阴影部分的TDR),另一个是程序看不到的移位寄存器(下图中阴影部分Transmit Shift Register)。 对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送结束;对照下图,当TDR中的数据传送到移位寄存器后,TXE被设置,此时移位寄存器开始向TX信号线按位传输数据,但因为TDR已经变空,程序可以把下一个要发送的字节(操作USART_DR)写入TDR中,而不必等到移位寄存器中所有位发送结束,所有位发送结束时(送出停止位后)硬件会设置TC标志。 另一方面,在刚刚初始化好USART还没有发送任何数据时,也会
[单片机]
STM32的<font color='red'>USART</font><font color='red'>发送</font>数据时如何使用TXE和TC标志
STM32F103ZET6 启动模式
STM32三种启动模式: STM32三种启动模式对应的存储介质均是芯片内置的,它们是: 1)用户闪存 = 芯片内置的Flash。 2)SRAM = 芯片内置的RAM区,就是内存啦。 3)系统存储器 = 芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。 在每个STM32的芯片上都有两个管脚BOOT0和BOOT1,这两个管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序,见下表: BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。 BOOT1=0 BOOT0=1 从系统存储器启动
[单片机]
基于stm32f103zet6的外部中断学习
一、关于中断中的结构体EXTI_InitTypeDef 原型:uint32_t EXTI_InitTypeDef::EXTI_Line { uint32_t EXTI_Line FunctionalState EXTI_LineCmd EXTIMode_TypeDef EXTI_Mode EXTITrigger_TypeDef EXTI_Trigger }含有4个成员 1、Specifies the EXTI lines to be enabled or disabled. This parameter can be any combination of EXTI_Lines EXTI_Lines的取值可以是下面的数字 #defi
[单片机]
STM32CUBEIDE(7)----USART收发配置
概述 本章STM32CUBEMX配置STM32F103,测试串口发送接收函数。 最近在弄ST和GD的课程,需要样片的可以加群申请:6_15061293。 生成例程 使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板 查看原理图,PA2和PA3设置为开发板的串口。 配置串口。 开启中断。 STM32CUBEIDE配置 若需要打印浮点型,需要勾选下面的选项。 串口重定向 在main.c中,添加头文件,若不添加会出现 identifier FILE is undefined报错。 /* USER CODE BEGIN Includes */ #include stdio.h /
[单片机]
STM32CUBEIDE(7)----<font color='red'>USART</font>收发配置
基于STM32F103的深海远程电机控制系统设计
深海电机控制系统是深海科学考察、地质勘探、生物资源采集、深海打捞等深海作业中的一项关键技术, 使电机在深海的复杂环境中高效、可靠地运行具有重要的意义。目前, 在我国的深海科学考察中,通常采用有刷直流电机作为动力来源, 水下锂电池为其供电。由于锂电池价格昂贵且需要不时的对其进行充电, 严重影响了有效作业时间, 所以, 采用水上供电即远程控制的方式有很大的实际意义。另一方面,有刷直流电机因长时间侵泡在高压油中, 加上深海作业环境的恶劣, 电刷和换相器很容易损坏。而永磁同步电机利用电子换相代替了机械换相, 不但具有直流电机的调速性能, 而且体积小、效率高。永磁同步电机的转子采用永磁体, 所以省去了励磁 电路 , 因而具有更高的功率因
[工业控制]
基于<font color='red'>STM32F103</font>的深海远程电机控制系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved