电平输出
HAL_GPIO_WritePin(端口号,引脚号,高低电平);
例子:
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
电平翻转
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
电平输入
HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8);
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13==GPIO_PIN_SET))
{
HAL_GPIO_TogglePin(GPIOB,PGIO_PIN_9);
}
中断系统
中断向量是一个中断地址 对应一个中断源的中断请求 理解为指针中放着一个中断服务函数
一个中断服务函数对应多个服务源 在入口地址判断来自哪个中断源
抢占优先级 响应优先级
NVIV 嵌套向量中断控制器
外部中断(EXTI) 中断请求来自于GPIO端口的引脚
16个中断源 EXTI0~EXTI15 分别对应七个中断向量 也就是对应着七个中断服务函数
EXTI0、EXTI1、EXTI2、EXTI3、TXTI4:专用
EXTI5~EXTI9:共用
EXTI10~EXTI15:共用
EXTI0->PA0~PG0
触发条件:上升沿 下降沿 双边沿
传统设计步骤
1将GPIO初始化为输入端口
2配置相关I/O引脚与中断线的映射关系
3设置该I/O引脚对应的中断触发条件
4配置NVIC,并使能中断
5编写中断服务函数
基于CubeMX的设计步骤
1指定引脚配置中断初始化参数
2重写该I/O引脚对应的中断回调函数
stm32|1xx_it.c 所有中断所在的文件
void EXTI15_10_IRQHandler(void){}
中断服务方法 HAL_GPIO_IRQHandler(GPIO_PIN_13)
清除中断标志 HAL_GPIO_EXTI_GLEAR_IT(GPIO_Pin)
中断回调函数 HAL_GPIO_EXTI_Callback(GPIO_Pin)
__weak 虚函数 重写虚函数
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_PIN==GPIO_PIN_13)
{
HAL_GPIO_*******
}
}
计时器基本原理
系统嘀嗒定时器 SysTick
集成在M3内核的计时器 用来给RTOS提供时钟节拍做时间基准
看门狗定时器 WatchDog
实时时钟RTC 用来计算时间
基本定时器 TIM6、TIM7
通用定时器 TIM2、TM3、TM4、TIM5
在基本定时器的基础上,实现输出比较、输入捕获、PWM生成、单脉冲模式输出等功能。
高级定时器 TIM1、TM8
通用计时器通过可编程预分频器驱动的16为自动重装主计数器构成
(prescaler+1)*(Counter Period)/定时器时钟频率=time
32MHZ 每隔500ms反转一次
32000*500/32000000=0.5s=500ms
500个1ms
定时器溢出回调函数
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)间隔时间回调函数
用户重写定时器溢出回调函数,实现具体的中断逻辑处理
if(htim->Instance==TIM2)
{
HAL_GPIO_......
}
stm32|1xx_it.c 定时器中断服务函数
HAL_TIM_IRQHandler(&himt);->
HAL_TIM_PeriodElapsedCallback(htim);->
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandlerTypeDef *htim)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
}
}
在main()函数中启动相应的定时器
stm32|1xx_hal_tim.c
HAL_TIM_Base_Start_IT(TIM_HandlerTypeDef *htim)开启了使能 可以进中断
HAL_TIM_Base_Start(TIM_HandlerTypeDef *htim)
在定时器初始化下面写 HAL_TIM_Base_Start_IT(&htim2);
串行接口相关知识点
并行通信与串行通信
单工、半双工、全双工
异步串行通信:通信双方在没有同步时钟的前提下,将一个字符(包括特定的附加位)按位进性传输的通信方式。
波特率:每秒钟传输的二进制位数,如9600bps.
TTL<--->RS232: MAX3232 SP3232
串口<---->USB接口:CH340 CP2012
对于日常编程而言 使用最多的还是异步串行通信
USATR1_TX与PA9复用,USART1_RX与PA10复用
HAL库中串口发送的重要函数
阻塞式发送函数
HAL_Status TypeDef HAL_UART_Transmit(UART_Handle TypeDef *huart,uint8_t *pData,uint16_t Size,uint32_t Timeout);
非阻塞式发送函数
HAL_Status TypeDef HAL_UART_Transmit——IT(UART_Handle TypeDef *huart,uint8_t *pData,uint16_t Size);
发送完毕中断回调函数
void HAL_UART_TxCpltCallback(UART_Handle TypeDef *huart);
非阻塞式
HAL_UART_Transmit_IT(&huart,&dat_Txd,5);
void HAL_UART_TxCpltCallback(UART_Handle TypeDef *huart)
{
if(huart->Instance==USART1)
{
HAL_GPIO_TogglePin();
if(dat_Rxd==0x5A)
{
HAL_GPIO_********
}
}
}
阻塞式
HAL_UART_Transmit(&huart1,dat_Txd,5,10000);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
定时器usart.c文件
UART_HandleTypeDef huart1; 定义 huart1
void MX_USART1_UART_Init(void) 定义usart1结构体
\r 回车 \n换行
接收
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
+
回调函数
void HAL_UART_RxCpltCallback(UART_HandleTyoeDef *huart)
{
if(huart->Instance==UART1)
{
if(Rx_dat==0xa1)
{
HAL_UART_Transmis(&huart1,Tx_str2,sizeof(Tx_str2),10000);
HAL_GPIO_****
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
if(Rx_dat==0xa2)
{
HAL_UART_Transmis(&huart1,Tx_str3,sizeof(Tx_str3),10000);
HAL_GPIO_****
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
}
}
ADC基本工作原理
各个通道的A/D转换可以单词、连续、扫描、或间断模式执行。
按照A/D转换的组织形式来划分,ADC的模式输入通道分为规则组和注入组两种。
ADC可以对一组最多16个通道按照指定的顺序逐个进行转换,这组指定的通道被称为规则组
在实际应用中,可能需要中断规则组的转换,临时对某些通道进行转换,好像这些通道注入了原来的规则组,故称组入组,最多由4个通道组成。
A/D转换结果有两种储存方式:左对齐、右对齐。
查询方式,阻塞式的A/D转换
uint16_t ADC_Value = 0;
HAL_ADC_Start(&hadc);
if(HAL_OK==HAL_ADC_PollForConversion(&hadc,10))
{
ADC0_Value=HAL_ADC_GetValue(&hadc);
}
中断方式,非阻塞式的A/D转换
uint16_t ADC_Value=0;
HAL_ADC_Start_IT(&hadc);
void HAL_ADC_ConvCpltCallback(ADC_Handle TypeDef* hadc1)
{
ADC0_Value=HAL_ADC_GetValue(&hadc);
}
void UR1_Send_Info()
{
sprintf((char *)str_buff,"采样值:%d,电压值:%d.%d%dv\r\n",ADC_Value,ADC_Volt/100,ADC_Volt%100/10,ADC_Volt%10);//数据格式化
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);//send
}
void ADC_Get_Value()
{
HAL_ADC_Start(&hadc1);//开启间断模式,每次需要先使用HAL_ADC_Start()开启转换
LED1_ON();
if(HAL_ADC_PollForConversion(&hadc1,10)== HAL_OK)//明转换完成
{
ADC_Value=HAL_ADC_GetValue(&hadc1);//读取ADC原始值
ADC_Volt=ADC_Value *330/4096;//3.3v/2^12
}
UR1_Send_Info();
LED1_OFF();
HAL_ADC_Stop(&hadc1);停止转换
}
中断
void UR1_Send_Info()//串口发送数据
{
sprintf((char *)str_buff,"采样值:%d,电压值:%d.%d%dv\r\n",ADC_Value,ADC_Volt/100,ADC_Volt%100/10,ADC_Volt%10);//数据格式化
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);//send
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1)
{
ADC_Value=HAL_ADC_GetValue(&hadc1);
ADC_Volt=ADC_Value *330/4096;
UR1_Send_Info();
LED1_ON();
}
}