完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
#include "sys.h"
#include "usart.h" #include "main.h" //如果使用ucos,则包括下面的头文件即可. #if SYSTEM_SUPPORT_OS #include "includes.h" //ucos 使用 #endif //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART1_RX_BUF[USART_RX_LEN]; //接收缓冲,最USART_RX_LEN个字节 u8 USART2_RX_BUF[USART_RX_LEN]; //接收缓冲,最USART_RX_LEN个字节 u8 USART1_TX_BUF[USART_TX_LEN]; //发送缓冲,最大USART_TX_LEN个字节 u8 USART2_TX_BUF[USART_TX_LEN]; //发送缓冲,最大USART_TX_LEN个字节 u8 USART1_RX_STA; //接收完成状态标记 u8 USART2_RX_STA; //接收完成状态标记 u8 USART3_RX_STA; //接收完成状态标记 //u8 USART1_Count = 0; //USART1接收计数器 //u8 USART2_Count = 0; //USART2接收计数器 u8 TX1_cn,TX1_no,RX1_cn,RX_no; u8 TX2_cn,TX2_no,RX2_cn,RX2_no; u8 u8Uart2_FSM; void usart1_init(u32 baud) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // NVIC_InitTypeDef NVIC_InitStructure; /* 第1步:打开GPIO和USART部件的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /* 第2步:将USART Tx的GPIO配置为推挽复用模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第3步:将USART Rx的GPIO配置为浮空输入模式 由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的 但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第3步已经做了,因此这步可以不做 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; */ GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第4步:配置USART参数 - 波特率 = 115200 baud - 数据长度 = 8 Bits - 1个停止位 - 无校验 - 禁止硬件流控(即禁止RTS和CTS) - 使能接收和发送 */ USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // //Usart1 NVIC 配置 // NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1 // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 // NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 /* 第5步:使能 USART, 配置完毕 */ USART_Cmd(USART1, ENABLE); // CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去 // 如下语句解决第1个字节无法正确发送出去的问题: // 清发送完成标志,Transmission Complete flag USART_ClearFlag(USART1, USART_FLAG_TC); } /************************************************************************************************************************* * 函数 : void uart2_init(u32 baud) * 功能 : USART2做RS485接口使用, * 参数 : 输入的波特率 * 返回 : 无 * 依赖 : 底层库函数 * 作者 : li_qcxy@126.com * 时间 : 2016-12-9 * 最后修改时间 : * 说明 : PA1为接收发送使能脚 *************************************************************************************************************************/ void usart2_init(u32 baud) //485通信串口初始化 { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART2,GPIOA时钟 //USART2_TX GPIOA.2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2 //USART2_RX GPIOA.3初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3 //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3 //USART2_RX_EN 使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA1 EN_USART2_RX(); //接收模式 //Usart2 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = baud;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART2, &USART_InitStructure); //初始化串口2 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART2, ENABLE); //使能串口2 USART2 -> CR1 = USART2 -> CR1; } //获取USART2当前接收计数器值 u32 UARTx_GetRxCnt(void) { return TX2_no; } /************************************************************************************************************************* * 函数 : void USART1_IRQHandler(void) * 功能 : 采用缓冲区满标志位的方法判断数据接收完成 * 参数 : 无 * 返回 : 无 * 依赖 : 底层读写函数 * 作者 : li_qcxy@126.com * 时间 : 2016-12-8 * 最后修改时间 : * 说明 : *************************************************************************************************************************/ void USART1_IRQHandler(void) //串口1中断服务程序 { u8 Res; #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntEnter(); #endif if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART1); //读取接收到的数据 USART1_RX_BUF[TX2_no++]=Res; } else if(TX2_no == USART_RX_LEN) //接收缓冲区接收满,即接收完成 { TX2_no = 0; USART1_RX_STA = 1; } #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntExit(); #endif } /************************************************************************************************************************* * 函数 : void USART2_IRQHandler(void) * 功能 : 采用空闲中断的方法判断数据接收完成 * 参数 : 无 * 返回 : 无 * 依赖 : 底层读写函数 * 作者 : li_qcxy@126.com * 时间 : 2016-12-8 * 最后修改时间 : * 说明 : *************************************************************************************************************************/ void USART3_IRQHandler(void) //串口2中断服务程序 { u8 Res; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART2);//(USART2->DR); //读取接收到的数据 USART2_RX_BUF[TX2_no++]=Res; } else if((USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)) //使用空闲中断判断接收不定长数据完成 { USART3_RX_STA = 1; //数据接收完成标志位 // } } /************************************************************************************************************************* * 函数 : void USART2_IRQHandler(void) * 功能 : 采用状态机的方法判断数据接收完成 * 参数 : 无 * 返回 : 无 * 依赖 : 底层读写函数 * 作者 : li_qcxy@126.com * 时间 : 2016-12-8 * 最后修改时间 : * 说明 : *************************************************************************************************************************/ void USART2_IRQHandler(void) { u8 u8Temp; /*****************发送中断************************************/ if (USART_GetITStatus(USART2, USART_IT_TC) == SET) { if(TX2_cn >= (TX2_no)) { EN_USART2_TX(); USART_ITConfig(USART2, USART_IT_TC, DISABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); u8Uart2_FSM = U_FSM_ADR; } else { u8Temp = USART2_TX_BUF[TX2_cn++]; USART2->DR = (u16)u8Temp; } } /******************接收中断*************************************/ if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) { u8Temp = (u8)USART2->DR; switch(u8Uart2_FSM) { case U_FSM_ADR: { if(u8Temp == local_info.id) //本地地址 { USART2_RX_BUF[0] = u8Temp; u8Uart2_FSM = U_FSM_FUN; } break; } case U_FSM_FUN: { if((u8Temp == 0x05)||(u8Temp == 0x01)||(u8Temp == 0x03)||(u8Temp == 0x04)) //本单元值接受0x05和0x01的指令,遥信和遥控 { USART2_RX_BUF[1] = u8Temp; u8Uart2_FSM = U_FSM_DATA; RX2_no = 8; RX2_cn = 2; } else if(u8Temp == 0x10) { USART2_RX_BUF[1] = u8Temp; u8Uart2_FSM = U_FSM_FUN16; // RX2_no = 15; RX2_cn = 2; } else { u8Uart2_FSM = U_FSM_ADR; } break; } case U_FSM_FUN16: { USART2_RX_BUF[RX2_cn++] = u8Temp; if(RX2_cn == 6) { USART2_RX_BUF[6] = u8Temp; u8Uart2_FSM = U_FSM_DATA16; RX2_cn = 7; RX2_no = 9 + USART2_RX_BUF[6]; } // else // { // USART2_RX_BUF[RX2_cn++] = u8Temp; // } break; } case U_FSM_DATA: { USART2_RX_BUF[RX2_cn++] = u8Temp; if(RX2_no <= RX2_cn) //数据接收完毕 { u8Uart2_FSM = U_FSM_ADR; USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); //一帧数据收完,不再接受数据 USART2_RX_STA = 1;//置一帧数据接收完标志 // GPIOA->ODR |= GPIO_Pin_8; // GPIO_SetBits(GPIOA,GPIO_Pin_11); } break; } case U_FSM_DATA16: { USART2_RX_BUF[RX2_cn++] = u8Temp; if(RX2_no <= RX2_cn) //数据接收完毕 { u8Uart2_FSM = U_FSM_ADR; USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); //一帧数据收完,不再接受数据 USART2_RX_STA = 1;//置一帧数据接收完标志 } break; } default:{u8Uart2_FSM = U_FSM_ADR; break;} } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1975 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1760 浏览 1 评论
1232 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
819 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1776 浏览 2 评论
2015浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
893浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
318浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
671浏览 3评论
662浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-24 06:47 , Processed in 0.764084 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191