STM32 F10x USART串口通信详解

产品功能

某外部设备实时发送串口数据, 本核心板通过串口1接收串口数据,并从串口数据中提取出数值信息,该数值信息与某设定值比较,其真假值驱动LED发出不同的状态(真:绿光,假:红光且闪烁)。

硬件结构

串口1的端口为PA9(TXD)和PA10(RXD),LED为共阳极的4脚LED,可以输出红,绿,蓝三色光。红光引脚接PB12,绿光引脚接PB13,阳极接5V DC,LED回路需串接欧姆电阻。在这里插入图片描述

软件程序 :

在工程模板下另外创建如下文件:

  1. uart.c
  2. uart.h
  3. led.c
  4. led.h

文件:uart.c

#include "uart.h"	

//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{ 	
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
	USART1->DR = (u8) ch;      
	return ch;
}

 

  	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	

//初始化IO 串口1 
//bound:波特率
void uart_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
	
	//配置GPIO的模式和IO口 
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX //串口输出PA9 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出 
	GPIO_Init(GPIOA, &GPIO_InitStructure); 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX //串口输入PA10
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入	  
	GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIO 


	//USART1 初始化设置
	USART_InitStructure.USART_BaudRate = bound;											//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;							//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_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;						//收发模式
	USART_Init(USART1, &USART_InitStructure); 											//初始化串口1

	USART_Cmd(USART1, ENABLE);	  														//使能串口1 

	USART_ClearFlag(USART1, USART_FLAG_TC);

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);										//开启串口接收中断

	//USART1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;              						//串口1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;								//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;									//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;										//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);														//根据指定的参数初始化VIC寄存器、
}


void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾!!!)
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成(这是定义的一个变量不是什么寄存器!)
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
  } 

} 

文件:uart.h

#ifndef __UART_H__
#define __UART_H_

#include "stm32f10x.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "stdio.h"	

#define USART1_REC_LEN  	200  	//定义USART1最大接收字节数
	  	
extern u8  USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符  
extern u16 USART1_RX_STA;         		//接收状态标记	
//函数声明
void uart_init(u32 bound);//串口1初始化并启动

#endif

文件:main.c

#include "stm32f10x.h"
#include "uart.h"

int main()
{	
	u8 t;
	u8 len;	
	u16 times=0;  
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2: 2位抢占优先级,2位响应优先级
	uart_init(115200);
	
	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}
		else
		{
			times++;
			if(times%5000==0)
			{
				printf("请输入数据\r\n\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  		 				   
	}
}

led.c

#include"stm32f10x.h"



led.h

#ifndef __LED_H__
#define __LED_H_

void led(void);

#endif

未完待续。。。。。。。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值