1.硬件设计流程
2.程序设计流程
1.串口初始化时钟使能:RCC_APBxPeriphClockCmd();
GPIO初始化时钟使能:RCC_AHBxPeriphClockCmd();
2.GPIO端口模式配置:GPIO_Init();
3.串口参数初始化:USART_Init();
4.串口使能:USART_Cmd();
5.重定向printf与scanf函数;
6.LED初始化:LED_Init();
初始化USART串口函数:
#include "Usart.h"void Usart_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;//打开串口GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//将USARTTx的GPIO配置为推挽复用模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);// 将 USART Rx 的 GPIO 配置为浮空输入模式GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);// 配置串口的工作参数// 配置波特率USART_InitStruct.USART_BaudRate = 115200;// 配置硬件流控制USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 配置工作模式,收发一起USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 配置校验位USART_InitStruct.USART_Parity = USART_Parity_No;// 配置停止位USART_InitStruct.USART_StopBits = USART_StopBits_1;// 配置 针数据字长USART_InitStruct.USART_WordLength = USART_WordLength_8b;// 完成串口的初始化配置USART_Init(USART1,&USART_InitStruct);// 使能串口USART_Cmd(USART1,ENABLE);
}
重定向c库函数printf到串口,重定向后可使用printf函数:
在进行重定向函数编写时首先需要完成如下两个操作:
(1)在MDK5界面中点击“”图标,将“USE MicroLIB”打上勾勾。
(2)在定义文件中需要包含 #include “stdio.h” 头文件。
int fputc(int ch , FILE *f)
{USART_SendData(USART1,(uint8_t) ch );while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//USART_FLAG_TXE:发送数据寄存器中的数据有没有被取走return (ch);
}
重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数:
int fgetc(FILE *f)
{while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//USART_FLAG_TXE:发送数据寄存器中的数据有没有被取走return (int)USART_ReceiveData(USART1);
}
重定向:
就是指重新定义C库函数。对于printf()函数而言,printf只是一个宏定义,实际上调用的是fputc()函数,为了能够使用printf()函数直接向串口发送数据,需要重定向fputc()函数。同理,重定向scanf()函数也是这个意思。
FILE *f是单片机函数重定向的固定用法,因为C语言和单片机对fputc(),fgetc()函数的定义是不同的,在C中,标准的参数为int xxx , FILE *x,如果没有FILE *x 这个指针变量,则无法实现重定向,因此这是一个固定用法。
在定义函数时,FILE *x 这个指针变量必须有,但是函数主体中可以不使用。
2. 初始化LED
#include "Led.h"void LED_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //开启时钟GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; //选用引脚5GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStruct);GPIO_SetBits(GPIOE,GPIO_Pin_5); //上电默认熄灭}void LED_ON()
{GPIO_ResetBits(GPIOE,GPIO_Pin_5); //灯亮
}void LED_OFF()
{GPIO_SetBits(GPIOE,GPIO_Pin_5); //灯灭
}
3. 主函数
#include "stm32f10x.h" // Device header
#include "Usart.h"
#include "Led.h"
#include "Delay.h"static void Show_Message(void); //函数声明int main(void)
{char ch = 0;/* 初始化 USART 配置模式为 115200 8-N-1,中断接收 */LED_Init();Usart_Init();Show_Message();while(1) { ch = getchar();if( ch != '\0'){Delay_ms(100);printf("接收到字符:%c\n",ch); }switch(ch){case '1': LED_ON();break; case '2':LED_OFF();break;default:Delay_ms (500);Show_Message();break; }}}static void Show_Message(void) //定义全局函数
{printf("\n 串口通讯控制实验: \n");printf("指令 ----------- LED亮灭\n");printf(" 1 ----------- LED1 ON \n");printf(" 2 ----------- LED1 OFF \n");
}