历史上的今天
返回首页

历史上的今天

今天是:2025年08月12日(星期二)

正在发生

2019年08月12日 | STM32-(09):USART库函数方式编程

2019-08-12 来源:eefocus

STM32库函数

STM32库是由ST公司针对STM32提供的函数接口,即API(Application Program Interface),开发者可调用这些函数接口来配置STM32 的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发快速,易于阅读,维护成本低等特点。

当我们调用库的API的时候可以不用挖空心思去了解库底层的寄存器操作,就像当年我们学习C语言的时候,用Printf()函数时只是学习它的使用格式,并没有去研究它的源码实现,如非必要,可以说是老死不相往来。

库是假设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口。

在这里插入图片描述

CMSIS 标准

在这里插入图片描述

因为基于Cortex的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的Cortex微控制器软件的兼容问题,ARM与芯片厂商建立了CMSIS标准(Cortex MicroController Sortware Interface Standard)。

在这里插入图片描述

注:MCU层一般都是ARM开发的,CMSIS都是外设访问层,一般是STM32厂商开发的。

STM32库函数组织

在这里插入图片描述

inc(include):表示头文件
src(source):表示源码
stm32f10x:表示芯片型号
其他等命名规则可查阅 STM32F103xx固件函数库用户手册

下面以同步异步收发器(USART)来大概介绍库函数的应用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面用库函数的方式编写上一篇文章的中的代码

//----------------头文件声明--------------------

#include"stm32f10x_lib.h" //包含所有的头文件

#include

//----------------函数声明--------------------

void Delay_MS(u16 dly);

void RCC_Configuration(void);

void GPIO_Configuration(void);

void USART_Configuration(u32 BaudRate);


#define PA1 GPIOA->BSRR

#define PA0 GPIOA->BRR


#define GPIOA_ODR_A  (GPIOA_BASE+0x0C)

#define GPIOA_IDR_A  (GPIOA_BASE+0x08)

#define GPIOB_ODR_A  (GPIOB_BASE+0x0C)

#define GPIOB_IDR_A  (GPIOB_BASE+0x08)

#define GPIOC_ODR_A  (GPIOC_BASE+0x0C)

#define GPIOC_IDR_A  (GPIOC_BASE+0x08)

#define GPIOD_ODR_A  (GPIOD_BASE+0x0C)

#define GPIOD_IDR_A  (GPIOD_BASE+0x08)

#define GPIOE_ODR_A  (GPIOE_BASE+0x0C)

#define GPIOE_IDR_A  (GPIOE_BASE+0x08)


#define BitBand(Addr,BitNum)    *((volatile unsigned long *)((Addr&0xF0000000)+0x2000000+((Addr&0xfffff)<<5)+(BitNum<<2)))


#define PAout(n)   BitBand(GPIOA_ODR_A,n)

#define PAin(n)    BitBand(GPIOA_IDR_A,n)

#define PBout(n)   BitBand(GPIOB_ODR_A,n)

#define PBin(n)    BitBand(GPIOB_IDR_A,n)

#define PCout(n)   BitBand(GPIOC_ODR_A,n)

#define PCin(n)    BitBand(GPIOC_IDR_A,n)

#define PDout(n)   BitBand(GPIOD_ODR_A,n)

#define PDin(n)    BitBand(GPIOD_IDR_A,n)

#define PEout(n)   BitBand(GPIOE_ODR_A,n)

#define PEin(n)    BitBand(GPIOE_IDR_A,n)


/*******************************************************************************

* Function Name  : main

* Description    : Main program.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/ 

int main(void)

{

u8 i,data;


RCC_Configuration();

GPIO_Configuration();

USART_Configuration(19600);


data='A';

for(i=0;i<30;i++)

{

USART_SendData(USART1, data); //通过外设USARTx发送单个数据(参数1:哪个串口,参数2:数据)

data++;

//检查指定的USART 标志位设置与否(这里参数2选择“发送完成标志位”)

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET) ;  

//SET表示1,RESET表示0,当等于0,会一直停在这里

}

}

/*******************************************************************************

* Function Name  : Delay_Ms

* Description    : delay 1 ms.

* Input          : dly (ms)

* Output         : None

* Return         : None

*******************************************************************************/

void Delay_MS(u16 dly)

{

u16 i,j;

for(i=0;i for(j=1000;j>0;j--);

}


/*******************************************************************************

* Function Name  : RCC_Configuration

* Description    : Configures the different system clocks.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void RCC_Configuration(void)

{

//----------使用外部RC晶振-----------

RCC_DeInit(); //初始化为缺省值

RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟 

while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪

//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer

//FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state

RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK

RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 =  HCLK

RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ

RCC_PLLCmd(ENABLE); //Enable PLLCLK


while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock

while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source

//---------打开相应外设时钟--------------------

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外设的GPIOA的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能APB2外设的GPIOC的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);  

 

}


/*******************************************************************************

* Function Name  : GPIO_Configuration

* Description    : 初始化GPIO外设

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/ 

void GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;


  /* Configure USARTx_Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* Configure USARTx_Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


}


void USART_Configuration(u32 BaudRate)

{

USART_InitTypeDef USART_InitStructure; //声明一个结构体 

USART_InitStructure.USART_BaudRate = BaudRate; //波特率

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长8位

USART_InitStructure.USART_StopBits = USART_StopBits_1; //1个停止位 

USART_InitStructure.USART_Parity = USART_Parity_No; //没有停止位 

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //不需要硬件控制流

USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;  //TX/RX、发送接收使能

USART_Init(USART1, &USART_InitStructure);

USART_Cmd(USART1, ENABLE);

}



//stm32f10x_usart.h

/* Exported types ------------------------------------------------------------*/

/* USART Init Structure definition */

typedef struct

{

  u32 USART_BaudRate; // 设置了USART传输的波特率 ;

  u16 USART_WordLength; // 提示了在一个帧中传输或者接收到的数据位数 ;

  u16 USART_StopBits; // 定义了发送的停止位数目 ;

  u16 USART_Parity;   // 定义了奇偶模式 ;

  u16 USART_Mode;   // 指定了使能或者失能发送和接收模式 ;

  u16 USART_HardwareFlowControl;  // 指定了硬件流控制模式使能还是失能 ;

} USART_InitTypeDef;


推荐阅读

史海拾趣

Elytone Electronics Co Ltd公司的发展小趣事

进入XXXX年代,随着电子技术的飞速发展,Elytone公司意识到技术创新是企业持续发展的关键。公司投入大量资金引进先进设备和研发人才,成功开发出一系列具有竞争力的电子产品。这些产品在市场上获得了良好的口碑,为公司的快速发展奠定了坚实基础。

Agere System(LSI Logic)公司的发展小趣事

随着公司规模的扩大,Elytone公司意识到品质管理对于企业发展至关重要。他们引入了先进的质量管理体系,加强了对原材料采购、生产过程和售后服务的监控。通过持续改进和优化,公司的产品质量得到了显著提升,赢得了客户的广泛认可。

DPA Components International公司的发展小趣事

作为一家具有社会责任感的企业,DPA Components International公司始终关注社会公益事业。公司积极参与各种公益活动,如扶贫助学、环保行动等,为社会做出了积极贡献。此外,DPA还关注行业发展和社会进步,积极参与行业交流和合作,推动整个电子行业的健康发展。通过担当社会责任,DPA不仅提升了企业的社会形象,也为社会的进步和发展做出了积极贡献。

安纳森(AnaSem)公司的发展小趣事

在电子行业中,产业链上下游之间的合作至关重要。安纳森深知这一点,因此始终致力于与产业链上下游的企业建立紧密的合作关系。通过与晶圆厂家、IC设计企业等合作伙伴的深入合作,安纳森不仅获得了稳定的原材料供应和技术支持,还共同研发出了多款具有市场竞争力的新产品。这种合作共赢的发展模式不仅提升了整个产业链的竞争力,也为安纳森的长远发展注入了源源不断的动力。

这五个故事只是安纳森在电子行业发展中可能经历的一部分,实际上,其发展历程可能更加复杂和丰富。无论如何,安纳森凭借其创新的技术、全球化的视野、环保的理念、对侵权问题的积极应对以及产业链合作的深化,已经成为了电子行业中一颗璀璨的明星。

CCS[Custom Computer Services]公司的发展小趣事

在电子行业中,产品质量和客户服务是企业生存和发展的关键。CCS公司始终坚持质量第一的原则,建立了严格的质量管理体系和客户服务体系。公司从原材料采购到产品生产、销售等各个环节都进行严格的质量控制,确保产品的质量和性能达到客户的期望。同时,CCS公司还提供了全方位的客户服务,包括售前咨询、售后服务和技术支持等,为客户提供了全方位的支持和帮助。

登丰微(GSTEK)公司的发展小趣事

歌普电子科技有限公司以自有品牌(GEPU歌普)创立于2006年,公司最初在台湾设立,随后逐步扩展至江苏和东莞,形成了跨区域的研发、生产和销售网络。公司自创立之初便专注于各式线对板连接器、板对板连接器、网络连接器等产品的研发与设计。通过不断的技术积累和市场需求洞察,歌普逐渐在连接器领域建立了自己的市场地位。

问答坊 | AI 解惑

DSP和FPGA怎么连接呢?

大家讨论一下,DSP和FPGA进行数据交流的时候,如何连接较好呢…

查看全部问答>

发现个博客挺不错的:CAN总线学习心得

把常见的问题都罗列了 链接:https://home.eeworld.com.cn/my/space.php?do=blog&uid=80086&id=28343…

查看全部问答>

嵌入式USB主机,有经验的开发者给点意见,谢!

我最近查了些资料 现在把我的需求在整理一下:我想做一个嵌入式USB主机(强调是主机端host,不是USB设备),这是第一次做一个完整的系统,不知从何入手,有这样几个问题,首先是主控芯片,如果单片机可以,用哪种?另外电源模块用什么方案比较好? ...…

查看全部问答>

ARM板开发触摸屏程序,出现飘屏!急求解决办法!

我用ARM板测试一个触摸屏程序,偶尔出现飘屏! 源码如下: #include \"def1.h\" #include \"2440addr.h\" #include \"2440lib.h\" #include \"config.h\" #define REQCNT 30 #define ADCPRS 9        //YH 0627 #define LO ...…

查看全部问答>

嵌入式学习

各位大虾,小弟偏软件出身,现做wince下驱动程序开发,不知道要学习那些硬件知识(软件方面没什么问题),望有经验的前辈给介绍介绍,请推荐一些相关书籍! 下面是我的一些想法: 看 单片机(以前学过51单片机,不过没打算做底层开发,也就没怎么 ...…

查看全部问答>

亚嵌《嵌入式linux系统暑期强化班》全面启动

亚嵌《嵌入式linux系统暑期强化班》全面启动 亚嵌-10年嵌入式技术研究 ???????? 6年嵌入式技术专业教学??亚嵌强调技术的严肃性、并向所有尊重技术、热爱技术的人们致敬! ?????????权威嵌入式研发机构    嵌入式职业生涯第一步!  ...…

查看全部问答>

关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问

void Launch(DWORD dwLaunchAddr)这个函数是在SMDK2440A\\Src\\Bootloader\\Eboot\\util.s(32)实现的 ;******************************************************************************     INCLUDE kxarm.h PHY_RAM_START  &n ...…

查看全部问答>

PADS2007_教程之PADS ROUTER

PADS2007_教程之PADS ROUTER…

查看全部问答>

128K的FLASH和20K的SRAM够ucos+ucgui么??

新手求教,问个简单问题~~~~~ 想买块便宜的STM32开发板学习UCOS+UCGUI。128K的FLASH和20K的SRAM够用么(神州一号)??…

查看全部问答>