3、USART实验

GPIO-USART⚡️

使用USART流程(例中使用串口1)🌘

方法一 printf 法📃

第一步 USART.h中设置

1️⃣:设置使用的串口,在头文件中将 #define USART_n USART1 中USART1的最后一个数改为要使用的串口号。

2️⃣:打开USART使能,打开需要使用的串口

#define EN_USART1 1 //使能(1)/禁止(0)串口1 #define EN_USART2 0 //使能(1)/禁止(0)串口2 #define EN_USART3 0 //使能(1)/禁止(0)串口3

USART.H事例:

#ifndef __USART_H
#define __USART_H

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

#define USART_n		USART1  //定义使用printf函数的串口,其他串口要使用USART_printf专用函数发送

#define USART1_REC_LEN  			200  	//定义USART1最大接收字节数
#define USART2_REC_LEN  			200  	//定义USART2最大接收字节数
#define USART3_REC_LEN  			200  	//定义USART3最大接收字节数

//不使用某个串口时要禁止此串口,以减少编译量
#define EN_USART1 			1		//使能(1)/禁止(0)串口1
#define EN_USART2 			0		//使能(1)/禁止(0)串口2
#define EN_USART3 			0		//使能(1)/禁止(0)串口3
	  	
extern u8  USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u8  USART2_RX_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u8  USART3_RX_BUF[USART3_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
 
extern u16 USART1_RX_STA;         		//接收状态标记	
extern u16 USART2_RX_STA;         		//接收状态标记	
extern u16 USART3_RX_STA;         		//接收状态标记	

//函数声明
void USART1_Init(u32 bound);//串口1初始化并启动
void USART2_Init(u32 bound);//串口2初始化并启动
void USART3_Init(u32 bound);//串口3初始化并启动
void USART1_printf(char* fmt,...); //串口1的专用printf函数
void USART2_printf(char* fmt,...); //串口2的专用printf函数
void USART3_printf(char* fmt,...); //串口3的专用printf函数

#endif
第二步 main.c 中调用函数

1️⃣:在最上方包含usart的头文件

​ #include “usart.h”

2️⃣:在USART头文件选择需要的串口初始化函数,拷贝到main.c中,并设置波特率(例如9600)

​ USART1_Init(9600);

3️⃣:接下来就可以自由自在的使用printf函数了😄

​ printf(“Hello World!”);

main.c事例

#include "stm32f10x.h"   
#include "stm32f10x_conf.h" 
#include "usart.h"
int main(void)
{
		USART1_Init(9600);
		USART1_printf("Hello World!");
    while(1);
}
printf的好处
1调用简单。
2发生数据方便。
3对C语言学习者友好
printf的缺点
  • 使用printf函数时只能由一个串口提供,也就是多个串口选择那一个用作printf,不能多个串口都使用printf函数

方法二 独立串口USART1_printf法📃

第一步 USART.h中设置

**打开USART使能,打开需要使用的串口 **

#define EN_USART1 1 //使能(1)/禁止(0)串口1 #define EN_USART2 0 //使能(1)/禁止(0)串口2 #define EN_USART3 0 //使能(1)/禁止(0)串口3

USART.H事例:

#ifndef __USART_H
#define __USART_H

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

#define USART_n		USART1  //定义使用printf函数的串口,其他串口要使用USART_printf专用函数发送

#define USART1_REC_LEN  			200  	//定义USART1最大接收字节数
#define USART2_REC_LEN  			200  	//定义USART2最大接收字节数
#define USART3_REC_LEN  			200  	//定义USART3最大接收字节数

//不使用某个串口时要禁止此串口,以减少编译量
#define EN_USART1 			1		//使能(1)/禁止(0)串口1
#define EN_USART2 			0		//使能(1)/禁止(0)串口2
#define EN_USART3 			0		//使能(1)/禁止(0)串口3
	  	
extern u8  USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u8  USART2_RX_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u8  USART3_RX_BUF[USART3_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
 
extern u16 USART1_RX_STA;         		//接收状态标记	
extern u16 USART2_RX_STA;         		//接收状态标记	
extern u16 USART3_RX_STA;         		//接收状态标记	

//函数声明
void USART1_Init(u32 bound);//串口1初始化并启动
void USART2_Init(u32 bound);//串口2初始化并启动
void USART3_Init(u32 bound);//串口3初始化并启动
void USART1_printf(char* fmt,...); //串口1的专用printf函数
void USART2_printf(char* fmt,...); //串口2的专用printf函数
void USART3_printf(char* fmt,...); //串口3的专用printf函数

#endif
第二步 main.c 中调用函数

1️⃣:在最上方包含usart的头文件

    #include "usart.h"

2️⃣:在USART头文件选择需要的串口初始化函数,拷贝到main.c中,并设置波特率(例如9600)

	USART1_Init(9600);

3️⃣:接下来就可以自由自在的使用printf函数了😄

​	USART1_printf("Hello World!");

main.c事例

#include "stm32f10x.h"   
#include "stm32f10x_conf.h" 
#include "usart.h"
int main(void)
{
		USART1_Init(9600);
		USART1_printf("Hello World!");
    while(1);
}
USART1_printf 的优点
  • 1、可以多个串口使用
    USART1_printf("wellcom !");
    USART2_printf("wellcom !");
    USART3_printf("wellcom !");
  • 2、用法与printf一致同样方便简介。

如何改写printf​ ​ 🗝

在C文件中添加下列代码


#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE {
	int handle; 
}; 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x){ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f){      
	while((USART_n->SR&0X40)==0)
	;//循环发送,直到发送完毕   
    USART_n->DR = (u8) ch;      
	return ch;
}

USART1_printf 的源码​ ​ 🗝


void USART1_printf(char *fmt, ...)
{
  static unsigned char Usartx_TxBuff[USART1_REC_LEN];
	unsigned int i, length;

	va_list ap; //va_list 可变参数列表,存参数地址

	va_start(ap, fmt); //获取可变参数地址 fmt地址赋给ap

	/*使用参数列表发送格式化输出到字符串,函数功能将可变参数格式化输出到一个字符数组*/
	vsprintf((char *)Usartx_TxBuff, fmt, ap); //fmt中内容赋给Usart3_TxBuff

	va_end(ap); //清空参数列表

	length = strlen((const char *)Usartx_TxBuff);
	while ((USART1->SR & 0X40) == 0)
		;
	for (i = 0; i < length; i++)
	{
		USART1->DR = Usartx_TxBuff[i];
		while ((USART1->SR & 0X40) == 0);
	}
}

串口的初始化函数 📃

 void USART1_Init(u32 bound){ //串口1初始化并启动

 {RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);GPIO_Init(GPIOA, &GPIO_InitStructure);USART_Init(USART1, &USART_InitStructure);NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//(选择串口,选择中断方式,使能中断)USART_Cmd(USART1, ENABLE);                    //使能串口 

 }

结束啦哈哈😃

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值