STM32F4学习笔记之USART(使用固件库,查询方式)
- 格式:doc
- 大小:25.00 KB
- 文档页数:2
STM32L4库学习总结ST为开发者提供了非常方便的开发库。
到目前为止,有标准外设库(STD库)、HAL库、LL库三种。
前两者都是常用的库,后面的LL库是ST最近才添加,随HAL源码包一起提供,目前支持的芯片也偏少。
一般来说STD库和LL库是不兼容的。
标准外设库(Standard Peripherals Library)是对STM32芯片的一个完整的封装,包括所有标准器件外设的器件驱动器。
这应该是目前使用最多的ST库。
几乎全部使用C语言实现。
但是,标准外设库也是针对某一系列芯片而言的,没有可移植性。
标准外设库仍然接近于寄存器操作,主要就是将一些基本的寄存器操作封装成了C函数。
开发者需要关注所使用的外设是在哪个总线之上,具体寄存器的配置等底层信息。
不支持从STM32L0、L4和F7以后的芯片。
HAL是Hardware Abstraction Layer的缩写,中文名:硬件抽象层。
HAL库是ST为STM32最新推出的抽象层嵌入式软件,可以更好的确保跨STM32产品的最大可移植性。
该库提供了一整套一致的中间件组件,如RTOS,USB,TCP / IP和图形等。
HAL库是基于一个非限制性的BSD许可协议(Berkeley Software Distribution)而发布的开源代码。
ST制作的中间件堆栈(USB主机和设备库,STemWin)带有允许轻松重用的许可模式,只要是在ST公司的MCU 芯片上使用,库中的中间件(USB 主机/设备库,STemWin)协议栈即被允许随便修改,并可以反复使用。
至于基于其它著名的开源解决方案商的中间件(FreeRTOS,FatFs,LwIP和PolarSSL)也都具有友好的用户许可条款。
可以说HAL库就是用来取代之前的标准外设库的。
相比标准外设库,STM32Cube HAL库表现出更高的抽象整合水平,HAL API集中关注各外设的公共函数功能,这样便于定义一套通用的用户友好的API函数接口,从而可以轻松实现从一个STM32产品移植到另一个不同的STM32系列产品。
STM32 固件库中RCC_GetClocksFreq()函数注意事项在STM32 固件库中,当你使用RCC_GetClocksFreq()这个函数的时候,需要注意一下。
(比如,你在使用串口的USART_Init 的时候,就无形中使用到这个函数)。
当你使用外部晶振做为系统时钟的时候,而且外部晶振不是标准8MHz 的时候,你需要留意一下STM32 的固件库,里面的stm32f10x_rcc.c 这个文件,在它的RCC_GetClocksFreq()这个函数中,有这么一段voidRCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks){u32 tmp = 0, pllmull = 0, pllsource = 0, presc = 0;/* Get SYSCLK source -*/tmp = RCC->CFGR & CFGR_SWS_Mask;switch (tmp){case 0 乘以00:/* HSI used as system clock */RCC_Clocks- >SYSCLK_Frequency = HSI_Value;break;case 0 乘以04:/* HSE used as system clock */RCC_Clocks- >SYSCLK_Frequency=HSE_Value;break;case 0 乘以08:/* PLL used as system clock *//* Get PLL clock source and multiplication factor -*/pllmull = RCC->CFGR & CFGR_PLLMull_Mask;pllmull = ( pllmull >> 18) + 2;pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;if (pllsource == 0 乘以00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;}else{/* HSE selected as PLL clock entry */if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (u32)RESET){/* HSE oscillator clock divided by 2 */。
/******************************************************************* 文件名:书写程序中一些特别需要留意的地方文件编辑人:张恒编辑日期:15/11/23功能:快速查阅巩固知识点*******************************************************************/ 版本说明:v1.0版本:1.开始编辑书写整个文档,开始用的为TXT文档的形式,整理了部分学习到的东西和一些在书写常用程序中容易出错的地方,以及经常忽视细节而导致程序运行失败,是巩固知识点,提醒值得注意地方的工具文档。
2.添加的功能上基本涵盖了所有的模块,除了串口通信中的SPI和I2C、I2S等,应用是比较简单后续可能会添加。
3.对一些特定的功能综合应用并未加入进去,这是一个不好的地方,后续应该会随着学习总结更新,每次更新记录为一个版本。
// 2015/11/24;v1.1版本:1.将所有的TXT版本的文档全部转换为DOC模式,并且更新的加入了目录显示,显示为1级目录,方便查阅相关内容。
2.更新了SysTick书写中值得注意的地方3.更新了FSMC的一些细微操作,后续继续追捕更新书写细节。
V1.2版本:1.更新了FSMC部分功能显示,详细了FSMC的使用注意事项2.添加了RTC实时时钟的一些注意事项。
//2015/12/1;V1.3版本:1.更新RTC部分注意事项。
//2015/12/11V1.4版本:1.更新ADC校准标志部分注意事项。
2.更新了TIM1和TIM8的高级定时器特殊功能说明。
//2015/12/13V1.5版本:1.优化了部分注意事项,SysTick的写法上重新的定制写法。
2.优化了ADC在使用过程的一些细节注意地方。
3.面对最近出现的浮点数运算错误,配合AD数据进行总结。
4.RTC细节的把握-配置正确顺序的错误。
stm32f4 的 dma 中断函数STM32F4系列微控制器是ST公司推出的一款高性能、低功耗的32位ARM Cortex-M4内核微控制器。
它具有丰富的外设和强大的计算能力,广泛应用于各种嵌入式系统中。
其中,DMA(Direct Memory Access,直接存储器访问)是STM32F4中重要的特性之一,可以有效地提高数据传输的效率和性能。
DMA中断函数是在DMA传输过程中产生中断时执行的函数。
在STM32F4中,DMA控制器负责处理数据传输,而CPU可以在数据传输过程中执行其他任务。
当DMA传输完成或出现错误时,DMA控制器会触发中断,然后执行相应的中断函数。
在编写DMA中断函数之前,首先需要配置DMA控制器和相关外设。
以USART为例,下面是配置USART和DMA的简单示例代码:```c// 配置USARTUSART_InitTypeDef USART_InitStruct;USART_ART_BaudRate = 115200;USART_ART_WordLength = USART_WordLength_8b; USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Tx;USART_Init(USART1, &USART_InitStruct);USART_Cmd(USART1, ENABLE);// 配置DMADMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_Channel = DMA_Channel_4;DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)buffer;DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;DMA_InitStruct.DMA_BufferSize = sizeof(buffer);DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;DMA_InitStruct.DMA_Priority = DMA_Priority_High;DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA2_Stream7, &DMA_InitStruct);// 配置DMA中断NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = DMA2_Stream7_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);```在上述代码中,首先配置了USART1的相关参数,然后配置了DMA2的Stream7通道,将USART1的数据寄存器和存储器进行连接。
STM32使⽤printf发送数据配置⽅法--串⼝UART,JTAGSWO,JLINKRTTSTM32串⼝通信中使⽤printf发送数据配置⽅法(开发环境 Keil RVMDK)在STM32串⼝通信程序中使⽤printf发送数据,⾮常的⽅便。
可在刚开始使⽤的时候总是遇到问题,常见的是硬件访真时⽆法进⼊main主函数,其实只要简单的配置⼀下就可以了。
下⾯就说⼀下使⽤printf需要做哪些配置。
有两种配置⽅法:⼀、对⼯程属性进⾏配置,详细步骤如下1、⾸先要在你的main ⽂件中包含“stdio.h” (标准输⼊输出头⽂件)。
2、在main⽂件中重定义<fputc>函数如下:// 发送数据int fputc(int ch, FILE *f){USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等while (!(USART1->SR & USART_FLAG_TXE));return (ch);}// 接收数据int GetKey (void){while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));}这样在使⽤printf时就会调⽤⾃定义的fputc函数,来发送字符。
3、在⼯程属性的 “Target" -> "Code Generation" 选项中勾选 "Use MicroLIB"MicroLIB 是缺省C的备份库,关于它可以到⽹上查找详细资料。
⼆、第⼆种⽅法是在⼯程中添加“Regtarge.c”⽂件1、在main⽂件中包含 “stdio.h” ⽂件2、在⼯程中创建⼀个⽂件保存为 Regtarge.c ,然后将其添加⼯程中在⽂件中输⼊如下内容(直接复制即可)#include <stdio.h>#include <rt_misc.h>#pragma import(__use_no_semihosting_swi)extern int SendChar(int ch); // 声明外部函数,在main⽂件中定义extern int GetKey(void);struct __FILE {int handle; // Add whatever you need here};FILE __stdout;FILE __stdin;int fputc(int ch, FILE *f) {return (SendChar(ch));}int fgetc(FILE *f) {return (SendChar(GetKey()));}void _ttywrch(int ch) {SendChar (ch);}int ferror(FILE *f) { // Your implementation of ferrorreturn EOF;}void _sys_exit(int return_code) {label: goto label; // endless loop}3、在main⽂件中添加定义以下两个函数int SendChar (int ch) {while (!(USART1->SR & USART_FLAG_TXE)); // USART1 可换成你程序中通信的串⼝USART1->DR = (ch & 0x1FF);return (ch);}int GetKey (void) {while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));}⾄此完成配置,可以在main⽂件中随意使⽤ printf 。
usart_senddata函数用法USART (Universal Synchronous/Asynchronous Receiver/Transmitter) 是一种由微处理器或计算机实现的串行通信接口,用于向外界设备或其他计算机传输数据。
USART可实现异步或同步的串行传输,具有高效性、可靠性和灵活性,因此在许多计算机和嵌入式系统中广泛应用。
USART使用串行通信协议,通过发送和接收数据包,实现设备间的数据交换。
在这里,我们将介绍USART_SendData函数的用法。
USART_SendData函数是STM32微控制器的USART库函数之一,用于在USART通信中向外界设备发送数据。
通常,在发送数据之前,需要初始化USART接口,配置它的各种参数,包括波特率、数据位、停止位和校验位等。
这些参数可以通过STM32芯片上的USART寄存器进行配置。
在配置完成之后,可以使用USART_SendData函数将数据发送到USART接口。
USART_SendData函数的参数有两个,第一个是USART_TypeDef类型的指针,指向USART寄存器组。
USART_TypeDef结构体中包含了USART寄存器的各种寄存器值,包括数据寄存器、状态寄存器和控制寄存器等。
第二个参数是要发送的数据值,为unsigned short类型。
USART_SendData函数的返回值为一个标志位,标志着数据是否成功发送。
如果数据发送成功,返回值为1;如果数据发送失败,返回值为0。
USART_SendData函数的使用非常简单,只需调用函数并传递参数即可发送数据。
以下是USART_SendData函数的示例代码,它将一个8位二进制字节(0x55)发送到USART1接口:USART_SendData(USART1, 0x55);在发送数据之后,通常需要检查发送是否成功。
可以使用USART_GetFlagStatus函数来读取USART标志位状态,以确定数据是否成功发送。
32位基于ARM微控制器STM32F101xx与STM32F103xx固件函数库介绍本手册介绍了32位基于ARM微控制器STM32F101xx与STM32F103xx的固件函数库。
该函数库是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。
该函数库还包括每一个外设的驱动描述和应用实例。
通过使用本固件函数库,无需深入掌握细节,用户也可以轻松应用每一个外设。
因此,使用本固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。
每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。
每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。
所有的驱动源代码都符合“Strict ANSI-C”标准(项目于范例文件符合扩充ANSI-C标准)。
我们已经把驱动源代码文档化,他们同时兼容MISRA-C 2004标准(根据需要,我们可以提供兼容矩阵)。
由于整个固态函数库按照“Strict ANSI-C”标准编写,它不受不同开发环境的影响。
仅对话启动文件取决于开发环境。
该固态函数库通过校验所有库函数的输入值来实现实时错误检测。
该动态校验提高了软件的鲁棒性。
实时检测适合于用户应用程序的开发和调试。
但这会增加了成本,可以在最终应用程序代码中移去,以优化代码大小和执行速度。
想要了解更多细节,请参阅Section 2.5。
因为该固件库是通用的,并且包括了所有外设的功能,所以应用程序代码的大小和执行速度可能不是最优的。
对大多数应用程序来说,用户可以直接使用之,对于那些在代码大小和执行速度方面有严格要求的应用程序,该固件库驱动程序可以作为如何设置外设的一份参考资料,根据实际需求对其进行调整。
此份固件库用户手册的整体架构如下:定义,文档约定和固态函数库规则。
固态函数库概述(包的内容,库的架构),安装指南,库使用实例。
1.使能对应USART模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, UART4 or
UART5.
2.使能对应GPIO的时钟
RCC_AHB1PeriphClockCmd() function. (The I/O can be TX, RX, CTS, or/and SCLK).
3.配置对应引脚的复用功能
GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_USARTx); //引脚映射
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 设置为推挽输
出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x | GPIO_Pin_x; //引脚选择
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz; //速度选择
GPIO_Init(GPIOx, &GPIO_InitStructure); //写入
配置信息
4.配置USART信息
USART_InitStructure.USART_BaudRate = xxx; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_xb;//字长
USART_InitStructure.USART_StopBits = USART_StopBits_x; //停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //校验
位,USART_Parity_Even,USART_Parity_Odd
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;//硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //工作模
式
USART_Init(USARTx, &USART_InitStructure); //写入配
置信息
USART_Cmd(USARTx, ENABLE);
//使能串口模块
5.发送
USART_SendData(USARTx, char xx); //发
送字符
while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);//等待发送
完成
6.接收
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) //查询是否接收到数据
xxx=USART_ReceiveData(USARTx) //读
取接收到的数据
程序举例:
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
while (1)
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
{
USART_SendData(USART1, USART_ReceiveData(USART1));
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
}
}