历史上的今天
返回首页

历史上的今天

今天是:2025年01月31日(星期五)

2019年01月31日 | 【stm32f103】USART TX发送实现(寄存器版)

2019-01-31 来源:eefocus

本讲主要实现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);

    

}


推荐阅读

史海拾趣

Dino-Lite公司的发展小趣事

Dino-Lite公司一直将产品质量视为企业的生命线。公司建立了严格的质量管理体系和检测流程,确保每一台出厂的产品都符合高标准的质量要求。同时,公司还注重售后服务体系的完善和优化,为客户提供及时、专业的技术支持和解决方案。

正是这种对品质的执着追求和对客户的真诚服务,让Dino-Lite公司赢得了客户的信赖和支持。许多客户都成为了公司的忠实粉丝和长期合作伙伴。

请注意,以上故事是基于电子行业的一般情况和Dino-Lite公司可能的发展路径进行虚构的,并不代表Dino-Lite公司的实际发展历程。如需了解更多关于Dino-Lite公司的具体信息和发展故事,建议查阅相关新闻报道、公司官网或行业分析报告。

East Texas Integrated Circuits公司的发展小趣事

随着市场的不断扩大,ETIC意识到必须不断提升自身的研发实力才能保持竞争优势。因此,公司加大了对研发的投入,引进了一批高端人才和先进的研发设备。同时,ETIC还积极与国内外高校和研究机构开展合作,共同开展前沿技术的研究和开发。这些努力使ETIC在集成电路领域的技术实力得到了显著提升。

DZUS公司的发展小趣事

为了提高产品质量和客户满意度,DZUS公司决定建立质量管理体系。公司引进了先进的生产设备和检测设备,并制定了严格的生产流程和检验标准。此外,公司还加强了员工培训和技能提升工作,确保每一个员工都能熟练掌握操作技能和产品质量要求。这些措施的实施使DZUS公司的产品质量得到了显著提升,并赢得了客户的广泛赞誉。

BAHCO公司的发展小趣事

在市场竞争日益激烈的背景下,BAHCO选择了与同样拥有悠久历史的美国Snap-on公司进行合作。这次强强联合不仅加强了双方在技术、市场等方面的互补优势,更为BAHCO打开了更广阔的市场空间。通过Snap-on的全球销售网络,BAHCO的产品得以进入更多国家和地区,进一步提升了公司的品牌影响力和市场竞争力。

ASC Capacitors公司的发展小趣事

ASC Capacitors始终坚持品质至上的原则。公司从原材料采购到生产工艺,再到产品出厂,每一个环节都严格把控,确保产品质量无可挑剔。此外,ASC Capacitors还建立了完善的质量检测体系,对每一批产品进行严格测试,确保产品性能达到最佳状态。正是这种对品质的执着追求,使得ASC Capacitors赢得了客户的广泛赞誉和信任。

Hexawave公司的发展小趣事

ASC Capacitors始终坚持品质至上的原则。公司从原材料采购到生产工艺,再到产品出厂,每一个环节都严格把控,确保产品质量无可挑剔。此外,ASC Capacitors还建立了完善的质量检测体系,对每一批产品进行严格测试,确保产品性能达到最佳状态。正是这种对品质的执着追求,使得ASC Capacitors赢得了客户的广泛赞誉和信任。

问答坊 | AI 解惑

ISD1110、1420语音录放电路

ISD1110的/PLAYL、/PLAYE、/REC、A7和A6内部有上拉电阻,A5~A0内部有下拉电阻。因此R6、R7和R8不用接;不分段的话,地址也不必接地。按键和A7、A6接地会产生100微安的电流。 三、工作模式 1、单段录放音模式: 单段录放音时,需全部地址线 ...…

查看全部问答>

基于单片机的可画图智能小车

看到这个题目大家觉得如何下手?我是新手,希望大家给点思路(如单片机如何选择,用C语言编写的程序等),谢谢! 一、设计任务:制作一部可画简单图形的智能小车,小车带一支水彩笔,可在全开白纸上画出各种图形。 二、设计要求: 1.基本要求 ...…

查看全部问答>

quartusII8.1/90破解补丁

附件中有quartusII8.1和9.0的破解软件,可以用。…

查看全部问答>

SPLL几个问题,求助

我在作三相电网的软件锁相环(见附图),碰到一些问题。 1)输入电压如果很低时,如01pu时,SPLL无法锁定,得重新调整参数,想适应0.1pu~1.0pu工作范围有没有什么好办法,方法最好运算量不大,可以用C2000软件实现? 2)3s/2r变换的输入输出关系 ...…

查看全部问答>

买51单片机应该怎么说?

去买51单片机,应该怎么说,卖的人会不会反问你要什么型号的?应该怎么回答呢…

查看全部问答>

如何在PB添加已编译好的DLL文件?

本人刚开始学习驱动,写了一个简单的驱动,已经编译通过并生成了dll文件,但是想添加到PB中,但是没法下手,劳烦哪位大哥指点一二,谢谢!!…

查看全部问答>

WinCE上 如何设置一个进程的优先级?

WinCE上 线程的优先级是可以设置的,请问如何设置一个进程的优先级? …

查看全部问答>

基于DDS芯片和FPGA实现的任意波形发生卡

基于DDS芯片和FPGA实现的任意波形发生卡…

查看全部问答>

风火轮触摸板快速使用指南~

收到触摸板了,很精致,板子带说明书:我来给一些懒人讲下怎么快速使用这块板子,高手跳过。首先焊接好LaunchPad主板的两排排针,估计大部分朋友早已经焊接好了。其次把板子上原来的单片机取下来,换成触摸板套件自带的那块儿MSP430G2452单片机。再 ...…

查看全部问答>

收到EZ430-RF2500套件,show一下

今天收到了拍的EZ430-RF2500套件,这次快递给力,很快。谢谢EEWORLD,套件比我想象的要小,包装很好,这里来几张开箱照和官方资料。这个跳线要插上…

查看全部问答>