STM32学习笔记

合集下载

《STM32Cube高效开发教程》笔记

《STM32Cube高效开发教程》笔记

《STM32Cube高效开发教程》读书笔记目录一、前言 (2)1.1 书籍简介 (3)1.2 编写目的 (4)二、STM32Cube概述 (5)2.1 STM32Cube的意义 (6)2.2 STM32Cube的主要特点 (7)三、安装与配置 (9)3.1 STM32Cube的安装 (10)3.2 开发环境的配置 (11)四、创建项目 (12)4.1 新建项目 (13)4.2 项目设置 (14)五、HAL库介绍 (15)5.1 HAL库简介 (16)5.2 HAL库的主要组件 (18)六、STM32最小系统 (19)6.1 STM32最小系统的组成 (21)6.2 STM32最小系统的应用 (22)七、GPIO操作 (24)7.1 GPIO的基本概念 (25)7.2 GPIO的操作方法 (26)八、中断系统 (28)8.1 中断的基本概念 (29)8.2 中断的处理过程 (31)九、定时器 (33)9.1 定时器的功能介绍 (34)9.2 定时器的操作方法 (36)十五、文件系统 (37)一、前言随着科技的飞速发展,嵌入式系统已广泛应用于我们生活的方方面面,从智能手机到自动驾驶汽车,其重要性不言而喻。

而STM32作为一款广泛应用的微控制器系列,以其高性能、低功耗和丰富的外设资源赢得了广大开发者的青睐。

为了帮助开发者更好地掌握STM32系列微控制器的开发技巧,提升开发效率,我们特别推出了《STM32Cube 高效开发教程》。

本书以STM32Cube为核心,通过生动的实例和详细的讲解,全面介绍了STM32系列微控制器的开发过程。

无论是初学者还是有一定基础的开发者,都能从中找到适合自己的学习内容。

通过本书的学习,读者将能够更加深入地理解STM32的内部结构和工作原理,掌握其编程方法和调试技巧,从而更加高效地进行嵌入式系统的开发和应用。

在科技日新月异的今天,STM32系列微控制器将继续扮演着举足轻重的角色。

STM32学习笔记:读写内部Flash(介绍+附代码)

STM32学习笔记:读写内部Flash(介绍+附代码)

STM32学习笔记:读写内部Flash(介绍+附代码)⼀、介绍⾸先我们需要了解⼀个内存映射:stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯⽚实际的flash⼤⼩,不同的芯⽚flash⼤⼩不同。

RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯⽚的RAM⼤⼩。

不同的芯⽚RAM也不同。

Flash中的内容⼀般⽤来存储代码和⼀些定义为const的数据,断电不丢失,RAM可以理解为内存,⽤来存储代码运⾏时的数据,变量等等。

掉电数据丢失。

STM32将外设等都映射为地址的形式,对地址的操作就是对外设的操作。

stm32的外设地址从0x4000 0000开始,可以看到在库⽂件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。

⼀般情况下,程序⽂件是从 0x0800 0000 地址写⼊,这个是STM32开始执⾏的地⽅,0x0800 0004是STM32的中断向量表的起始地址。

在使⽤keil进⾏编写程序时,其编程地址的设置⼀般是这样的:程序的写⼊地址从0x08000000(数好零的个数)开始的,其⼤⼩为0x80000也就是512K的空间,换句话说就是告诉编译器flash的空间是从0x08000000-0x08080000,RAM的地址从0x20000000开始,⼤⼩为0x10000也就是64K的RAM。

这与STM32的内存地址映射关系是对应的。

M3复位后,从0x08000004取出复位中断的地址,并且跳转到复位中断程序,中断执⾏完之后会跳到我们的main函数,main函数⾥边⼀般是⼀个死循环,进去后就不会再退出,当有中断发⽣的时候,M3将PC指针强制跳转回中断向量表,然后根据中断源进⼊对应的中断函数,执⾏完中断函数之后,再次返回main函数中。

⼤致的流程就是这样。

1.1、内部Flash的构成:STM32F429 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及⼤⼩如下:STM32F103的中容量内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及⼤⼩如下:注意STM32F105VC的是有64K或128页x2K=256k字节的内置闪存存储器,⽤于存放程序和数据。

stm32学习经历(5篇可选)

stm32学习经历(5篇可选)

stm32学习经历(5篇可选)第一篇:stm32学习经历随便写写,关于stm32 最近在学习stm32,写点东西,虽然简单,但都是原创啊开发板是前辈画的,好像是用来测试一个3G功能的,不过对于我来说太远;我要来了3个,自己焊了一个最小系统,好在公司资源还是不错的,器件芯片有,还可以问问前辈--对公司还是比较满意的,虽然工资少了点,但学东西第一位O(∩_∩)O~。

最开始当然是建工程了,这个真不太会,前前后后竟用了一周(时间真长,别见笑啊),上网查资料,问前辈,自己琢磨。

总算搞定,然后从GPIO开始学,开始还真没什么头绪(虽然在大学学点51,但完全没有真正应用,顶多是跑马灯实验),开始纠结是从寄存器开始学还是从库函数开始学,后来看到一句“用库函数入门,用寄存器提高”于是下定决心用库,但当时没有库的概念,结果走了很多弯路,看了很多不必要的东西,当时竟没理解到只是调用库就OK了,别的不用管。

最后潜心的在教程网看完一个例程后照猫画虎写了一个,经过了多次调试以后,灯终于亮了!那个兴奋啊。

再次还要感谢希望自己坚持下去,早日能写出一个属于自己的程序,完成一个说的过去的功能,下面把我的程序粘出来,和大家分享下,大虾看到了别见笑啊注:1.有两个灯,PA4 B12,都是低电平点亮2.有两个按键,PB8 和 PB9,按下是低电平3.程序开始后两个灯常亮,按下按键后熄灭,抬起后继续亮main.c中#include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_exti.h" void RCC_Configuration(void) //时钟配置函数{ ErrorStatus HSEStartUpStatus; //使能外部晶振RCC_HSEConfig(RCC_HSE_ON); //等待外部晶振稳定HSEStartUpStatus = RCC_WaitForHSEStartUp(); //如果外部晶振启动成功,则进行下一步操作if(HSEStartUpStatus==SUCCESS) { //设置HCLK(AHB时钟)=SYSCLK 将系统时钟进行分频后,作为AHB总线时钟RCC_HCLKConfig(RCC_SYSCLK_Div1); //PCLK1(APB1) = HCLK/2 将HCLK时钟2分频后给低速外部总线RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK2(APB2) = HCLK HCLK时钟配置给高速外部总线 RCC_PCLK2Config(RCC_HCLK_Div1); //外部高速时钟HSE 4倍频RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4); //启动PLL RCC_PLLCmd(ENABLE); //等待PLL稳定while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //系统时钟SYSCLK来自PLL输出RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //切换时钟后等待系统时钟稳定 while(RCC_GetSYSCLKSource()!=0x08); } // 下面这些都是外设总线上所挂的外部设备时钟的配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); }void GPIO_Configuration(void) //GPIO配置函数{ //GPIO_DeInit(GPIOA); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP; GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP; GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;GPIO_Init(GPIOB,&GPIO_InitStructure); } void EXTI_Config(void) { EXTI_InitTypeDef EXTI_InitStructure; // 管脚选择GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9); // 清除 EXTI线路挂起位EXTI_ClearITPendingBit(EXTI_Line8|EXTI_Line9); // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Line = EXTI_Line8|EXTI_Line9; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; // 注意名称是“_IRQn”,不是“_IRQChannel”NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } int main(void) { RCC_Configuration(); GPIO_Configuration(); EXTI_Config(); NVIC_Config();while(1) { GPIO_ResetBits(GPIOB,GPIO_Pin_12); GPIO_ResetBits(GPIOA,GPIO_Pin_4); } } 中断文件 it.c中void EXTI9_5_IRQHandler(void) { if ( EXTI_GetITStatus(EXTI_Line8) != RESET ) { EXTI_ClearITPendingBit(EXTI_Line8);GPIO_SetBits(GPIOA,GPIO_Pin_4);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0); } if ( EXTI_GetITStatus(EXTI_Line9) != RESET ){ EXTI_ClearITPendingBit(EXTI_Line9);GPIO_SetBits(GPIOB,GPIO_Pin_12);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0);勤劳的蜜蜂有糖吃} }第二篇:STM32入门经历,高手不要进!现在STM32初学入门,写些关于入门的帮助,也算答谢帮助过我的人.希望象我这样想学STM32的朋友不用迷茫.(本入门只适合低手,高手不要见笑).1.硬件平台.现在可以买到学习有的有英蓓特的MCBSTM32 和万利的EK-STM32F,可能目前出来最好的还是的神舟系列开发板,包括神舟I号(103RBT),神舟II号(103VCT),神舟III号(103ZET),神舟iv号(107VCT)几款都有,反正这几个板我都买了,学校出钱买的,还挺实惠,让老板打了个折扣,如果你自己开板做,成本还比这高.学会了才自己做自己的板子吧.2.软件平台.现在流行的有Keil MDK 3.15b和 IAR EWARM 4.42A. 购买评估板时,里面的光盘已经带了.为什么选这两个平台,用的人多,你以后遇到问题,可以找人解决的机会就大.英蓓特的MCBSTM32用的是Keil MDK 平台, 万利的是 IAR EWARM.3.C语言知识如果想补这推荐一本入门的书C Primer Plus 中文版.这本也是入门的好书.4.ST的数据手册STM32F10x参考手册看完这个就对STM32的内部有认识.STM32 Document and library rules 个人认为这个最重要.因为你学会了C语言看例程时.很多如GPIO_SetBits GPIO_ResetBits.很多C语言以外的函数库.这些都是STM32的库文件.5.看例程.如keil MDK 3.15b下的C:/Keil/ARM/Boards/Keil/MCBSTM32 有很多例程.GPIO口,RTC,PWM,USB,CAN等等....你想到的都有例程.6.多上论坛,呵呵.....有不明问下高手,我也是这样.只要不断努力,你一定会成功的.第三篇:STM32学习心得笔记STM32学习心得笔记时钟篇在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

STM32自学笔记

STM32自学笔记

STM32⾃学笔记⼀、原⼦位操作:原⼦位操作定义在⽂件中。

令⼈感到奇怪的是位操作函数是对普通的内存地址进⾏操作的。

原⼦位操作在多数情况下是对⼀个字长的内存访问,因⽽位号该位于0-31之间(在64位机器上是0-63之间),但是对位号的范围没有限制。

原⼦操作中的位操作部分函数如下:void set_bit(int nr, void *addr)原⼦设置addr所指的第nr位void clear_bit(int nr, void *addr)原⼦的清空所指对象的第nr位void change_bit(nr, void *addr)原⼦的翻转addr所指的第nr位int test_bit(nr, void *addr)原⼦的返回addr位所指对象nr位inttest_and_set_bit(nr, void *addr)原⼦设置addr所指对象的第nr位,并返回原先的值int test_and_clear_bit(nr, void *addr)原⼦清空addr所指对象的第nr位,并返回原先的值int test_and_change_bit(nr, void *addr)原⼦翻转addr所指对象的第nr位,并返回原先的值unsigned long word = 0;set_bit(0, &word); /*第0位被设置*/set_bit(1, &word); /*第1位被设置*/clear_bit(1, &word); /*第1位被清空*/change_bit(0, &word); /*翻转第0位*/⼆、STM32的GPIO锁定:三、中断挂起:因为某种原因,中断不能马上执⾏,所以“挂起”等待。

⽐如有⾼、低级别的中断同时发⽣,就挂起低级别中断,等⾼级别中断程序执⾏完,在执⾏低级别中断。

四、固⽂件:固件(Firmware)就是写⼊EROM(可擦写只读存储器)或EEPROM(电可擦可编程只读存储器)中的程序。

STM32学习笔记及勘误手册

STM32学习笔记及勘误手册

/******************************************************************* 文件名:书写程序中一些特别需要留意的地方文件编辑人:张恒编辑日期: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细节的把握-配置正确顺序的错误。

stm32学习笔记-usart程序解释(原子)

stm32学习笔记-usart程序解释(原子)

USART程序分析一 .H文件#ifndef __USART_H#define __USART_H#include <stm32f10x_lib.h>#include "stdio.h"extern u8 USART_RX_BUF[64]; //接收缓冲,最大63个字节.末字节为换行符extern u8 USART_RX_STA; //接收状态标记//如果想串口中断接收,请不要注释以下宏定义//#define EN_USART1_RX 使能串口1接收void uart_init(u32 pclk2,u32 bound);#endif解释:extern 作用域:如果整个工程由多个文件组成,在一个文件中想引用另外一个文件中已经定义的外部变量时,则只需在引用变量的文件中用extern关键字加以声明即可。

可见,其作用域从一个文件扩展到多个文件了。

例子:文件a.c的内容:#include <stdio.h>int BASE=2; //变量定义int exe(int x); //外部函数提前声明int main(int argc, char *agrv[]){int a=10;printf("%d^%d = %d\n",BASE,a,exe(a));return 0;}文件b.c的内容:#include <stdio.h>extern BASE; //外部变量声明int exe(int x){int i;int ret=1;for(i=0;i<x;i++){ret*=BASE;}return ret;}利用gcc工具编译gcc a.c b.c –o demo,再运行./demo,结果为2^10= 1024。

其中,在a.c文件中定义BASE=2,在b.c中引用BASE时,需要用extern关键字声明其为外部变量,否则编译会找不到该变量。

stm32自学笔记共20页

stm32自学笔记共20页


LED0=1;

LED1=0;

delay_ms(300);

}
•}
第二章 跑马灯实验
• Led.c函数
• void LED_Init(void)
•{

RCC->APB2ENR|=1<<2; //使能PORTA时钟

GPIOA->CRH|=0XFFFFFFFF3;//PA8 推挽输出

GPIOA->ODR|=1<<8; //PA8 输出高
• JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD,在原理图上可以看 到PA13和PA15为键盘和JTAG与SWD所共用,而这两种方针接口,他们 和普通的IO口公用,当想使用普通IO口时,必须先把他们关闭。在这 个函数里面设置参数,如果为二进制数00,则代表全部使能,如果是 二进制数01,则是能SWD,如果是10,则表示全部关闭。JTAG是一种 国际标准测试协议,主要用于芯片内部的测试。
• }要想实现一个点亮led小灯的功能,最少只需对3个寄存器进行设 置,第一步是设置外设时钟使能先把PORTA时钟使能,接下来把IO
口设置为输出,在接下来设置输出为高电平还是低电平,这里使用 推挽输出(3.3v),推挽输出主要是增强驱动能力,为外部提供大电 流。
第二章 跑马灯实验
• #ifndef __LED_H • #define __LED_H • #include "sys.h" • #define LED0 PAout(8)// PA8 • #define LED1 PDout(2)// PD2 • void LED_Init(void);//初始化

《STM32库开发实战指南 基于STM32F103 第2版 》读书笔记思维导图

《STM32库开发实战指南 基于STM32F103 第2版 》读书笔记思维导图

31.5 定时器初始化 结构体详解
31.6 PWM互补输 出实验
31.7 脉宽测量输入 捕获实验
31.8 PWM输入捕 获实验
32.1 电容按键 原理
32.2 电容按键 检测实验
33.1 IWDG简介
33.2 IWDG功能框 图剖析
33.3 怎么用IWDG
33.4 IWDG超时实 验
34.1 WWDG简介
11.2 软件设计
11.1 硬件设计
11.3 STM32标准 库补充知识
12.2 软件设计
12.1 硬件设计
12.3 下载验证
13.1 位带简介
13.2 GPIO位 带操作
14.2 查找ARM汇 编指令
14.1 启动文件简介
14.3 启动文件代码 讲解
15.2 RCC框图剖 析——时钟部分
4 40.4 操作内部
Flash的库函 数
5
40.5 实验:读 写内部Flash
41.1 选项字节与读 写保护
41.2 修改选项字节 的过程
41.3 操作选项字节 的库函数
41.4 实验:设置读 写保护及解除
42.2 OV7725摄像 头
42.1 摄像头简介
42.3 摄像头驱动实 验
43.1 Huawei Lite OS简...
18.2 Sys Tick寄存 器介绍
18.1 Sys Tick简介
18.3 Sys Tick定时 实验
19.1 串行通信与并 行通信
19.2 全双工、半双 工及单工通信
19.3 同步通信与异 步通信
19.4 通信速率
01
20.1 串口 通信协议简 介
02
20.2 STM32的 USART简 介

stm32相关笔记——ADC部分

stm32相关笔记——ADC部分

stm32相关笔记——ADC部分我们在学习⼀门技术的时候,应该对它的理论部分有所了解,然后才能在实践中进⼀步加深理解,进⽽掌握。

对于stm32来说,我认为学习的时候应该先仔细阅读相关的参考⼿册,然后再动⼿实践,这样才能理解得更加透彻,掌握得更加牢固!今天记录⼀下我学习stm32的ADC部分的了解。

1.介绍⼩结:stm32的ADC有18个通道(16个外部通道+2个内部通道),有单次、连续、扫描和间断四种模式,ADC的结果可以左对齐和右对齐的⽅式存储在16位的数据寄存器中(⼀般我们都是使⽤右对齐的⽅式)2、特征3、框图框图应该是最重要的部分了,理解了框图,对这个外设的理解就⽐较透彻了。

①模拟⾄数字转换器中有两个通道,⼀个是注⼊通道,⼀个是规则通道,对应的转换结果也是存储到注⼊通道数据寄存器和规则通道数据寄存器中(都是16位的);②注⼊通道数据寄存器有4个,规则通道数据寄存器只有1个,规则通道最多可以转化16个通道的数据,⽽结果都是存储在⼀个规则通道数据寄存器中,为了避免数据丢失,可以采⽤DMA搬运数据,提⾼效率。

③触发注⼊通道开始转化的外部触发信号有8种,如图所⽰,其中TIM8_CH4及其重映射只存在于⼤容量的产品中。

④类似于注⼊通道,触发规则通道的外部触发信号也有8种,如图所⽰,其中TIM8_TRGO及其重映射也只存在于⼤容量产品中。

⑤以上的两点只针对ADC1和ADC2,ADC3的触发信号有所不同,如图所⽰:⑥转换的过程如图,ADCx_IN0~ADCx_IN15共16个外部通道,通过GPIO端⼝将模拟量传达到模拟⾄数字转化器中的注⼊通道或者规则通道,另外还有两个内部通道温度传感器和V REFINT,同样也可以将模拟量传送到模拟⾄数字转化器中的注⼊通道或者规则通道,注⼊通道最多可以转换4个通道的模拟量,转换结果存储到注⼊通道数据寄存器中,转换完成后会产⽣JEOC标志位,规则通道最多可以转换16个通道,转换结果存储到规则通道数据寄存器中,转换完成后会产⽣EOC标志位。

STM32学习笔记

STM32学习笔记

一、GPIO操作IO 的方法:1)使能IO 口时钟。

调用函数为RCC_APB2PeriphClockCmd()。

2)初始化IO 参数。

调用函数GPIO_Init();3)操作IO。

GPIO_Mode有:GPIO_Mode_AIN = 0x0, //模拟输入GPIO_Mode_IN_FLOATING = 0x04, //浮空输入GPIO_Mode_IPD = 0x28, //下拉输入GPIO_Mode_IPU = 0x48, //上拉输入GPIO_Mode_Out_OD = 0x14, //开漏输出GPIO_Mode_Out_PP = 0x10, //通用推挽输出GPIO_Mode_AF_OD = 0x1C, //复用开漏输出GPIO_Mode_AF_PP = 0x18 //复用推挽IO 口速度设置:GPIO_Speed_10MHz = 1,GPIO_Speed_2MHz,GPIO_Speed_50MHz初始化结构体初始化GPIO 的常用格式://初始化PGIO_PC.4为上拉输入GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PC.4 端口配置GPIO_Mode_IPU = 0x48, //上拉输入GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能,GPIOA 时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.0 发送端读GPIOA.5 的电平状态:GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);控制IO 口的输出状态:void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);设置GPIOA 的第1 个端口值为1,那么你只需要往寄存器BSRR 的低16 位对应位写1 即可:GPIOA->BSRR=1<<1;如果你要设置GPIOA 的第1 个端口值为0,你只需要往寄存器高16 位对应为写1 即可:GPIOA->BSRR=1<<(16+1)对应函数void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);STM32 的IO 口做输入使用的时候,是通过调用函数GPIO_ReadInputDataBit()来读取IO 口的状态的在配置STM32 外设的时候,任何时候都要先使能该外设的时钟!二、串口串口设置的一般步骤可以总结为如下几个步骤:1) 串口时钟使能,GPIO 时钟使能2) 串口复位3) GPIO 端口模式设置4) 串口参数初始化5) 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)6) 使能串口7) 编写中断处理函数1.串口时钟使能。

单片机STM32学习笔记

单片机STM32学习笔记

推挽输出与开漏输出的区别推挽输出推挽输出::可以输出高可以输出高,,低电平低电平,,连接数字器件连接数字器件; ;开漏输出开漏输出::输出端相当于三极管的集电极输出端相当于三极管的集电极. . 要得到高电平状态需要上拉电阻才行要得到高电平状态需要上拉电阻才行. . 适合于做电流型的驱动电流型的驱动,,其吸收电流的能力相对强其吸收电流的能力相对强((一般20ma 以内以内). ).推挽结构一般是指两个三极管分别受两互补信号的控制推挽结构一般是指两个三极管分别受两互补信号的控制,,总是在一个三极管导通的时候另一个截止另一个截止. .要实现“线与”需要用OC(open collector)collector)门电路门电路门电路..是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中以推挽方式存在于电路中,,各负责正负半周的波形放大任务各负责正负半周的波形放大任务,,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小关管每次只有一个导通,所以导通损耗小,,效率高。

输出既可以向负载灌电流,也可以从负载抽取电流。

抽取电流。

问题:问题:很多芯片的供电电压不一样,有3.3v 和5.0v 5.0v,需要把几种,需要把几种IC 的不同口连接在一起,是不是直接连接就可以了?实际上系统是应用在I2C 上面。

上面。

简答:简答:1、部分3.3V 器件有5V 兼容性,可以利用这种容性直接连接兼容性,可以利用这种容性直接连接2、应用电压转换器件,如TPS76733就是5V 输入,转换成3.3V 3.3V、、1A 输出。

输出。

开漏电路特点及应用在电路设计时我们常常遇到开漏(在电路设计时我们常常遇到开漏(open drain open drain )和开集()和开集()和开集(open collector open collector )的概念。

所)的概念。

所谓开漏电路概念中提到的“漏”就是指MOSFET 的漏极。

STM32学习笔记系统时钟和SysTick定时器

STM32学习笔记系统时钟和SysTick定时器

STM32学习笔记(3):系统时钟和SysTick定时器1.STM32的时钟系统在STM32中,一共有5个时钟源,分别是HSI、HSE、LSI、LSE、PLL(1)HSI是高速内部时钟,RC振荡器,频率为8MHz;(2)HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围是4MHz – 16MHz;(3)LSI是低速内部时钟,RC振荡器,频率为40KHz;(4)LSE是低速外部时钟,接频率为32.768KHz的石英晶体;(5)PLL为锁相环倍频输出,严格的来说并不算一个独立的时钟源,PLL 的输入可以接HSI/2、HSE或者HSE/2。

倍频可选择为2 – 16倍,但是其输出频率最大不得超过72MHz。

其中,40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。

另外,实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。

STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。

该时钟源只能从PLL端获取,可以选择为1.5分频或者1分频,也就是,当需使用到USB模块时,PLL必须使能,并且时钟配置为48MHz 或72MHz。

另外STM32还可以选择一个时钟信号输出到MCO脚(PA.8)上,可以选择为PLL输出的2分频、HSI、HSE或者系统时钟。

系统时钟SYSCLK,它是提供STM32中绝大部分部件工作的时钟源。

系统时钟可以选择为PLL输出、HSI、HSE。

系系统时钟最大频率为72MHz,它通过AHB分频器分频后送给各个模块使用,AHB分频器可以选择1、2、4、8、16、64、128、256、512分频,其分频器输出的时钟送给5大模块使用:(1)送给AHB总线、内核、内存和DMA使用的HCLK时钟;(2)通过8分频后送给Cortex的系统定时器时钟;(3)直接送给Cortex的空闲运行时钟FCLK;(4)送给APB1分频器。

STM32学习笔记(5):通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出1.TIMER输出PWM基本概念脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

简单一点,就是对脉冲宽度的控制。

一般用来控制步进电机的速度等等。

STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM 输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。

1.1PWM输出模式STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。

模式1和模式2的区别如下:110:PWM模式1-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

111:PWM模式2-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。

而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。

1.2PWM输出管脚PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7定时器复用功能重映射”一节。

在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。

STM32学习笔记,定时器,PWM,ADC,UART,DMA

STM32学习笔记,定时器,PWM,ADC,UART,DMA
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1 ); capture = TIM_GetCapture1(TIM1); TIM_SetCompare1(TIM1, capture + 2000); //这里解释下: //将 TIM1_CCR1 的值增加 2000,使得下一个 TIM 事件也需要 2000 个脉冲, //另一种方式是清零脉冲计数器 //TIM_SetCounter(TIM2,0x0000); }
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,\ ENABLE); //启动 AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //启动 TIM1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//Step2. GPIO 做相应设置,为 AF 输出 //PA.8/9 口设置为 TIM1 的 OC1 输出口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
}
关于 TIM 的操作,要注意的是 STM32 处理器因为低功耗的需要,各模块需要分别独立开启时钟,所以, 一定不要忘记给用到的模块和管脚使能时钟,因为这个原因,浪费了我好多时间阿~~!
STM32 笔记(二)TIM 模块产生 PWM 这个是 STM32 的 PWM 输出模式,STM32 的 TIM1 模块是增强型的定时器模块,天生就是为电机控制而生,可 以产生 3 组 6 路 PWM,同时每组 2 路 PWM 为互补,并可以带有死区,可以用来驱动 H 桥。

STM32_深入浅出(新手必看)

STM32_深入浅出(新手必看)

STM32学前班教程之一:为什么是它经过几天的学习,基本掌握了STM32的调试环境和一些基本知识。

想拿出来与大家共享,笨教程本着最大限度简化删减STM32入门的过程的思想,会把我的整个入门前的工作推荐给大家。

就算是给网上的众多教程、笔记的一种补充吧,所以叫学前班教程。

其中涉及产品一律隐去来源和品牌,以防广告之嫌。

全部汉字内容为个人笔记。

所有相关参考资料也全部列出。

:lol教程会分几篇,因为太长啦。

今天先来说说为什么是它——我选择STM32的原因。

我对未来的规划是以功能性为主的,在功能和面积之间做以平衡是我的首要选择,而把运算放在第二位,这根我的专业有关系。

里面的运算其实并不复杂,在入门阶段想尽量减少所接触的东西。

不过说实话,对DSP的外设并和开发环境不满意,这是为什么STM32一出就转向的原因。

下面是我自己做过的两块DSP28的全功能最小系统板,在做这两块板子的过程中发现要想尽力缩小DSP的面积实在不容易(目前只能达到50mm×45mm,这还是没有其他器件的情况下),尤其是双电源的供电方式和1.9V的电源让人很头疼。

后来因为一个项目,接触了LPC2148并做了一块板子,发现小型的ARM7在外设够用的情况下其实很不错,于是开始搜集相关芯片资料,也同时对小面积的AVR和51都进行了大致的比较,这个时候发现了CortexM3的STM32,比2148拥有更丰富和灵活的外设,性能几乎是2148两倍(按照MIPS值计算)。

正好2148我还没上手,就直接转了这款STM32F103。

与2811相比较(核心1.8V供电情况下),135MHz×1MIPS。

现在用STM32F103,72MHz×1.25MIPS,性能是DSP的66%,STM32F103R型(64管脚)芯片面积只有2811的51%,STM32F103C型(48管脚)面积是2811的25%,最大功耗是DSP的20%,单片价格是DSP的30%。

STM32单片机应用与全案例实践stm32自学笔记第二版pdf

STM32单片机应用与全案例实践stm32自学笔记第二版pdf

STM32单⽚机应⽤与全案例实践stm32⾃学笔记第⼆版pdf STM32单⽚机应⽤与全案例实践pdfhttps:///s/16WrivuLcHvLTwS__Zcwl6Q4rj3stm32⾃学笔记第⼆版 pdfhttps:///share/init?surl=hsjGIXm6k5ustm32⾃学笔记第⼀版pdf/down1/stm32zxbj_downcc.zip/soft/317742.html第1章如何学习STM32 (1)1.1 学习STM32必须具备的知识基础(1)1.2 STM32的基本架构和基本原理(2)1.2.1 什么是ARM (2)1.2.2 什么是STM32 (3)1.2.3 STM32的内部结构(3)1.2.4 典型型号—STM32F103ZET6 (5)1.2.5 STM32的时钟树(5)1.3 学习STM32的最好⽅法是什么(9)1.4 学习STM32需要哪些⼯具或平台(9)1.4.1 硬件平台(10)1.4.2 软件平台(11)1.5 STM32程序开发的模式(12)1.5.1 基于寄存器的开发模式(13)1.5.2 基于ST固件库的开发模式(20)1.5.3 基于操作系统的开发模式(26)1.5.4 三种编程模式的选⽤建议(27)思考题(27)第2章如何调试STM32 (28)2.1 STM32单⽚机的最⼩系统(28)2.2 STM32⼯程模板的建⽴(30)2.2.1 STM32的固件库(Standard Peripherals Library)(30)2.2.2 新建⼯程模板第⼀步—拷贝固件库⽂件(34)2.2.3 新建⼯程模板第⼆步—新建⼀个KEIL⼯程(35)2.2.4 关于创建⼯程模板的简单⼩结(41)2.3 程序的烧写(42)2.3.1 基于串⼝的程序下载(烧写)⽅式(42)2.3.2 基于JTAG(SWD)的程序下载(烧写)⽅式(44)2.4 程序的调试(46)2.5 模板的使⽤(48)2.6 三个GPIO输出的范例—STM32中实现延时的三种常⽤⽅法(48)2.6.1 我的第⼀个LED⼯程—基于延时函数的延时(48)2.6.2 我的第⼆个LED⼯程—SysTick中断延时(50)2.6.3 我的第3个⼯程—定时器中断延时(52)2.7 GPIO⼝的各种输出⽅式及其应⽤(55)2.7.1 功能要求(55)2.7.2 程序实现(56)2.8 本章⼩结(58)思考题(59)第3章 GPIO及其应⽤—输⼊(60)3.1 单功能按键输⼊(60)3.1.1 实现思想(60)3.1.2 具体程序(61)3.2 复⽤功能按键输⼊(64)3.2.1 按键复⽤的基本概念(64)3.2.2 程序实现举例(64)3.3 ⾮按键类开关信号输⼊及其实现(67)3.3.1 GPIO的输⼊⽅式及其特点(67)3.3.2 程序实现(68)3.4 GPIO输⼊输出⼩结(69)思考题(70)第4章 TIMER与PWM (71)4.1 关于STM32的定时器概述(71)4.2 STM32定时器的简单应⽤(72)4.2.1 按周期输出⽅波的例⼦(72)4.2.2 实现原理(72)4.2.3 具体程序(72)4.3 STM32定时器的复杂应⽤—检测输⼊⽅波的频率(77)4.3.1 STM32定时器的其他特性(77)4.3.2 本例设计要求(78)4.3.3 硬件接⼝设计与测量原理(79)4.3.4 具体程序(79)4.4 PWM原理及其应⽤⼀—⼀个LED呼吸灯的实现(84)4.4.1 PWM的基本概念及其基本应⽤(84)4.4.2 STM32的PWM的实现原理(84)4.4.3 基于PWM的LED呼吸灯的实现思路(88)4.4.4 呼吸灯的实现程序(89)4.5 PWM原理及其应⽤⼆—通过L298N控制电机转速(96)4.5.1 硬件设计(96)4.5.2 直流电机调速与调向的原理(97)4.5.3 程序实现(97)思考题(104)第5章 USART及其应⽤(105)5.1 串⾏通信模块USART的基本应⽤要点(105)5.1.1 STM32的USART及其基本特性(105)5.1.2 STM32的USART应⽤的基本要领(106)5.2 ⼀个USART的通信实现(STM32与PC)—查询法(107)5.2.1 功能要求(107)5.2.2 实现难点(108)5.2.3 程序实现(108)5.2.4 USART应⽤的有关事项(114)5.3 ⼀个USART的通信实现(STM32与PC)—中断法(115)5.3.1 功能要求及通信协议设计(115)5.3.2 程序算法(115)5.3.3 本例的源程序(116)5.4 两个USART的通信实现(124)5.4.1 功能要求与通信协议(124)5.4.2 接⼝设计(124)5.4.3 程序实现(125)5.5 USART应⽤⼩结(139)思考题(141)第6章⼈机界⾯—按键输⼊与液晶显⽰(142)6.1 STM32与液晶模块12864的接⼝实现(142)6.1.1 STM32与液晶模块12864的接⼝实现—延时法(142)6.1.2 STM32与液晶模块12864的接⼝实现—查询“忙”状态(153)6.2 基于液晶模块12864的菜单实现(173)6.2.1 程序中菜单的种类与菜单化程序的优势(173)6.2.2 基于液晶模块12864的菜单实现实例(173)6.3 矩阵键盘的接⼝实现(186)6.3.1 矩阵键盘的应⽤与程序设计思想(186)6.3.2 4×4矩阵键盘的硬件设计(186)6.3.3 演⽰程序(187)6.4 本章⼩结(198)思考题(199)第7章同步串⾏接⼝总线SPI与I2C (200)7.1 STM32的SPI (200)7.1.1 SPI概述(200)7.1.2 STM32之SPI总线的应⽤要点(201)7.2 SPI的接⼝应⽤及其实现(202)7.2.1 STM32与OLED12864液晶模块的SPI接⼝(202)7.2.2 STM32的SPI1与OLED12864的接⼝程序(203)7.3 STM32的I2C总线(223)7.3.1 I2C总线的基本概念(223)7.3.2 STM32的I2C总线应⽤要领(226)7.4 STM32的I2C总线的应⽤举例(227)7.4.1 具有I2C接⼝的DS3231时钟模块(227)7.4.2 STM32与DS3231时钟模块的硬件接⼝(229)7.4.3 STM32与DS3231的软件接⼝及其演⽰实例(229)7.5 I2C总线稳健性设计(247)思考题(247)第8章 ADC、DAC与DMA及其应⽤(248)8.1 STM32的DMA (248)8.1.1 STM32的DMA及其基本特性(248)8.1.2 STM32的DMA原理及其配置要点(249)8.2 STM32的ADC (251)8.2.1 STM32的ADC的基本特性(251)8.2.2 STM32的ADC的程序流程与编程要点(253)8.3 ⼀个三通道A/D转换的范例(254)8.3.1 功能要求与⽅案设计(254)8.3.2 实现程序(256)8.3.3 本例的中断法实现(263)8.4 STM32的DAC (266)8.4.1 DAC概述(266)8.4.2 DAC的配置要领(266)8.4.3 DAC应⽤实例(268)思考题(277)第9章⼯程实例—基于线性CCD的⼩车循迹系统(278)9.1 系统要求(278)9.2 线性CCD的原理及其使⽤(278)9.2.1 线性CCD传感器原理(279)9.2.2 线性CCD传感器应⽤(280)9.2.3 硬件接⼝(281)9.3 ⾃适应曝光的算法设计(281)9.3.1 ⾃适应曝光算法(281)9.3.2 模块化架构(283)9.4 具体程序(285)9.4.1 ⼯程⽂件视图—⽂件结构(285)9.4.2 程序源代码(286)9.5 系统性能实测(315)9.5.1 系统实物与测试环境(315)9.5.2 系统实测结果(316)思考题(318)参考⽂献(319)。

stm32寄存器版学习笔记定时计数器中断

stm32寄存器版学习笔记定时计数器中断

stm32寄存器版学习笔记定时计数器中断STM32共有8个定时计数器,⾼级定时器: TIME1 TIME8是通⽤定时器:TIME2~TIME5基本定时器: TIME6和TIME7以TIME3通⽤定时器为例总结定时计数器的基本⽤法⼀:TIM3时钟使能APB1外设时钟使能寄存器(RCC_APB1ENR)Eg:RCC->APB1ENR|=1<<1; //使能TIM3时钟⼆:设置TIM3_ARR和TIM3_PSC的值通过这两个寄存器来设置⾃动重装的值以及分频系数⾃动重装载寄存器(TIMx_ARR)预分频器(TIMx_PSC)三:设置TIM3_DIER允许更新中断中断使能寄存器(TIMx_DIER)Eg: TIM3->DIER|=1<<0; //允许更新中断四:允许TIM3⼯作控制寄存器1(TIMx_CR1)CEN:使能计数器位0 0:禁⽌计数器; 1:使能计数器Eg: TIM3->CR1|=0x01; //使能定时器3 或 TIM3->CR1|=1<<0;五:TIM3中断分组设置直接调⽤MY_NVIC_Init()函数Eg:MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,⼦优先级3,组2六:编写中断服务函数状态寄存器(TIMx_SR)Eg: if(TIM3->SR&0X0001)//溢出中断Eg: //定时器3中断服务程序 void TIM3_IRQHandler(void) //TIM3_Int_Init(5000,7199); //10Khz的计数频率,计数到5000为500ms//500ms中断⼀次 { if(TIM3->SR&0X0001) //溢出中断 { //add your code } TIM3->SR&=~(1<<0); //清除中断标志位 }六:关于溢出事件的计算因为Stm32_Clock_Init函数⾥⾯已经初始化APB1的时钟为2分频,所以APB1的时钟是32MHz(系统时钟72MHz)。

超经典的STM32学习笔记——第一章GPIO口

超经典的STM32学习笔记——第一章GPIO口

…函数GPIO_Init】:GPIO_TypeDef为一结构体:typedef struct{__IO uint32_t CRL;:例:配置PA口为浮空输入Gpio_Pin = GPIO_Pin_All;:该参数设置了成员NVIC_IRQChannel 中的先占优先级,Table. 273 列举了该参数的取值。

NVIC_IRQChannelSubPriority该参数设置了成员NVIC_IRQChannel 中的从优先级,Table. 273 列举了该参数的取值。

Table. 273 给出了由函数NVIC_PriorityGroupConfig 设置的先占优先级和从优先级可取的值Table 273. 先占优先级和从优先级值~NVIC_IRQChannelCmd该参数指定了在成员NVIC_IRQChannel中定义的IRQ通道被使能还是失能。

这个参数取值为ENABLE或者DISABLE。

例:NVIC_InitTypeDef NVIC_InitStructure;/*设置优先级分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 选择外部中断线15-10中断*/= EXTI15_10_IRQChannel;^= 0;= 2;/*使能该通道*/= ENABLE;NVIC_InitStructure(&NVIC_InitStructure);与EXTI相关的函数例:选择PA13为中断的输入口GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource13);—EXTI_InitTypeDef structureEXTI_InitTypeDef定义于文件“”:typedef struct{ u32 EXTI_Line;EXTIMode_TypeDef EXTI_Mode;EXTIrigger_TypeDef EXTI_Trigger;FunctionalState EXTI_LineCmd; } EXTI_InitTypeDef;EXTI_Line给出了该参数可取的值EXTI_LineCmd用来定义选中线路的新状态。

STM32学习笔记——printf

STM32学习笔记——printf

STM32学习笔记——printfprintf复习当我们写printf("%d\n", 1);的时候,printf函数并不能通过C语⾔语法得知第⼆个参数是int类型。

printf是⼀个变参函数(variadic function):int printf(const char *restrict format, ...);参数的类型都是通过格式串format推导出的。

如果参数类型与格式串中指定的不匹配,或提供的参数数量少于需要的,将导致未定义⾏为。

由于参数类型是动态的,printf和scanf⽐静态类型的std::cout和std::cin慢,前提是后者的众多overhead被⼿动消除。

C为可变参数提供了va_start、va_arg、va_copy、va_end、va_list等⼯具,定义在头⽂件<stdarg.h>中。

va_arg⽤于取出参数,va_copy⽤于拷贝参数供多次使⽤。

引⽤上的例⼦:#include <stdio.h>#include <stdarg.h>#include <math.h>double sample_stddev(int count, ...){/* Compute the mean with args1. */double sum = 0;va_list args1;va_start(args1, count);va_list args2;va_copy(args2, args1); /* copy va_list object */for (int i = 0; i < count; ++i) {double num = va_arg(args1, double);sum += num;}va_end(args1);double mean = sum / count;/* Compute standard deviation with args2 and mean. */double sum_sq_diff = 0;for (int i = 0; i < count; ++i) {double num = va_arg(args2, double);sum_sq_diff += (num-mean) * (num-mean);}va_end(args2);return sqrt(sum_sq_diff / count);}int main(void){printf("%f\n", sample_stddev(4, 25.0, 27.3, 26.9, 25.7));}<stdio.h>还定义了vprintf系列函数,与不带v的相⽐,可变参数...都换成了va_list的实例:int vprintf(const char *format, va_list vlist);可以借此实现⾃⼰的printf。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、GPIO函数:输出:HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);//此例以PA12口为例HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); //此例以PA12口为例HAL_GPIO_ TogglePin(GPIOA,GPIO_PIN_12); //此例以PA12口为例2、串口函数:1、串口发送/接收函数HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制HAL_UART_Receive();串口轮询模式接收,使用超时管理机制HAL_UART_Transmit_IT();串口中断模式发送HAL_UART_Receive_IT();串口中断模式接收HAL_UART_Transmit_DMA();串口DMA模式发送HAL_UART_Transmit_DMA();串口DMA模式接收2、串口中断函数HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用HAL_UART_TxCpltCallback();数据完全发送完成后调用HAL_UART_RxHalfCpltCallback();一半数据接收完成时调用HAL_UART_RxCpltCallback();数据完全接受完成后调用HAL_UART_ErrorCallback();传输出现错误时调用例程:串口接收中断uint8_t aTxStartMessages[] = "\r\n******UART commucition using IT******\r\nPlease enter 10 characters:\r\n";uint8_t aRxBuffer[20];2、在main函数中添加两个语句通过串口中断发送aTxStartMessage数组的数据和接收数据10个字符,保存在数组aRxBuffer中HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)aTxStartMessages,sizeof(aTxStartMessages)); //sizeof()可读取目标长度HAL_UART_Receive_IT(&huart1,(uint8_t*)aRxBuffer,10);3、在main.c文件后面添加中断接收完成函数,将接收到的数据又通过串口发送回去。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){UNUSED(huart);HAL_UART_Transmit(&huart1,(uint8_t*)aRxBuffer,10,0xFFFF);//(uint8_t*)aRxBuffer为字符串地址,10为字符串长度,0xFFFF为超时时可以在中间加任何可执行代码。

}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // 串口接收中断{if(huart->Instance == USART1) // 判断是由哪个串口触发的中断 if(huart==&huart1){HAL_UART_Transmit(&huart1,aRxBuffer1,1,100); // 接收到数据马上使用串口1发送出去HAL_UART_Receive_IT(&huart1,aRxBuffer1,1); // 重新使能串口1接收中断}if(huart->Instance == USART2){HAL_UART_Transmit(&huart2,aRxBuffer2,1,100); // 接收到数据马上使用串口1发送出去HAL_UART_Receive_IT(&huart2,aRxBuffer2,1); // 重新使能串口2接收中断}}4、编译后下载至开发板,进行复位后通过串口监视器可看到串口发送的aTxStarMessages字符串,向串口发送10个字节的数据后可看到串口将所接收数据又发送回来(注意由于HAL_UART_Receive_IT()函数中的字节参数设置为了10,故只有发送10个字节的字符串才会被串口返回,且由于while循环中无语句,该程序只能执行一次)memcpy(txbuf,"将这里的数据拷到txbuf里\n",100);HAL_UART_Transmit(&huart1,txbuf,strlen((char *)txbuf),1000);//将txbuf里的内容通过串口发出。

HAL_UART_Transmit(&huart1,test_buf,10,1000); uint8_t test_buf[10];其中:&huart1为串口代号,txbufo为数据缓冲器,1000为发送时间HAL_UART_Transmit(&huart2,txData,sizeof(txData)-1,0xffff);HAL_UART_Receive_IT(&huart1,&aRxBuffer,10); //串口接收,并将接受的数据,放在aRxBuffer地址里。

/* Infinite loop *//* USER CODE BEGIN WHILE */memcpy(txbuf,"My name is Dr.Ark!\n",100);prinrf函数添加以下代码,在(main())之前。

int fgetc(FILE * f){uint8_t ch = 0;HAL_UART_Receive(&huart1,&ch, 1, 0xffff);return ch;}int fputc(int ch,FILE *f){uint8_t temp[1]={ch};HAL_UART_Transmit(&huart1,temp,1,2);return(ch);}例:printf("hello everyone!\r\n");printf("Hello Qi!\r\n");HAL_Delay(5000);关于Printf的使用说明1、printf("t=%d v",t);输出结果:t=?V(不换行)2、printf("t=%d v\ts=%fV\n",t,s);输出结果:t=?V s=V(换行)3、printf("t=%dv\t s=%.2fV\n",t,s);t=?V s=0.00V (换行)5、串口DMA测试CUBE的配置:HAL_UART_Receive_DMA(&huart1,aRxBuffer1,5);// 启动DMA接收HAL_UART_Transmit_DMA(&huart1,aTxBuffer,sizeof(aTxBuffer));// DMA发生数据void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){HAL_UART_Transmit_DMA(&huart1,aRxBuffer1,sizeof(aTxBuffer)); // DM2发送出去 HAL_UART_Receive_DMA(&huart1,aRxBuffer1,5); // 重新DMA接收}2、定时器基础定时器及通用定时器基本功能。

a、非阻塞模式下的定时器回调函数输入参数:htim 定时器名柄无返回值HAL_TIM_Base_Start_IT(&htim3);在中断模式下启动定时器。

否则不工作HAL_TIM_Base_Stop_IT(&htimx);关闭定时器。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){//if(htim==&htim4) ??static uint16_t timer_count =0;if (htim->Instance == htim4.Instance) //???????????{timer_count++;}}b、高级定时器的PWM发生器HAL_TIM_Base_Start_IT(&htimx);HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_3); 启动通道PWM输出。

HAL_TIM_PWM_Start_IT(&htimx,TIM_CHANNEL_3); 在中断模式下启动通道PWM输出。

HAL_TIM_PWM_Stop(&htimx,TIM_CHANNEL_3);HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_1);htimx.Instance->CCR3 = “比较寄存器值”; CCR3代表的是通道。

c、 pwm模式指令__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,1500); //设置PWM脉宽HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//关闭PWMHAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//开启PWMHAL_TIMEx_PWMN_Start(&htimx,TIM_CHANNEL_1); /* 启动定时器互补通道PWM输出*/D、PWM时间的配置E、PWM频率测量Cube设置并配置中断Keil定义全局变量:volatile static uint32_t tmp1 = 0;volatile static uint32_t tmp2 = 0;在主函数定义变量并开启定时器:uint32_t duty = 0;uint32_t freq = 0;HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);频率和占空比计算(在while(1))if(tmp1 == 0){duty = 0;freq = 0;}else{duty = tmp2 *100.f / tmp1 +0.5f;freq = 72000000.0f / tmp1;}void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){// static uint32_t tmp1 = 0,tmp2 = 0;if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){tmp1 = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);}else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){tmp2 = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);}}定时器设置:HSI频率是16Mhz,则单指令周期是1/16Mhz,预分频设置为1600,则每跑1600下,定时器加1,相当于定时器加1的时间是1600*(1/16Mhz)=100us,定义周期为10000,则计数到10000时候,定时器溢出,定时器溢出的时间为10000*100us=1s3、模数转换1、多通道ADC转换uint32_t ADC_Value[20];uint8_t i;uint32_t ad1,ad2;HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC_Value, 20);开启后,将采集到的数据存入数组ADC_Value。

相关文档
最新文档