完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
实验平台:野火STM32F407ZGT6;
实验现象:利用板载复位按键实现每按一次在上位机上显示“a显示成功”; 代码借鉴:野火例程; 一、通信方式: 1.串并行传输方式:串行--数据按位发送,发送数据慢 并行--数据多位传输,发送速度快 2.数据传输方向: 单工--数据流单方向传输 半双工--数据流可以双方向,但是不能同时双方向,不能同时传输 全双工--数据流可以同时双方向传输 3.同步异步:同步--设备之间进行通讯时钟是同步的。 异步:设备之间有各自的工作时钟,通信时有其他约束方式,本实验的串口通讯的约束方式为波特率。 二、实验环节:USART通信--串行异步全双工 想要做成串口通讯实验需要了解物理层和协议层的协议标准,简单的说物理层就是硬件部分,物理接口,电气特性等。协议层主要规定的是通讯逻辑,双方的数据打包,解包标准,也就是软件部分。串口通讯遵循RS232标准及一种在低速率,近距离串行通讯的单端标准。 RS232的电气标准:电平逻辑为1时:-3V~-15V 电平逻辑为0时:+3V~+15V 协议层--配置:1-8-N-1格式协议(起始位-数据位-校验位-停止位) 起始位1位:空闲状态下--高电平(当改位变成低电平就有数据传输了)。数据位:配置为8位(注意高位先发)N:奇偶校验位占用1位可选择不用。一般配置为0。 三、软件编程。 软件编程部分是需要在有工程模板的前提下进行的,本文所用的工程模板为野火固件库版本。 第一步:在USER文件夹下创建usart子文件夹→创建usart.c、usart.h文件 第二步:进入工程编译文件确保文件无错误 第三步:程序部分 1.usart.c #include "usart.h"static void NVIC_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* 抢断优先级为1 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级为1 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */ NVIC_Init(&NVIC_InitStructure);}void UsartConfig(void)//串口初始化函数{ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;// 1.usart.c #include "usart.h" static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* 抢断优先级为1 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级为1 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */ NVIC_Init(&NVIC_InitStructure); } void UsartConfig(void)//串口初始化函数 { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; //第一步初始化GPIO RCC_AHB1PeriphClockCmd(DEBUG_USART_RX_GPIO_CLK|DEBUG_USART_TX_GPIO_CLK,ENABLE); /* GPIO初始化 */ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 配置Tx引脚为复用功能 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN ; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); /* 配置Rx引脚为复用功能 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); /* 连接 PXx 到 USARTx_Tx*/ GPIO_PinAFConfig(DEBUG_USART_RX_GPIO_PORT,DEBUG_USART_RX_SOURCE,DEBUG_USART_RX_AF);//具体复用成什么第二功能 /* 连接 PXx 到 USARTx__Rx*/ GPIO_PinAFConfig(DEBUG_USART_TX_GPIO_PORT,DEBUG_USART_TX_SOURCE,DEBUG_USART_TX_AF);//具体复用成什么第二功能 //第二步配置串口初始化结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&USART_InitStructure); //第三步配置串口接收中断 NVIC_Configuration(); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能串口中断 //第四步使能串口 USART_Cmd(USART1, ENABLE); } void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* 发送一个字节数据到USART */ USART_SendData(pUSARTx,ch); /* 等待发送数据寄存器为空 */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(USART1, (uint8_t) ch); /* 等待发送完毕 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } ///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { /* 等待串口输入数据 */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); } 2.usart.h #ifndef ___USART_H #define ___USART_H #include "stm32f4xx.h" #include void UsartConfig(void);//串口初始化函数 void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch); //引脚定义 /*******************************************************/ #define DEBUG_USART USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_BAUDRATE 115200 //串口波特率 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOA #define DEBUG_USART_RX_PIN GPIO_Pin_10 #define DEBUG_USART_RX_AF GPIO_AF_USART1 #define DEBUG_USART_RX_SOURCE GPIO_PinSource10 #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOA #define DEBUG_USART_TX_PIN GPIO_Pin_9 #define DEBUG_USART_TX_AF GPIO_AF_USART1 #define DEBUG_USART_TX_SOURCE GPIO_PinSource9 #define DEBUG_USART_IRQHandler USART1_IRQHandler #define DEBUG_USART_IRQ USART1_IRQn /************************************************************/ void Debug_USART_Config(void); void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch); void Usart_SendString( USART_TypeDef * pUSARTx, char *str); void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch); #endif /* __USART1_H */ 3.main.c #include "stm32f4xx.h" #include "usart.h" int main(void) { UsartConfig();//串口初始化函数 Usart_SendByte( USART1, 'a'); printf ("显示成功t"); while (1) { } } 四、总结 串口编程有以下几个步骤:1.初始化串口发送端和接收端GPIO 2.将发送和接收GPIO配置成复用输出推挽模式 3.将引脚映射到USART接收端与发送端 4.配置串口初始化结构体 5.配置串口接收中断 6.使能串口 7.编写发送函数 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3458 浏览 1 评论
9000 浏览 16 评论
4051 浏览 18 评论
1110浏览 3评论
572浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
569浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2302浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 18:47 , Processed in 1.205542 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号