完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
点亮LED灯后,基本了解了GPIO口的使用,下面学通过查询方式运用USART1口收发数据。
首先总结全文,通过查询方式运用USART1口收发数据的主要步骤如下:
1.初始化GPIO口 通过查阅STM32数据手册可知,stm32f103c8 ,USART1的输入、输出引脚,分别为GPIOA端口的 Pin_10,Pin_9引脚,所以先定义GPIO结构体并赋值: void IO_Init() { GPIO_InitTypeDef Uart_A; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); Uart_A.GPIO_Pin = GPIO_Pin_9; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&Uart_A); Uart_A.GPIO_Pin = GPIO_Pin_10; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //stm32 data sheet page 110 GPIO_Init(GPIOA,&Uart_A); } 还和以前一样,先定义GPIO结构体变量,在使能GPIO外设时钟,紧接着分别对各个引脚的寄存器赋值并初始化。 这里需要注意引脚模式的选择:根据STM32参考手册,在全双工模式下,输出口的引脚(Pin_9)要配置为推挽复用输出,接收口的引脚(Pin_10)要配置为浮空输入或带上拉输入,刚开始学STM32不需要过深了解,只需要知道引脚要配置为相应模式即可。如想深究请查看STM32参考手册110页。 2,初始化串口 要初始化串口可以利用库函数中的串口结构体 USART_InitTypeDef,这样对于初学者来说方便易懂。 库函数中的结构体 USART_InitTypeDef为: typedef struct {//波特率 uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. The baud rate is computed using the following formula: - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */ //字长 uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. This parameter can be a value of @ref USART_Word_Length */ //停止位 uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. This parameter can be a value of @ref USART_Stop_Bits */ //是否奇偶校验 uint16_t USART_Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref USART_Parity @note When parity is enabled, the computed parity is inserted at the MSB position of the transmitted data (9th bit when the word length is set to 9 data bits; 8th bit when the word length is set to 8 data bits). */ //串口模式,收or发? uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. This parameter can be a value of @ref USART_Mode */ //是否使能硬件流,这个初学者暂时先放放,还用不到(博主现在是初学者) uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled or disabled. This parameter can be a value of @ref USART_Hardware_Flow_Control */ } USART_InitTypeDef; 知道了结构体,便可轻松理解下面的定义了。 USART_InitTypeDef Uart; 使能串口时钟后,依次对结构体中的变量赋值(注:STM32的每个外设都有其单独的时钟,只有使能了其时钟,外设才能开始工作)详细代码如下: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); Uart.USART_BaudRate = 115200;//波特率115200 Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流失能 Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置为 输出和输入模式 Uart.USART_Parity = USART_Parity_No;//不进行奇偶校验 Uart.USART_StopBits = USART_StopBits_1;//1个停止位 Uart.USART_WordLength = USART_WordLength_8b;//单次数据长读为8 USART_Init(USART1,&Uart);//初始化串口 在初始化串口后,按照STM32参考手册还需要对usart使能见下图: (注:博主当时在这里想到一个问题:STM32有多个串口,但是只有这一个串口使能位,也就是这么多串口公用一个使能位,那么,当使用多个串口工作,如果临时需要关闭一个串口,怎么办?答案见文章最下部分,答案1。) 由上图可知,在初始化串口完毕后,还需要使能串口: USART_Cmd(USART1,ENABLE); 然后根据参考手册: 此时还需要先清除状态寄存器USART_SR的发送完成(TC)位,要不然发送数据的第一个字节显示不出来。代码如下: SART_ClearFlag(USART1,USART_FLAG_TC); 到此,串口的初始化也就完成了。 3,编写发送函数 此处比较简单,先说代码: void sendByte(uchar character) { USART1->DR = character; while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } 需要发送时,直接把数据赋值给USART1的数据寄存器(USART_DR),即可通过串口发出,接下来需要等待数据发送完毕,当数据发送完毕后,USART的状态寄存器的发送寄存器空(TXE)位会置1,(RESET在库函数的宏定义为 0),即,若数据未发送完成,那么循环会一直空转,直到数据全部转到移位寄存器。 4.编写主函数 本文是通过运用查询方法来实现串口的发送。通过串口向电脑发送一个字符,串口之后会自动向电脑发送已发送字符的后9个。 先粘贴代码在解释: int main() { int count= -1; char temp= '0'; IO_Init(); Usart1_Init(); while(1){ if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))//判断是否接受到数据 { temp = USART1->DR;//若接收到数据,则将数据从数据寄存器取出 count = 10; } if(USART_GetFlagStatus(USART1,USART_FLAG_TC) && (count >=0))//判断能否发送数据 { while(count >0){ sendByte(temp++);//若能发送数据,则向接收端发送数据 count--;//连着发送10个字符 delay(1000);延时一秒 } if(count<0){ sendByte('r');//博主本来想在电脑接收端输出回车换行,但是一直接收不了,还没弄明白。 } } } } 解释见代码中的注释。 答案1:当不需要使用多个串口中的一个时,直接将对应串口外设的时钟失能就可以了。 通过查询方式实现串口收发数据完结。2018年3月20日 下一篇,通过中断来使用串口。 见STM32基础设计(3)---中断串口通信 本文的完整代码如下: #include #define uint unsigned int #define uchar unsigned char void delay(uint n) { int i,j; for(i=0;i } void IO_Init() { GPIO_InitTypeDef Uart_A; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); Uart_A.GPIO_Pin = GPIO_Pin_9; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&Uart_A); Uart_A.GPIO_Pin = GPIO_Pin_10; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110 GPIO_Init(GPIOA,&Uart_A); } void Usart1_Init() { USART_InitTypeDef Uart; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); Uart.USART_BaudRate = 115200; Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; Uart.USART_Parity = USART_Parity_No; Uart.USART_StopBits = USART_StopBits_1; Uart.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&Uart); USART_Cmd(USART1,ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC); //page 540 } void sendByte(uchar character) { USART1->DR = character; while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } int main() { int count= -1; char temp= '0'; IO_Init(); Usart1_Init(); while(1){ if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)) { temp = USART1->DR; count = 10; } if(USART_GetFlagStatus(USART1,USART_FLAG_TC) && (count >=0)) { while(count >0){ sendByte(temp++); count--; delay(1000); } if(count<0){ sendByte('r'); } } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 02:08 , Processed in 0.748847 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号