STM32入门(12)

STM32入门(12)

项目一:串口发送数据

#include "stm32f10x.h"                    // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"


int main()
{
	
	// 模块初始化
	OLED_Init();          // OLED初始化
	
	Serial_Init();        // 串口初始化
	
	// 串口基本函数
	Serial_SendByte(0x41);				              // 串口发送一个字节数据0x41
	
	uint8_t MyArray[] = {0x42, 0x43, 0x44, 0x45};	  // 定义数组
	Serial_SendArray(MyArray, 4);		              // 串口发送一个数组
	
	Serial_SendString("\r\nNum1=");		              // 串口发送字符串
	
	Serial_SendNumber(111, 3);			              // 串口发送数字
	
	// 下述3种方法可实现printf的效果
	
	/*方法1:直接重定向printf,但printf函数只有一个,此方法不能在多处使用*/
	printf("\r\nNum2=%d", 222);		         //串口发送printf打印的格式化字符串
										     //需要重定向fputc函数,并在工程选项里勾选Use MicroLIB
	
	/*方法2:使用sprintf打印到字符数组,再用串口发送字符数组,此方法打印到字符数组,之后想怎么处理都可以,可在多处使用*/
	char String[100];					   //定义字符数组
	sprintf(String, "\r\nNum3=%d", 333);   //使用sprintf,把格式化字符串打印到字符数组
	Serial_SendString(String);			   //串口发送字符数组(字符串)
	
	/*方法3:将sprintf函数封装起来,实现专用的printf,此方法就是把方法2封装起来,更加简洁实用,可在多处使用*/
	Serial_Printf("\r\nNum4=%d", 444);	   //串口打印字符串,使用自己封装的函数实现printf的效果
	Serial_Printf("\r\n");
	
	while(1)
	{
		
	}
}
	
#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

/**
  * 函    数:串口初始化
  * 参    数:无
  * 返 回 值:无
  */
void Serial_Init(void)
{
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);    // 开启USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);     // 开启GPIOA的时钟
	
	// GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);                        // 将PA9引脚初始化为复用推挽输出
	
	// USART初始化
	USART_InitTypeDef USART_InitStructure;                       // 定义结构体变量
	USART_InitStructure.USART_BaudRate = 9600;                   // 波特率
	// 硬件流控制,不需要
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   
	USART_InitStructure.USART_Mode = USART_Mode_Tx;              // 模式,选择为发送模式       
	USART_InitStructure.USART_Parity = USART_Parity_No;			 // 奇偶校验,不需要
	USART_InitStructure.USART_StopBits = USART_StopBits_1;		 // 停止位,选择1位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 字长,选择8位
	USART_Init(USART1,&USART_InitStructure);					 // 将结构体变量交给USART_Init,配置USART1
	
	// USART使能
	USART_Cmd(USART1,ENABLE);
}

/**
  * 函    数:串口发送一个字节
  * 参    数:Byte 要发送的一个字节
  * 返 回 值:无
  */
void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1,Byte);         // 将字节数据写入数据寄存器,写入后USART自动生成时序波形
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);  // 等待发送完成
	/*下次写入数据寄存器后会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}

/**
  * 函    数:串口发送一个数组
  * 参    数:Array  要发送数组的首地址
  * 参    数:Length 要发送数组的长度
  * 返 回 值:无
  */
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{
	uint16_t i;
	for(i = 0;i < Length; i++)      // 遍历数组
	{
		Serial_SendByte(Array[i]);  // 依次调用Serial_SendByte发送每个字节数据
	}
}

/**
  * 函    数:串口发送一个字符串
  * 参    数:String 要发送字符串的首地址
  * 返 回 值:无
  */
void Serial_SendString(char *String)
{
	uint8_t i;
	for(i = 0;String[i] != '\0';i++)   // 遍历字符数组(字符串),遇到字符串结束标志位后停止
	{
		Serial_SendByte(String[i]);    // 依次调用Serial_SendByte发送每个字节数据
	}
}

/**
  * 函    数:次方函数(内部使用)
  * 返 回 值:返回值等于X的Y次方
  */
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{
	uint32_t Result = 1;      // 设置结果初值为1
	while(Y--)                // 执行Y次
	{
		Result *= X;          // 将X累乘到结果
	}
	return Result;
}

/**
  * 函    数:串口发送数字
  * 参    数:Number 要发送的数字,范围:0~4294967295
  * 参    数:Length 要发送数字的长度,范围:0~10
  * 返 回 值:无
  */
void Serial_SendNumber(uint32_t Number,uint8_t Length)
{
	uint8_t i;
	for(i = 0;i < Length;i ++)                // 根据数字长度遍历数字的每一位
	{
        // 依次调用Serial_SendByte发送每位数字
		Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + '0');   
	}
}

/**
  * 函    数:使用Printf需要重定向的底层函数
  * 参    数:保持原始格式即可,无需变动
  * 返 回 值:保持原始格式即可,无需变动
  */
int fputc(int ch, FILE *f)
{
	Serial_SendByte(ch);			//将printf的底层重定向到自己的发送字节函数
	return ch;
}

/**
  * 函    数:自己封装的Prinf函数
  * 参    数:format 格式化字符串
  * 参    数:... 可变的参数列表
  * 返 回 值:无
  */
void Serial_Printf(char *format, ...)
{
	char String[100];				   //定义字符数组
	va_list arg;					   //定义可变参数列表数据类型的变量arg
	va_start(arg, format);			   //从format开始,接收参数列表到arg变量
	vsprintf(String, format, arg);	   //使用vsprintf打印格式化字符串和参数列表到字符数组中
	va_end(arg);					   //结束变量arg
	Serial_SendString(String);		   //串口发送字符数组(字符串)
}


#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_Printf(char *format, ...);

#endif

posted @ 2026-03-17 22:43  Q&25  阅读(5)  评论(3)    收藏  举报