当前位置:   article > 正文

STM32通过串口发送指令控制LED灯亮灭OLED并显示命令

STM32通过串口发送指令控制LED灯亮灭OLED并显示命令

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

接下来就不说废话了,自己看源代码吧!每一行我都做了注释:

首先是主函数main.c文件:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Serial.h"
  4. #include "Delay.h"
  5. #include "String.h"
  6. #include "LED.h"
  7. int main(void)
  8. {
  9. OLED_Init(); //oled 屏幕初始化
  10. Serial_Init(); //串口初始化
  11. LED_Init(); //LED灯初始化
  12. while(1)
  13. {
  14. if(Rx_Flag) //如果接收到数据
  15. {
  16. if(strcmp(Rx_Data, "LED_ON") == 0) //如果接收到的数据是LED_ON
  17. {
  18. OLED_ShowString(1,1," "); //OLED显示16个空格,清屏
  19. LED_ON(); //执行开灯函数
  20. OLED_ShowString(1,1,Rx_Data); //OLED显示LED_ON
  21. Send_String("LED ON"); //串口发送LED ON,反馈控制者灯已经打开
  22. }
  23. else if(strcmp(Rx_Data, "LED_OFF") == 0) //如果接收到的数据是LED_OFF
  24. {
  25. OLED_ShowString(1,1," "); //OLED显示16个空格,清屏
  26. LED_OFF(); //执行关灯函数
  27. OLED_ShowString(1,1,Rx_Data); //OLED显示LED_OFF
  28. Send_String("LED OFF"); //串口发送LED OFF,反馈控制者灯已经关闭
  29. }
  30. Rx_Flag=0; //接收到数据标志位置0,为下次接收字符串做准备
  31. }
  32. Delay_ms(1000); //延时50毫秒,不用那么快
  33. }
  34. }

接下来是LED.h文件:

  1. #ifndef __LED_H
  2. #define __LED_H
  3. void LED_Init(void);
  4. void LED_ON(void);
  5. void LED_OFF(void);
  6. #endif

接下来是LED.c文件:

  1. #include "stm32f10x.h" // Device header
  2. // LED灯初始化函数
  3. void LED_Init(void)
  4. {
  5. GPIO_InitTypeDef GPIO_InitStruct; //创建GPIOA初始化的结构体
  6. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式
  7. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; //引脚5
  8. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //频率50MHz
  9. GPIO_Init(GPIOA, &GPIO_InitStruct); //GPIOA初始化
  10. GPIO_SetBits(GPIOA, GPIO_Pin_5); //引脚5设置高电平,防止LED灯初始化后亮
  11. }
  12. // 打开LED灯的函数
  13. void LED_ON(void)
  14. {
  15. GPIO_ResetBits(GPIOA, GPIO_Pin_5); //引脚5置低电平
  16. }
  17. // 关闭LED灯的函数
  18. void LED_OFF(void)
  19. {
  20. GPIO_SetBits(GPIOA, GPIO_Pin_5); //引脚5置高电平
  21. }

记下来是串口相关的Serial.h文件:

  1. #ifndef __SERIAL_H
  2. #define __SERIAL_H
  3. extern char Rx_Data[];
  4. extern uint8_t Rx_Flag;
  5. void Serial_Init(void);
  6. void Send_Byte(uint8_t Byte);
  7. void Send_String(char *str);
  8. #endif

接下来就是最后一个serial.c文件了:

  1. #include "stm32f10x.h" // Device header
  2. char Rx_Data[100]; //创建接收字符串的变量能盛放100个字节,闲小可以扩大
  3. uint8_t Rx_Flag = 0; //创建接收到字符串的标志位。1表示接收到了字符串,0表示没有接收到字符串
  4. //串口初始化函数
  5. void Serial_Init(void)
  6. {
  7. //1:RCC
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开始串口1时钟
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开启GPIOA的时钟
  10. //2:GPIO_init
  11. GPIO_InitTypeDef GPIO_InitStruct; //创建GPIO初始化的结构体
  12. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO的模式为推挽输出
  13. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //GPIO的引脚9
  14. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //GPIO的频率50MHz
  15. GPIO_Init(GPIOA, &GPIO_InitStruct); //GPIO初始化
  16. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //GPIO的模式为上拉输入
  17. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //GPIO引脚10
  18. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //GPIO的频率50MHz
  19. GPIO_Init(GPIOA, &GPIO_InitStruct); //GPIO初始化
  20. //3:USART_Init
  21. USART_InitTypeDef USART_InitStruct; //创建串口初始化的结构体
  22. USART_InitStruct.USART_BaudRate = 9600; // 波特率为9600
  23. USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 没有硬件流控制
  24. USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 串口1的接收和发送模式
  25. USART_InitStruct.USART_Parity = USART_Parity_No; // 串口无校验
  26. USART_InitStruct.USART_StopBits = USART_StopBits_1; // 串口停止位1位
  27. USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 串口数据位长度:8位
  28. USART_Init(USART1, &USART_InitStruct); // 串口初始化
  29. //4:NVIC_Init
  30. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC的分组选择2组
  31. NVIC_InitTypeDef NVIC_InitStruct; //NVIC初始化的结构体
  32. NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; //通道选择串口1
  33. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //NVIC串口通道使能
  34. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //NVIC抢占优先级:1
  35. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //NVIC响应优先级:1
  36. NVIC_Init(&NVIC_InitStruct); //NVIC初始化
  37. //5:USART_Cmd
  38. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口1的接收数据中断
  39. USART_Cmd(USART1, ENABLE); //串口1使能
  40. }
  41. // 发送字节的函数(参数:8位的一个字节)
  42. void Send_Byte(uint8_t Byte)
  43. {
  44. USART_SendData(USART1, Byte); //发送1个字节
  45. while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成的标志位置1,是0时就等待
  46. USART_ClearFlag(USART1, USART_FLAG_TXE); //发送完成的标志位置0,为下次发送做准备
  47. }
  48. // 发送字符串函数(参数char类型的指针)
  49. void Send_String(char *str)
  50. {
  51. while(*str) //如果解引用指针内容不是0就循环
  52. {
  53. Send_Byte(*str); //发送字节当前指针所指向的内容
  54. str++; // 指针++,指向下一个字节的内容
  55. }
  56. }
  57. // 串口1中断函数
  58. void USART1_IRQHandler(void)
  59. {
  60. static uint8_t state =0; // 定义接收状态码
  61. static uint8_t i=0; //定义接收数组的下标
  62. uint8_t Dat; //定义每次进中断接收当前字节的变量
  63. if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) //如果接收标志置位了
  64. {
  65. Dat = USART_ReceiveData(USART1); // 变量接收当前收到的字节
  66. if(state == 0) // 如果状态码是0
  67. {
  68. if(Dat == '@') //如果收到的字节是@
  69. {
  70. state = 1; //状态码置1
  71. }
  72. }
  73. else if(state == 1) // 如果状态码是1
  74. {
  75. if(Dat == '$') //如果收到的字节是$
  76. {
  77. state = 2; //状态码置2
  78. }
  79. else //否则
  80. {
  81. Rx_Data[i]=Dat; //接收数组的第i个下标赋值为当前接收的字节
  82. i++; //下标++,移到数组下一个位置,准备下次接收
  83. }
  84. }
  85. else if(state == 2) // 如果状态码是2
  86. {
  87. if(Dat == '&') //如果收到的字节是&
  88. {
  89. state = 0; //状态码置0 结束这次的接收
  90. i = 0; //小标置0 这一串字符串接收完毕,下串从头覆盖
  91. }
  92. }
  93. }
  94. Rx_Flag = 1; // 接收标志位置1, 证明这段字符串接收完毕
  95. USART_ClearFlag(USART1, USART_FLAG_RXNE); // 清除接收标志位
  96. }

所有文件在工程中的目录为:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/330757
推荐阅读
相关标签
  

闽ICP备14008679号