赞
踩
先来看看程序运行的结果吧:
接下来就不说废话了,自己看源代码吧!每一行我都做了注释:
首先是主函数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_ON
- Send_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_OFF
- Send_String("LED OFF"); //串口发送LED OFF,反馈控制者灯已经关闭
- }
- Rx_Flag=0; //接收到数据标志位置0,为下次接收字符串做准备
- }
- Delay_ms(1000); //延时50毫秒,不用那么快
- }
- }
接下来是LED.h文件:
- #ifndef __LED_H
- #define __LED_H
-
-
-
- void 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; //引脚5
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //频率50MHz
- GPIO_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_H
-
- extern 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 header
-
- char Rx_Data[100]; //创建接收字符串的变量能盛放100个字节,闲小可以扩大
- uint8_t Rx_Flag = 0; //创建接收到字符串的标志位。1表示接收到了字符串,0表示没有接收到字符串
-
-
- //串口初始化函数
- void Serial_Init(void)
- {
- //1:RCC
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开始串口1时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开启GPIOA的时钟
- //2:GPIO_init
- GPIO_InitTypeDef GPIO_InitStruct; //创建GPIO初始化的结构体
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO的模式为推挽输出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //GPIO的引脚9
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //GPIO的频率50MHz
- GPIO_Init(GPIOA, &GPIO_InitStruct); //GPIO初始化
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //GPIO的模式为上拉输入
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //GPIO引脚10
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //GPIO的频率50MHz
- GPIO_Init(GPIOA, &GPIO_InitStruct); //GPIO初始化
- //3:USART_Init
- USART_InitTypeDef USART_InitStruct; //创建串口初始化的结构体
- USART_InitStruct.USART_BaudRate = 9600; // 波特率为9600
- USART_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_Init
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC的分组选择2组
- NVIC_InitTypeDef NVIC_InitStruct; //NVIC初始化的结构体
- NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; //通道选择串口1
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //NVIC串口通道使能
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //NVIC抢占优先级:1
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //NVIC响应优先级:1
- NVIC_Init(&NVIC_InitStruct); //NVIC初始化
- //5:USART_Cmd
- USART_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灯的亮灭了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。