最终效果
1 STM32通过串口打印基本信息
2 上位机通过串口向STM32发送控制指令,当发送A或C时LED点亮,当发送B或D时LED熄灭。
代码示例
usart.h
cpp
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h" // Device header
void USART1_Init(void);
void USART_Send1Byte(uint8_t Byte);
void USART_Send1String(char* str);
void USARTPrintf(USART_TypeDef *USARTx, char *fmt, ...);
#endif
usart.c
cpp
#include "usart.h"
#include <stdio.h>
#include <stdarg.h>
/**
函数名字:USART1_Init()
函数功能:串口初始化(配置GPIO USART NVIC)
**/
void USART1_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/*配置GPIO*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置USART*/
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200; //波特率
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);
USART_Cmd(USART1, ENABLE);//使能串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口中断
/*配置NVIC*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级
NVIC_Init(&NVIC_InitStructure);
}
/**
函数名字:USART_Send1Byte()
函数功能:发送一个字节
函数参数:Byte要发送的数据
**/
void USART_Send1Byte(uint8_t Byte)
{
USART_SendData(USART1, Byte);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); //等待传输完成
}
/**
函数名字:USART_Send1String()
函数功能:发送一个字符串
函数参数:str要发送的字符串
**/
void USART_Send1String(char* str)
{
if (str == NULL) return;
while(*str)
{
USART_Send1Byte((uint8_t) *str++);
}
}
/**
函数名字:USARTPrintf()
函数功能:发送一个字符串
函数参数:USARTx:USART1\2\3
函数参数:fmt格式化字符串
函数参数:...可变参数,对应fmt占位符
**/
void USARTPrintf(USART_TypeDef *USARTx, char *fmt, ...)
{
char buf[128];
va_list ap;
char *p;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
p = buf;
while(*p)
{
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); //等待发送数据寄存器为空可以进行发送
USART_SendData(USARTx, *p++);
}
}
/**
函数名字:USART1_IRQHandler()
函数功能:串口中断
**/
//void USART1_IRQHandler()
//{
// if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
// {
// uint8_t Data = USART_ReceiveData(USART1);
//
// USART_SendData(USART1, Data); //回显
//
// while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
//
// USART_ClearITPendingBit(USART1, USART_IT_RXNE);
// }
//}
main.c
cpp
#include "stm32f10x.h" // Device header
#include "usart.h"
int main(void)
{
USART1_Init();
/*初始化LED*/
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //GPIO13,单片机自带LED
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// GPIO_SetBits(GPIOC, GPIO_Pin_13); //PC13高电平(LED熄灭)
GPIO_ResetBits(GPIOC, GPIO_Pin_13); //PC13低电平(LED点亮)
USARTPrintf(USART1, "A C ==> OFF-LED\r\nB D ==> ON-LED\r\n\n"); //串口格式化打印
USART_Send1Byte('A'); //串口发送一个字节
USART_Send1String(" C ==> OFF-LED\r\nB D ==> ON-LED\r\n"); //串口发送字符串
while (1)
{
}
}
/**
函数名字:USART1_IRQHandler()
函数功能:串口中断
**/
void USART1_IRQHandler()
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否发生了接收中断
{
uint8_t Data = USART_ReceiveData(USART1); //获取接收到的字符
USART_SendData(USART1, Data); //回显
switch(Data){
case 'A': case 'C': GPIO_ResetBits(GPIOC, GPIO_Pin_13); break;
case 'B': case 'D': GPIO_SetBits(GPIOC, GPIO_Pin_13); break;
default: break;
}
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); //等待发送完成(USART_FLAG_TC置1未发送完成)
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除了RXNE标志,可省略避免冗余
}
}
注:本篇文章以STM32F10xx系列为基础编写。
注:以上内容仅个人理解,不具备唯一性和绝对正确性,仅供参考。