先来看看程序运行的结果吧:


接下来就不说废话了,自己看源代码吧!每一行我都做了注释:
首先是主函数main.c文件:
#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Serial.h"
#include "Delay.h"
#include "String.h"
#include "LED.h"int main(void)
{OLED_Init();       //oled  屏幕初始化Serial_Init();      //串口初始化LED_Init();        //LED灯初始化while(1){if(Rx_Flag)                                         //如果接收到数据{if(strcmp(Rx_Data, "LED_ON") == 0)                  //如果接收到的数据是LED_ON{OLED_ShowString(1,1,"                ");            //OLED显示16个空格,清屏LED_ON();                                           //执行开灯函数OLED_ShowString(1,1,Rx_Data);                       //OLED显示LED_ONSend_String("LED    ON");                           //串口发送LED    ON,反馈控制者灯已经打开}else if(strcmp(Rx_Data, "LED_OFF") == 0)            //如果接收到的数据是LED_OFF{OLED_ShowString(1,1,"                ");            //OLED显示16个空格,清屏LED_OFF();                                          //执行关灯函数OLED_ShowString(1,1,Rx_Data);                       //OLED显示LED_OFFSend_String("LED    OFF");                          //串口发送LED    OFF,反馈控制者灯已经关闭}Rx_Flag=0;                                      //接收到数据标志位置0,为下次接收字符串做准备}Delay_ms(1000);                                      //延时50毫秒,不用那么快}
}
接下来是LED.h文件:
#ifndef __LED_H
#define __LED_Hvoid LED_Init(void);
void LED_ON(void);
void LED_OFF(void);#endif
接下来是LED.c文件:
#include "stm32f10x.h"                  // Device header//  LED灯初始化函数
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;                 //创建GPIOA初始化的结构体GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;             //引脚5GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;     //频率50MHzGPIO_Init(GPIOA, &GPIO_InitStruct);                //GPIOA初始化GPIO_SetBits(GPIOA, GPIO_Pin_5);                   //引脚5设置高电平,防止LED灯初始化后亮
}// 打开LED灯的函数
void LED_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_5);  //引脚5置低电平
}// 关闭LED灯的函数
void LED_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_5);   //引脚5置高电平
}
记下来是串口相关的Serial.h文件:
#ifndef __SERIAL_H
#define __SERIAL_Hextern char Rx_Data[];
extern uint8_t Rx_Flag;void Serial_Init(void);
void Send_Byte(uint8_t Byte);
void Send_String(char *str);#endif
接下来就是最后一个serial.c文件了:
#include "stm32f10x.h"                  // Device headerchar Rx_Data[100];                 //创建接收字符串的变量能盛放100个字节,闲小可以扩大
uint8_t Rx_Flag = 0;               //创建接收到字符串的标志位。1表示接收到了字符串,0表示没有接收到字符串//串口初始化函数
void Serial_Init(void)
{//1:RCCRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //开始串口1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 开启GPIOA的时钟//2:GPIO_initGPIO_InitTypeDef GPIO_InitStruct;                        //创建GPIO初始化的结构体GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;             // GPIO的模式为推挽输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;                   //GPIO的引脚9GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHzGPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;               //GPIO的模式为上拉输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;                  //GPIO引脚10GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHzGPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化//3:USART_InitUSART_InitTypeDef USART_InitStruct;                                          //创建串口初始化的结构体USART_InitStruct.USART_BaudRate = 9600;                                      // 波特率为9600USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 没有硬件流控制USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 // 串口1的接收和发送模式USART_InitStruct.USART_Parity = USART_Parity_No;                             // 串口无校验USART_InitStruct.USART_StopBits = USART_StopBits_1;                          // 串口停止位1位USART_InitStruct.USART_WordLength = USART_WordLength_8b;                     // 串口数据位长度:8位USART_Init(USART1, &USART_InitStruct);                                       // 串口初始化//4:NVIC_InitNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //NVIC的分组选择2组                       NVIC_InitTypeDef NVIC_InitStruct;                      //NVIC初始化的结构体NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;          //通道选择串口1NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            //NVIC串口通道使能NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  //NVIC抢占优先级:1NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;          //NVIC响应优先级:1NVIC_Init(&NVIC_InitStruct);                            //NVIC初始化//5:USART_CmdUSART_ITConfig(USART1, USART_IT_RXNE, ENABLE);          //开启串口1的接收数据中断USART_Cmd(USART1, ENABLE);                           //串口1使能
}// 发送字节的函数(参数:8位的一个字节)
void Send_Byte(uint8_t Byte)
{USART_SendData(USART1, Byte);                                //发送1个字节while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);     //等待发送完成的标志位置1,是0时就等待USART_ClearFlag(USART1, USART_FLAG_TXE);                         //发送完成的标志位置0,为下次发送做准备
}// 发送字符串函数(参数char类型的指针)
void Send_String(char *str)
{ while(*str)         //如果解引用指针内容不是0就循环{Send_Byte(*str);      //发送字节当前指针所指向的内容str++;                // 指针++,指向下一个字节的内容}
}// 串口1中断函数
void USART1_IRQHandler(void)
{static uint8_t state =0;        // 定义接收状态码static uint8_t i=0;                 //定义接收数组的下标uint8_t Dat;                                    //定义每次进中断接收当前字节的变量if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))  //如果接收标志置位了{Dat = USART_ReceiveData(USART1);           // 变量接收当前收到的字节if(state == 0)                      // 如果状态码是0{if(Dat == '@')                            //如果收到的字节是@{state = 1;                            //状态码置1}}else if(state == 1)             // 如果状态码是1{if(Dat == '$')                      //如果收到的字节是${state = 2;                            //状态码置2}else                       //否则{Rx_Data[i]=Dat;                 //接收数组的第i个下标赋值为当前接收的字节 i++;                            //下标++,移到数组下一个位置,准备下次接收}}else if(state == 2)          // 如果状态码是2{if(Dat == '&')                    //如果收到的字节是&{state = 0;                              //状态码置0   结束这次的接收i = 0;                                  //小标置0    这一串字符串接收完毕,下串从头覆盖}}}Rx_Flag = 1;                               // 接收标志位置1, 证明这段字符串接收完毕USART_ClearFlag(USART1, USART_FLAG_RXNE);  // 清除接收标志位}所有文件在工程中的目录为:

工程编译后下载到单片机就能实现串口控制LED灯的亮灭了。