STM32F10X USART 中断接受+发送,测试无误
来源:互联网 发布:2016淘宝怎么刷 编辑:程序博客网 时间:2024/06/09 16:50
硬件平台:STM32F10X USART模块 + JLink+USB转TTL小板
软件平台:Keil 4
前一个程序只是作为下位机的MCU将数据发送给串口助手,也就是上位机,相当于单工通信,对于一个完整的通信来说只是完成了一半的功能。
这是一个完整的通信例程,作为下位机的单片机可以将数据发送给上位机,也可以检测上位机是否发了数据回来。中断方式检测,如果接收到数据,则将数据发送给上位机,相当于半双工模式。
其实与基础的51串口通信无实质区别,只是STM32相关寄存器配置稍微复杂些而已。相比于前一个发送程序,只是在中断检测和主函数里做了相应的修改而已,RCC模块、USART模块与GPIO模块配置基本没变。
二、发送程序例程
程序涉及的模块有:
RCC:复位及时钟控制模块,用于初始化STM32 USART外设时钟及IO口复用时钟;
USART:通用同步异步收发器,即串口,用于发送数据至上位机显示已发送的数据;
GPIO:通用输入输出口复用配置模块。
1、RCC(复位和时钟控制 RESET CLOCK Controller)配置:常规时钟配置+USART相对应的IO口时钟+USART时钟 + 管脚功能复用时钟
2、GPIO(通用输出输入口)配置 AFIO 复用...:发送端推挽输出,接收端浮空输入
3、USART配置:通用同步异步收发器:8bits一帧,通过缓存区交换
4、NVIC配置(Nest Vector Interrupt Controller):嵌入中断向量控制器
中断响应
中断优先级:优先级编号小者优先级高
查询优先级+执行优先级
多个中断挂起时,执行优先级高者先执行
若执行优先级同,先执行查询优先级高的,在中断向量表的位置决定
中断嵌套:优先级低着被打断,CPU先执行优先级高者
中断挂起:执行高的时候,低者来了,低者被挂起,等待执行
NVIC 管理中断优先级,256个中断分配优先级,次占优先级不会造成中断嵌套
5、发送接收数据
RCC
//RCC时钟配置 void RCC_cfg(void) { ErrorStatus HSEStartUpStatus; //定义错误状态变量 RCC_DeInit();////将RcC初始化,重新设置为默认值 RCC_HSEConfig(RCC_HSE_ON); //打开外部高速时钟晶振,使能HSE /*RCC_HSE_ON 开 _off 关 _bypass hse晶振被外部时钟旁路*/ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /*RCC_WaitForHSEStartUp()返回一个ErrorStatus枚举值, success好,error未好*/ if(HSEStartUpStatus == SUCCESS)//HES就绪 { RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB时钟(HCLK)=系统时钟 RCC_PCLK1Config(RCC_HCLK_Div2); //设置低速AHB时钟(APB1)为HCLK的2分频 RCC_PCLK2Config(RCC_HCLK_Div1); //设置高速AHB时钟(APB2)=HCLK时钟 FLASH_SetLatency(FLASH_Latency_2); //设置FLASH代码延时 //使能领取指缓存 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //设置PLL时钟源及倍频系数,为HSE的9倍频 8MHz * 9 = 72MHz /*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul) RCC_PLLSource_HSI_Div2 pll输入时钟=hsi/2; RCC_PLLSource_HSE_Div1 pll输入时钟 =hse RCC_PLLSource_HSE_Div2 pll输入时钟=hse/2 RCC_PLLMul_2 ------_16 pll输入时钟*2---16 pll输出时钟不得超过72MHZ*/ RCC_PLLCmd(ENABLE); //ENABLE / DISABLE while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待就绪 /*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG) 检查指定RCC标志位 返回SET OR RESET RCC_FLAG_HSIRDY HSI晶振就绪 RCC_FLAG_HSERDY RCC_FLAG_PLLRDY RCC_FLAG_LSERDY RCC_FLAG_LSIRDY.......*/ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置PLL为系统时钟源 /*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) 设置系统时钟 RCC_SYSCLKSource_HSI RCC_SYSCLKSource_HSE RCC_SYSCLKSource_PLLCLK 选HSI HSE PLL 作为系统时钟*/ while(RCC_GetSYSCLKSource() != 0x08); //判断PLL是否是系统时钟 /*u8 RCC_GetSYSCLKSource(void) 返回用作系统时钟的时钟源 0x00:HSI 0x04:HSE 0x08:PLL */ } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //打开GPIO时钟,复用功能,串口1的时钟 /*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState) enable 或 disable apb2 外设时钟 RCC_APB2Periph_AFIO 功能复用IO 时钟 RCC_APB2Periph_GPIOA/B/C/D/E GPIOA/B/C/D/E 时钟 RCC_APB2Periph_ADC1/ADC2ADC1/2 时钟 RCC_APB2Periph_TIM1 RCC_APB2Periph_SPI1 RCC_APB2Periph_USART1 RCC_APB2Periph_ALL全部APB2外设时钟*/ }
GPIO
//IO口配置 void GPIO_cfg(void) { GPIO_InitTypeDef GPIO_InitStructure; //GPIO_InitStructure初始化结构体为GPIO_InitTypeDef结构 //PA9作为US1的TX端,打开复用,负责发送数据 GPIO_StructInit(&GPIO_InitStructure); /*typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef;*/ //函数:指向结构GPIO_InitTypeDef的指针,待初始化 //GPIO_StructInit中的成员:GPIO_PIN/SPEED/MODE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //1、选中引脚GPIO_PIN_0--15 OR GPIO_PIN_ALL 选中全部管脚 //2、GPIO_SPEED:GPIO_SPEED_10MHz/_2MHz/_50MHz 最高输出速率 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /*Mode,工作状态:GPIO_MODE_AIN ----- 模拟输入 _IN_FLOATING ----- 浮空输入 _IPD ----- 上拉输出 _IPU ----- 上拉输入 _OUT_OD ----- 开漏输出 _OUT_PP ----- 推挽输出 _AF_OD ----- 复用开漏输出 _AF_PP ----- 复用推挽输出*/ GPIO_Init(GPIOB , &GPIO_InitStructure); //选择A,初始化 //PA10作为US1的RX端,负责接收数据 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //选择10脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //IO浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 //提示标示:LED显示串口正在发送数据/接收数据 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); }
USART
//串口初始化 void USART_cfg(void) { USART_InitTypeDef USART_InitStructure; USART_StructInit(&USART_InitStructure); //将结构体设置为缺省状态 /*USART_StructInit通用同步异步串行口初始结构成员: USART_BaudRate----9600,默认9600 IntegerDivider = ((APBClock) / (16 * (USART_InitStruct->USART_BaudRate))) FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 _WordLength 帧中传输的数据位----USART_WordLength_8b/_9b,字长宽8位 _StopBits 停止位 可为 USART_StopBits_1 ---帧结尾传输1个停止位 USART_StopBits_0.5 0.5个 USART_StopBits_2 USART_StopBits_1.5 _parity 奇偶模式 USART_Parity_No//奇偶失能,无奇偶 USART_Parity_even oumoshi USART_Parity_odd jimoshi 奇偶使能时,在数据的MSB位插入奇偶位,字长9位时的第九位,8位时的第八位 _HardwareFlowControl // _none,硬件流控制失能 _rts 发送请求rts使能 _cts 清除发送cts使能 _rts_cts rts and cts 使能*/ //波特率设置为115200 USART_InitStructure.USART_BaudRate = 115200; //一帧数据的宽度设置为8bits USART_InitStructure.USART_WordLength = USART_WordLength_8b; //在帧尾传输1个停止位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //奇偶检验失能模式,无奇偶校验位 USART_InitStructure.USART_Parity = USART_Parity_No; //发送/接收使能 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //硬件流控制失能 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //设置串口3 USART_Init(USART3, &USART_InitStructure); //打开串口3的中断响应函数 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); /*void USART_ITConfig(USART_TypeDef* USARTx, u16 USART_IT, FunctionalState NewState) 失能或使能相应的USART中断,x---1/2/3 _IT : _IT_PE 奇偶错误中断 _IT_TXE FASONG中断 _IT_TC 传输完成中断 _IT_RXNE 接收中断 _IT_IDLE 空闲总线中断 _IT_LBD LIN中断检测中断 _IT_CTS CTS中断 _IT_ERR 错误中断*/ USART_Cmd(USART3, ENABLE); /*void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) 失能或使能外设 x--1/2/3 NewState: USARTx ENABLE /DISABLE*/ }NVIC
//配置中断 void NVIC_cfg(void) { NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC初始化结构体 NVIC_InitStructure NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /*优先级分组:先占优先级与从优先级,只可设置一次 NVIC_PriorityGroup_0 先0位从4位 0 0--15 NVIC_IRQChannelPreemptionPriority 对中断通道设置不产生影响 NVIC_PriorityGroup_1先1位从3位0-1 0--7 NVIC_IRQChannelSubPriority 不影响中断 NVIC_PriorityGroup_2先2从20-3 0-3 NVIC_PriorityGroup_3先3从10-7 0-1 NVIC_PriorityGroup_4先4从00-15 0 选择中断优先级分组2*/ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //UA=SART1 全局中断 //用3.5的库的时候,所有的USART1_IRQChannel全部换成USART1_IRQn;!!!!! /*typedef struct { u8 NVIC_IRQChannel; //enable/disable 相应的IRQ通道,3.5库的时候,IRQChannel全部换成IRQn u8 NVIC_IRQChannelPreemptionPriority;//成员 NVIC_IRQChannel先占优先级 u8 NVIC_IRQChannelSubPriority; //成员 NVIC_IRQChannel从占优先级 FunctionalState NVIC_IRQChannelCmd; //成员 NVIC_IRQChannel 使能还是失能 } NVIC_InitTypeDef;*/ //选择串口1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式,先占 中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式,从 中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断 NVIC_Init(&NVIC_InitStructure); } #include "stm32f10x_it.h" extern FlagStatus RX_status; extern char urt_flag; void USART3_IRQHandler(void) { GPIO_SetBits(GPIOA, GPIO_Pin_4); RX_status = USART_GetFlagStatus(USART3, USART_FLAG_RXNE); //确认是否收到数据 //USART_ClearFlag(USART3,USART_FLAG_TC);//清除usart1-3 待处理标志位 if(USART_GetITStatus(USART3,USART_IT_RXNE)==SET) //中断发生与否,接收中断 { USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除usart1-3的中断待处理位 urt_flag=1; } if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET) //溢出,若溢出,先读取SR,再读取 DR ,寄存器可清除不断入中断的问题 { USART_ClearFlag(USART3,USART_FLAG_ORE); //读取SR ,清除溢出错误标志位 USART_ReceiveData(USART3);//读取DR /*USART_SendData(USART3, USART_ReceiveData(USART3)); //将数据发送到上位机 while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); //等待数据发送完毕 //USART3_Puts("\r\n"); GPIO_ResetBits(GPIOA, GPIO_Pin_4); //发送完后亮灯*/ urt_flag=1; } }
欢迎讨论,共同学习
- STM32F10X USART 中断接受+发送,测试无误
- STM32F10X USART发送详解,测试无误
- STM32F10X CAN+TJA1050中断 接受例程详解,测试无误
- STM32F10X DMA发送例程详解,测试无误
- STM32F10X PWM配置例程详解,测试无误
- STM32 USART DMA发送 中断接收
- STM32F10x usart数据收发
- STM32F10x usart数据收发
- AVR USART(UART)发送中断程序 使用缓冲器
- STM32F10X CAN+TJA1050发送程序例程,已测试
- STM32F10x外部中断释疑
- STM32F10x的中断
- USART测试
- 第一个 node js http 发送post请求(测试无误)
- STM32 -USART中断方式
- STM32 -USART中断方式
- USART接收中断
- STM32使用串口中断发送和接受数据
- JetBrains注册码计算(IntelliJ IDEA 15.0注册码激活)
- 蓝桥杯 - Torry的困惑(基本型)
- 【JS】【笔记】JavaScript入门经典(第5版)第8章 JSON
- light1010 - Knights in Chessboard【找规律】
- 【JS】【笔记】JavaScript入门经典(第5版)第9章 响应事件
- STM32F10X USART 中断接受+发送,测试无误
- 自定义Dialog
- 【JS】【笔记】JavaScript入门经典(第5版)第10章 JavaScript和cookie
- java32.HTTP通信------使用Http的Get方式读取网络数据
- Linux内核调试工具: Crash - 编码要求
- D7100 调节白平衡
- 初识过滤器笔记
- Longest Increasing Path in a Matrix
- BestCoder Round #70 总结