1、功能引脚
TX:发送数据输出引脚。
RX:接收。
SW_RX:数据接收引脚,属于内部引脚。
nRTS:请求以发送,n表示低电平有效。如果使能 RTS 流控制,当USART接收器准备好接收新数据时就会将nRTS变成低电平;当接收寄存器已满时,nRTS将被设置为高电平。该引脚只适用于硬件流控制。
nCTS:清除以发送(Clear To Send),n表示低电平有效。如果使能 CTS流控制,发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。
USART:下图是STM32F103VET6芯片的USART引脚
串口设置的一般步骤可以总结为如下几个步骤:
1) 串口时钟使能,GPIO 时钟使能
2) 串口复位
3) GPIO 端口模式设置
4) 串口参数初始化
5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
6) 使能串口
7) 编写中断处理函数
以串口2通信为例:
1) 串口时钟使能,GPIO 时钟使能
2) 串口复位
3) GPIO 端口模式设置
4) 串口参数初始化
6) 使能串口
void USART2_Init(unsigned int bound)
{
GPIO_InitTypeDef GPIO_InitStructure; //引脚配置结构体
USART_InitTypeDef USART_InitStructure; //串口配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //配置串口2 (USART2) 时钟 GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//因为串口2 挂载在APB1上 注意其他串口在哪个APB上
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 串口2模式(USART2 mode)配置 */
USART_InitStructure.USART_BaudRate = bound; //一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长
USART_InitStructure.USART_StopBits = USART_StopBits_1; //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; // RX接收 TX发送模式
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启中断 接收中断
USART_Cmd(USART2, ENABLE); //使能串口
}
5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
}
7) 编写中断处理函数
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //检查是否发生中断
{
Rxflag=1;
ucTemp = USART_ReceiveData(USART2);
}
}
检测串口2中断标志位 看是否中断发生 如果发生将运行对应动作
对应测试程序:
usart.h
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include <stdio.h>
void USART2_Init(unsigned int bound);
void NVIC_Configuration(void);
void Usart_SendByte(uint8_t ch);
void Usart_SendString(uint8_t *str);
void Usart_SendStr_length(uint8_t *str,uint32_t strlen);
#endif
usart.c
#include "usart.h"
#include "misc.h"
void USART2_Init(unsigned int bound)
{
GPIO_InitTypeDef GPIO_InitStructure; //引脚配置结构体
USART_InitTypeDef USART_InitStructure; //串口配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //配置串口2 (USART2) 时钟 GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 串口2模式(USART2 mode)配置 */
USART_InitStructure.USART_BaudRate = bound; //一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长
USART_InitStructure.USART_StopBits = USART_StopBits_1; //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; // RX接收 TX发送模式
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启中断 接收中断
USART_Cmd(USART2, ENABLE); //使能串口
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
}
void Usart_SendByte(uint8_t ch)
{
USART_SendData(USART2,ch); //发送一个字节数据到USART2
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); //等待发送完毕
}
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
Usart_SendByte(*(str + k));
k++;
} while(*(str + k)!='\0');
}
void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
unsigned int k=0;
do
{
Usart_SendByte(*(str + k));
k++;
} while(k < strlen);
}
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "motor.h"
#include "switch.h"
#include "usart.h"
#include <string.h>
uint8_t Rxflag=0;
uint8_t ucTemp;
int main(void)
{
uint8_t ucaRxBuf[256]; //命令长度
uint16_t usRxCount;
USART2_Init(9600); //串口初始化配置 波特率9600
NVIC_Configuration(); //中断初始化配置
delay_init(); //延时函数初始化
STEP_Init(); //电机引脚初始化
SWITCH_GPIO_Init(); //限位器引脚初始化
LOCATION_Init(); //镜片位置初始化(复位)
Usart_SendString("串口测试\n");
usRxCount = 0;
while(1)
{
// if(Rxflag)
// {
// if (usRxCount < sizeof(ucaRxBuf))
// {
// ucaRxBuf[usRxCount++] = ucTemp;
// }
// else
// {
// usRxCount = 0;
// }
if(ucTemp == '1')
{
Usart_SendStr_length("abcd",4);
usRxCount = 0;
delay_ms(1000);
ReverseMotor(LIFT_MOTOR,NEG_SWITCH);
ALLReset();
delay_ms(1000);
ForwardMotor(LIFT_MOTOR,LIFT_SWITCH);
ALLReset();
ucTemp = 0;
}
Rxflag=0;
// memset(ucTemp, 0, sizeof(ucTemp));
}
}
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //检查是否发生中断
{
Rxflag=1;
ucTemp = USART_ReceiveData(USART2);
}
}