历史上的今天
今天是: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 } /******************************************************************************* * 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;
史海拾趣
|
把常见的问题都罗列了 链接:https://home.eeworld.com.cn/my/space.php?do=blog&uid=80086&id=28343… 查看全部问答> |
|
我最近查了些资料 现在把我的需求在整理一下:我想做一个嵌入式USB主机(强调是主机端host,不是USB设备),这是第一次做一个完整的系统,不知从何入手,有这样几个问题,首先是主控芯片,如果单片机可以,用哪种?另外电源模块用什么方案比较好? ...… 查看全部问答> |
|
我用ARM板测试一个触摸屏程序,偶尔出现飘屏! 源码如下: #include \"def1.h\" #include \"2440addr.h\" #include \"2440lib.h\" #include \"config.h\" #define REQCNT 30 #define ADCPRS 9 //YH 0627 #define LO ...… 查看全部问答> |
|
亚嵌《嵌入式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 ...… 查看全部问答> |
|
128K的FLASH和20K的SRAM够ucos+ucgui么?? 新手求教,问个简单问题~~~~~ 想买块便宜的STM32开发板学习UCOS+UCGUI。128K的FLASH和20K的SRAM够用么(神州一号)??… 查看全部问答> |




