stm32f103入门第四天
中断
优先级 = 抢占优先级(中断嵌套) + 子优先级(响应顺序)
例如
中断1:抢占优先级1 子优先级1
中断2:抢占优先级0 子优先级0
中断3:抢占优先级1 子优先级0
中断4:抢占优先级1 子优先级1
- 如果中断1触发了,随后中断2也触发了,因为中断2抢占优先级高,所以中断1被中断了,优先运行中断2;
- 如果中断1触发看,随后中断3也触发了,但是抢占优先级是一样的,所以中断3要等待;
- 如果中断1和3同时触发,但是中断3的子优先级高,所以先运行中断3;
- 如果中断1和4同时触发,那就看中断向量表的顺序了。
GPIO中断
GPIO中断会经过EXTI处理,因为GPIO支持外部中断模式和事件控制模式
中断模式
外部电平变化时候,触发中断服务函数
当PA0作为中断的时候,最好不要将PB0也作为中断源
事件触发
外部电平变化时候,做ADC处理等
串口通信
并行传输/串行通信
并行通信一次可以传输多bit,串行通信一次只能传输1bit.
全双工 半双工 单工
全双工:手机对手机
半双工:对讲机
单工:信号塔和收音机
异步通信 同步通信
异步通信:双方提前协商节拍
同步通信:双方由外部时钟线调节数据收发节拍
通信电平
- 芯片之间通信只需要TTL电平:逻辑1:2.4~5 逻辑0:0 ~ 0.4
- RS232:逻辑1:-3~ -15V 逻辑0:3 ~ 15V
- RS422/485:逻辑1:两线差2~ 6V 逻辑0:两线差-2 ~ -6V
通信速率计算
USART_BRR寄存器使用高12位[15:4]存放整数部分,低4位[3:0]存放小数部分,小数部分每一位对应1/24=0.0625。
串口通信UART
Asynchronous:异步通信
Synchronous : 同步通信
Single Write:单通道 半双工
Multiprocessor Communication :处理器通信
IrDA:红外线
LIN:网络
SmartCard:智能卡
SmartCard with Card Clock:智能卡同步时钟
int fputc(int ch, FILE *f) //用于输入
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 10);
return ch;
}
int fgetc(FILE *f) //用于输出
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, (uint8_t*)&ch, 1, 10);
return (int)ch;
}
//*******************main 函数中的回显测试********************************
HAL_StatusTypeDef status = HAL_UART_Receive(&huart1, &chat_in, 1, 10);
if(status == HAL_OK)
HAL_UART_Transmit(&huart1, &chat_in, 1, 10);
与8266进行通信
实验需要开启中断功能。
实验目的:通过串口2发送AT指令给8266,串口2中断接收返回的数据,再通过串口1打印接收到的数据到电脑上。
开始使能才能触发事件中断。
HAL_UART_Init //初始化串口通信设置
HAL_GPIO_Init //初始化GPIO
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); //设置中断抢占
HAL_NVIC_EnableIRQ(USART2_IRQn); //使能中断
HAL_UART_Receive_IT//使用时候使能中断
__HAL_UART_ENABLE_IT//实际上调用这个
使用库函数比较地层的方式
- 串口初始化
MX_USART2_UART_Init()//main函数中调用此接口初始化串口
//实际上是调用:HAL_UART_Init()// 先初始化GPIO 再配置UART
- 中断使能
//在HAL_UART_Init()已经调用了HAL_UART_MspInit()
//在HAL_UART_MspInit中会初始化GPIO后就会设置uart中断配置
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);//设置抢占组和优先组
HAL_NVIC_EnableIRQ(USART2_IRQn);//使能中断
- 开启uart的RXEN中断使能
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
此函数被UART_Start_Receive_IT->HAL_UART_Receive_IT ,一定要运行此函数才能实现中断 或者直接运行 __HAL_UART_ENABLE_IT(,,,,)
- 中断接收
void USART2_IRQHandler(void)
{
if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE)) //__HAL_UART_GET_IT_SOURCE(&huart2,UART_IT_RXNE) != RESET
{
Uart2_rbuf[Number] = huart2.Instance->DR;//读取数据
Number++;
__HAL_UART_CLEAR_FLAG(&huart2 , UART_IT_RXNE);//清空中断标志位
}
}
- 打印内容
if(Number > 0)//main函数中添加即可
{
printf("recesive = %s\r\n" , Uart2_rbuf);
Number = 0;
}
实验结束