实验平台:野火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;
//第一步初始化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 <stdio.h>
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.编写发送函数
|