- 开发板原理图
所需要的硬件设施和上一个实验(USART串口所需一致),使用的是串口1来实现通信。
2. 实现和步骤
串口的重定向的目的是为了方便更好的观测程序,因为printf的默认输出设备是显示器,所以要想printf输出的内容在串口上显示出来,就需要将printf函数进行重定向。
方法:
printf函数的内部会调用int fputc(int ch, FILE *p)函数
即要将fputc函数重定向到串口上。
实现:
实现很简单。之后便是主函数的编写,要打印我们建立的数据。
使用printf函数的话需要加入c语言的头文件
#include “stdio.h”
且需要点击魔术棒-----Target-----勾选上微库
3. 之后定义好数据过后,在主函数中像写C语言的输出语句,电脑连上开发板---打开串口调试助手---打开串口---勾选DTR之后再取消,稍等就可以看到我们的数据在串口调试助手中打开了。
实验现象
Usart.h文件
#ifndef _USART_H
#define _USART_H
#include "system.h"
#include "stdio.h"
void USART1_Init(u32 bound);
#define USART1_TX_PIN GPIO_Pin_9
#define USART1_RX_PIN GPIO_Pin_10
#define USART_GPIO GPIOA //USART1的有关的GPIO口
#define USART USART1
#endif
Usart.c文件
#include "Usart.h"
//时间:2020-1-15
//制作者:SaBo
//适用:STM32F103ZET6 (普中科技 PZ6800L)
//使用的串口是USART1串口进行通信
int fputc(int ch, FILE *p)
{
USART_SendData(USART,(u8)ch); //发送数据函数
//发送完成的标识
//发送完成的话,这个标识会被置为1,
//当返回值是1的时候,
//就会退出这个while循环表明我们的数据发送完成。
while(USART_GetFlagStatus(USART,USART_FLAG_TXE)!=SET);
return ch;
}
//串口的初始化函数,GPIO、NVIC、USART初始化的程序书写地方
void USART1_Init(u32 bound)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//GPIOA_PIN_9是输出数据的管脚,设置为复用输出模式
//TX
GPIO_InitStructure.GPIO_Pin=USART1_TX_PIN; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(USART_GPIO,&GPIO_InitStructure); /* 初始化GPIO */
//GPIOA_PIN_10是数据的接收管脚,设置为浮空输入模式
//RX
GPIO_InitStructure.GPIO_Pin=USART1_RX_PIN; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //设置浮空输入模式
GPIO_Init(USART_GPIO,&GPIO_InitStructure); /* 初始化GPIO */
//串口配置
USART_InitStructure.USART_BaudRate=bound; //波特率由参数设置
USART_InitStructure.USART_WordLength=USART_WordLength_8b; //八个字节长度
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(USART,&USART_InitStructure);
//使能串口
USART_Cmd(USART,ENABLE);
//清除标志位
USART_ClearFlag(USART, USART_FLAG_TC);//发送完成的标识清除,用于增加程序的健壮性
//使能中断
USART_ITConfig(USART, USART_IT_RXNE,ENABLE);
//设置优先级
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//中断服务函数
void USART1_IRQHandler()
{
u8 r;
//不等于0,就是接收到中断,执行服务函数
if(USART_GetITStatus(USART,USART_IT_RXNE)!=RESET)
{
//按字节接收
//接收数据函数
r=USART_ReceiveData(USART);
//r=r+r+r+r;
USART_SendData(USART,r); //发送数据函数
//发送完成的标识
while(USART_GetFlagStatus(USART,USART_FLAG_TC)!=SET);//发送完成的话,这个标识会被置为1,当返回值是1的时候,就会退出这个while循环表明我们的数据发送完成。
}
USART_ClearFlag(USART,USART_FLAG_TC);
}
main.c文件
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "pwm.h"
#include "Usart.h"
//时间:2020-1-15
//制作者:SaBo
//适用:STM32F103ZET6 (普中科技 PZ6800L)
/*********************************************
程序写好后,下载到开发板上,打开我们的串口调试助手,
设置波特率为9600,数据位8位,停止位1位
串口的调试助手会自动打印数据
led1的闪烁表明我们的程序是否正常在进行。(检测作用)
*********************************************/
//---------------------------------------
//名称:主函数
//适用:STM32F103ZET6 (普中科技 PZ6800L)
//日期:2020-1-15
//---------------------------------------
int main()
{
u8 i;
u16 data=1314;
float fdata=13.14;
char str[]="hello world!";
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
USART1_Init(9600);
while(1)
{
i++;
if(i%20 == 0)
{
led1=!led1;
printf("输出的整型数据data = %d\r\n",data);
printf("输出的浮点型型数据fdata = %.2f\r\n",fdata);
printf("输出的字符串数据str = %s\r\n",str);
}
delay_ms(10);
}
}