HAL库学习¶
GPIO相关¶
常用功能¶
-
点亮LED
根据电路确定引脚->初始化系统时钟与GPIOx的时钟->初始化GPIOx->设置对应引脚的高低电平
设置GPIO的mode为GPIO_Mode_Out_PP
-
按键
根据电路确定引脚->初始化系统时钟与GPIOx的时钟->初始化GPIOx->读取电平
设置引脚为GPIO的输入模式,既不上拉也不下拉(其实是否上拉下拉并无影响)
GPIO类¶
-
GPIO_InitTypeDef
HAL库中GPOI的初始化类型
包括Pin,Mode,Pull,Speed
工作模式mode定义
注意,这里的定义的具体名字可能在不同的文档中不一样,需要查询,可能和HAL版本有关
在stm32f1xx_hal_gpio.h中有详细定义,如下:
#define GPIO_MODE_INPUT 0x00000000u /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP 0x00000001u /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD 0x00000011u /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP 0x00000002u /!< Alternate Function Push Pull Mode/
#define GPIO_MODE_AF_OD 0x00000012u /!< Alternate Function Open Drain Mode/
#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT/!< Alternate Function Input Mode/
#define GPIO_MODE_ANALOG 0x00000003u /!< Analog Mode/
#define GPIO_MODE_IT_RISING 0x10110000u /!< External Interrupt Mode with Rising edge trigger detection/
#define GPIO_MODE_IT_FALLING 0x10210000u /!< External Interrupt Mode with Falling edge trigger detection/
#define GPIO_MODE_IT_RISING_FALLING 0x10310000u /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
#define GPIO_MODE_EVT_RISING 0x10120000u /!< External Event Mode with Rising edge trigger detection/
#define GPIO_MODE_EVT_FALLING 0x10220000u /!< External Event Mode with Falling edge trigger detection/
#define GPIO_MODE_EVT_RISING_FALLING 0x10320000u /!< External Event Mode with Rising/Falling edge trigger detection/
GPIO函数¶
-
__HAL_RCC_GPIOx_CLK_ENABLE()
GPIOx的时钟使能信号,在使用该GPIO前一定要使能时钟
-
HAL_GPIO_Init(GPIOx, &GPIO_InitTypeDef);
初始化GPIOx
-
HAL_GPIO_WritePin(GPIOx,GPIO_Pin,a)
a可以为GPIO_PIN_RESET或GPIO_PIN_SET,表示把GPIOx的GPIO_Pin脚设置为0或1
-
TeHAL_GPIO_ReadPin(GPIOx,GPIO_Pin)st
读取GPIOx的GPIO_Pin脚的电平
1是高电平,0是低电平
时钟相关¶
RCC(复位和时钟控制器)的时钟部分¶
-
需要设置的内容有: 1.系统时钟SYSCLK
2.设置AHB分频因子(决定HCLK等于多少)
3.设置APB2分频因子(决定PCLK2等于多少)
4.设置APB1分频因子(决定PCLK1等于多少)
5.设置各个外设的分频因子
然后控制AHB、APB2和APB1这三条总线时钟的开启、控制每个外设的时钟的开启。
常用的设置为:PCLK2 = HCLK = SYSCLK=PLLCLK = 72M,PCLK1=HCLK/2 = 36M
-
MCO输出
可以将PA8(stm32f103中)引脚设置为MOC输出,然后可通过示波器查看其出书情况 函数
-
函数 HAL_Delay() 延时一段时间
中断相关¶
中断都定义在IRQn_Type结构体中
中断函数的定义位于stm32f1xx_it中
-
EXTI(外部中断/事件控制器)
EXIT0~EXIT15可用于GPIO,通过编程可将任意GPIO作为EXIT的输入源 举例EXIT0对应GPIOx的PIN0引脚
-
HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
第一个为中断号,也即IRQn_Type结构体中的某一个,第二个为抢占优先级0~3(越低优先级越高),第三个为响应优先级
-
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
使能IRQn中断
在startup中可以找到对应中断函数的名称(大概?????)
然后自己写中断函数,可以用define的方法给中断函数改个名字方便使用
\#define EXTI0_IRQHandler MYIT_Handler详细的情况用到EXTI中断的时候再配置
-
-
systick系统定时器
当其数值清0时会触发一次中断,也即每隔一段时间调用一次中断
因此可以设定其数值,然后触发的中断为修改某一变量的值,通过该变量的值即可判断调用了多少次中断函数,也即经过了多少个周期
D可以用于一些固定频率触发的时间
比如电机的恒定频率的控制上
通信¶
-
分类:
1.串行通讯与并行通讯
2.全双工、半双工及单工通讯
-
全双工:在同一时刻,两个设备之间可以同时收发数据
-
半双工:两个设备之间可以收发数据,但不能在同一时刻进行
-
单工:在任何时刻都只能进行一个方向的通讯,即一个固定为发送设备,另一个固定为接收设备
3.同步通讯与异步通讯
-
-
USART串口通信
有别于USART还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。
本身USART接口,在stm32f103xb.h中有定义
ADC相关¶
-
电压限制
ADC的输入范围为:[VREF- , VREF+],还受VDDA,VSSA影响
这些电压值是由硬件电路决定的
VREF-与VSSA会接地,VREF+与VDDA会接3.3V,所以范围是0~3.3V
-
通道
规则通道与注入通道
规则通道是最常用的一种,没有什么特别注意的地方
注入通道,类似于中断,有可能插入规则通道过程中进行转换,转换完成后再回到规则通道
-
转换顺序
规则通道的转换顺序由SQR3~SQR1决定
-
触发源
可以通过寄存器ADC_CR2来控制,写1开始,写0结束
还可以触发转换:内部定时器触发,外部IO触发
-
ADC时钟
由PCLK2经过分频产生,最大14M
分频因子由RCC时钟配置寄存器RCC_CFGR的位15:14 ADCPRE[1:0]设置,可以是2/4/6/8分频
-
中断相关
中断方式
-
使用方法
typedef struct { uint32_t Mode; // ADC 工作模式选择 一个ADC为独立模式 两个 // ADC为双模式,双模式下还有具体模式 FunctionalState ScanConvMode; // ADC 扫描(多通道)用ENABLE或者单次(单通道)模式选择DISABLE // FunctionalState ContinuousConvMode; // ADC 单次转换或者连续转换选择 uint32_t ExternalTrigConv; // ADC 转换触发信号选择 uint32_t DataAlign; // ADC 数据寄存器对齐格式 uint8_t NbrOfChannel; // ADC 采集通道数 }ADC_InitTypeDef;
其他¶
-
断言:
通过定义USE_FULL_ASSERT来判断是否使用断言#ifdef USE_FULL_ASSERT /** * @brief assert_param 宏用于函数的输入参数检查 * @param expr:若expr值为假,则调用assert_failed函数 * 报告文件名及错误行号 * 若expr值为真,则不执行操作 */ #define assert_param(expr) \((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* 错误输出函数 ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) #endif若使用,可以用以下函数来输出错误:
注释:void assert_failed(uint8_t \* file, uint32_t line) { printf(“/r/n 输入参数错误,错误文件名=%s,行号=%s”,file,line); }使用Doxygen注释规范
防止头文件重复包含
和C++中一样的方式使用