完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32四个串口的使用方法
/=============================================================================== Copyright: Version: Author: Date: 2017/11/3 Description: 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串口发送出去 通过滴答定时器方式获取数据 revise Description: ===============================================================================/ #include “stm32f10x_usart.h” #include “stm32f10x.h” #define USART4_TIMEOUT_Setting 800 //(ms) u8 USART4_RX_BUF[250]; u16 USART4_RX_CNT=0; u16 USART2_RX_STA=0; //接收状态标记 void Systick_delay_init(u8 SYSCLK); u8 virtual_delay(u32 num,u8 unit); //通用异步收发器UART4 void UART4_Init(u32 bound) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //used for USART3 full remap//GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//for UART4//Configure RS485_TX_EN PINGPIO_InitStructure.GPIO_Pin = RS485_TX_EN_PIN; //PC9端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(RS485_TX_EN_PORT, &GPIO_InitStructure);RS485_TX_EN=0; //设置485默认为接收模式/* Configure USART Tx as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure USART Rx as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOC, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = bound;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(UART4, &USART_InitStructure);//USART_Init(USART3, &USART_InitStructure);/* Enable the USART */USART_Cmd(UART4, ENABLE);USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_ClearFlag(UART4,USART_FLAG_TC); } //USART1查询接收到的数据 //buf:接收缓存首地址 //len:读到的数据长度 void UART4_Receive_Data(u8 *buf) { u8 rxlen=21; u8 i=0; delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 RS485_RX_FLAG = 0;if((UART4_RX_BUF[0]==0x01)&&(UART4_RX_BUF[1]==0x03)){ for(i=0;i《rxlen;i++) { buf=UART4_RX_BUF; UART4_RX_BUF = 0; } RS485_RX_FLAG = 1;} UART4_RX_CNT=0; //清零 } //USART1发送len个字节。 //buf:发送区首地址 //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节) void UART4_Send_Data(u8 *buf,u16 len) { u16 t; RS485_TX_EN=1; //设置为发送模式 for(t=0;t《len;t++) //循环发送数据 { while(USART_GetFlagStatus(UART4,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(UART4,buf[t]); } while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET); RS485_TX_EN=0; //设置为接收模式 } void main(void) { Systick_delay_init(72); Usart4_Init(9600);//串口1波特率设置为9600 while(1) { if(USART2_RX_STA) { if(virtual_delay(USART4_TIMEOUT_Setting,MS))//超过800ms空闲则可以读取数据 { UART4_Send_Data(UART4_RX_BUF,UART4_RX_CNT); USART2_RX_STA=0; UART4_RX_CNT=0; } }} } void UART4_IRQHandler(void) //UART4 Receive Interrupt { u8 Res; if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(UART4);//(USART1-》DR); //读取接收到的数据 UART4_RX_BUF[UART4_RX_CNT&0XFF]=Res; //回传的数据存入数组,0X3F限制为64个数值 UART4_RX_CNT++; USART2_RX_STA=1; } if( USART_GetITStatus(UART4, USART_IT_TC) == SET ) { USART_ClearFlag(UART4, USART_FLAG_TC); } //溢出-如果发生溢出需要先读SR,再读DR寄存器则可清除不断入中断的问题 if(USART_GetFlagStatus(UART4,USART_FLAG_ORE) == SET){ USART_ReceiveData(UART4); USART_ClearFlag(UART4,USART_FLAG_ORE); } // USART_ITConfig(UART4, USART_IT_RXNE, DISABLE); //临时关闭接收中断 USART_ClearFlag(UART4,USART_IT_RXNE); //一定要清除接收中断 } //初始化延迟函数 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void Systick_delay_init(u8 SYSCLK) { SysTick-》CTRL&=0xfffffffb;//bit2清空,选择外部时钟 HCLK/8 // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 fac_us=SYSCLK/8; fac_ms=(u16)fac_us1000; } /=============================================================================== Author:peter pan Date: Description: 查询式分时或叫做轮询式(近似延时)。本函数是用于执行高效率场合的查询延时,但是一个for or while 循环中只能用一次。 revise Description: @ num : //分时查询的周期计数值 @ unit : //分时查询的周期单位 @@ParaValue : MS //周期单位为MS毫秒级 US //周期单位为US微秒级 @ virtual_delay_status : //静态变量 @@ParaValue : SET //SYSTICK正在占用中,请勿用 RESET //SYSTICK空闲,可以使用 @ReValue : with zero mean Time non-arrive ,one representative Time arrived ,you can do task; ##example if(virtual_delay(1000,MS)) LedFlash(); //1000ms LED闪烁一下 =======================================================================*/ u8 virtual_delay(u32 num,u8 unit) { u32 temp; if(virtual_delay_statusRESET) // SYSTICK空闲,可以使用 { if(unitMS) { SysTick-》LOAD=(u32)numDelay_SYSCLK125;//时间加载(SysTick-》LOAD为24bit) SysTick-》VAL =0x00; //清空计数器 SysTick-》CTRL=0x01 ; //开始倒数 }else if(unitUS) { SysTick-》LOAD=num*Delay_SYSCLK/8; //时间加载 SysTick-》VAL=0x00; //清空计数器 SysTick-》CTRL=0x01 ; //开始倒数 } virtual_delay_status=SET; return 0; } else { //virtual_delay_status*SET SYSTICK被占用 temp=SysTick-》CTRL; if(!(temp&0x01&&!(temp&(1《《16))))//等待时间到达 { SysTick-》CTRL=0x00; //关闭计数器 SysTick-》VAL =0X00; //清空计数器 virtual_delay_status=RESET; return 1; }else return 0; } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1584 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1526 浏览 1 评论
958 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
672 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1567 浏览 2 评论
1852浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
622浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
508浏览 3评论
517浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
494浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-15 11:57 , Processed in 0.744168 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号