基于STM32(Freertos)&ESP01S的红外空调网络控制器 -STM32软件部分 ...

打印 上一主题 下一主题

主题 1379|帖子 1379|积分 4137

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1.概述
本文主要介绍控制器软件部分,包含Freertos系统初始化,STM32红外接收发射任务应用实现,加湿器模块控制实现、串口初始化及Freertos任务控制逻辑。
2.Freertos 初始化
2.1Freertos 配置
  1. #ifndef FREERTOS_CONFIG_H
  2. #define FREERTOS_CONFIG_H
  3. /*-----------------------------------------------------------
  4. * Application specific definitions.
  5. *
  6. * These definitions should be adjusted for your particular hardware and
  7. * application requirements.
  8. *
  9. * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
  10. * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
  11. *
  12. * See http://www.freertos.org/a00110.html
  13. *----------------------------------------------------------*/
  14. #define configUSE_PREEMPTION                1//设置抢占式调度器
  15. #define configUSE_IDLE_HOOK                        0//设置空闲任务钩子
  16. #define configUSE_TIME_SLICING  0//设置相同优先级任务被轮转执行
  17. #define configUSE_TICK_HOOK                        0//设置时间片钩子
  18. #define configUSE_TASK_NOTIFICATIONS 1
  19. #define configUSE_MUTEXES 1
  20. #define configPRIO_BITS    4
  21. #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   0x0F //四位,值越小优先级越高
  22. #define configCPU_CLOCK_HZ                        ( ( unsigned long ) 72000000 )        //CPU执行频率
  23. #define configTICK_RATE_HZ                        ( ( TickType_t ) 1000 )//节拍中断频率,每次中断会进行任务调度
  24. #define configMAX_PRIORITIES                ( 5 )//设置优先级范围:0·X-1数字越小优先级越低
  25. #define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 256 )//定义空闲任务使用的堆栈的大小
  26. #define configTOTAL_HEAP_SIZE                ( ( size_t ) ( 10 * 1024 ) )//
  27. #define configMAX_TASK_NAME_LEN                ( 16 )//定义任务名的长度限制
  28. #define configUSE_TRACE_FACILITY        0//启动可视化跟踪调试
  29. #define configUSE_16_BIT_TICKS                0
  30. #define configIDLE_SHOULD_YIELD                1
  31. /* Co-routine definitions. */
  32. #define configUSE_CO_ROUTINES                 0
  33. #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
  34. /* Set the following definitions to 1 to include the API function, or zero
  35. to exclude the API function. */
  36. #define INCLUDE_vTaskPrioritySet                1
  37. #define INCLUDE_uxTaskPriorityGet                1
  38. #define INCLUDE_vTaskDelete                                1
  39. #define INCLUDE_vTaskCleanUpResources        0
  40. #define INCLUDE_vTaskSuspend                        1
  41. #define INCLUDE_vTaskDelayUntil                        1
  42. #define INCLUDE_vTaskDelay                                1
  43. /* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
  44. (lowest) to 0 (1?) (highest). */
  45. //#define configKERNEL_INTERRUPT_PRIORITY                 255 //在port.c 中L37定义
  46. /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
  47. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
  48. #define configMAX_SYSCALL_INTERRUPT_PRIORITY         191 /* equivalent to 0xb0, or priority 11. */
  49. #define xPortPendSVHandler   PendSV_Handler
  50. #define xPortSysTickHandler  SysTick_Handler
  51. #define vPortSVCHandler      SVC_Handler
  52. /* This is the value being used as per the ST library which permits 16
  53. priority values, 0 to 15.  This must correspond to the
  54. configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
  55. NVIC value of 255. */
  56. //#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY        15                //数字越小优先级越高,这里高于"最低优先级15"都不可管理
  57. //即只可管理最低15优先级,其他都管不了,不合理我要改
  58. #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY          5                //数字越小优先级越高,这里高于5都不可管理,即数字小于5的都管不了
  59. #endif /* FREERTOS_CONFIG_H */
复制代码
2.2 系统初始化
此处是System.h的代码,主要界说全局变量及I2C的引脚宏界说
  1. #ifndef __system_H
  2. #define __system_H
  3. /*System Head doc*/
  4. #include "stm32f10x.h"                  // Device header
  5. #include "delay.h"
  6. #include <stdbool.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <stdbool.h>
  11. #include "usart.h"
  12. #include "iic.h"
  13. /*FreeRtos lib*/
  14. #include "FreeRTOS.h"
  15. #include "task.h"
  16. #include "semphr.h"
  17. typedef enum
  18. {
  19.                 State_OFF,
  20.                 State_Low,
  21.                 State_High,
  22. }RH_State;
  23. typedef enum {Auto,cold,DeHumi,Heat,SentWind}ConducterMode;
  24. //RH_State RH_app_Sta = State_OFF;
  25. typedef struct IR_S
  26. {
  27.         u8 IR_Sent_Data[3];//依次A B C,A固定0xB2,B的高3位控制风速,低5五位保留1,
  28.           //高3位101为自动风,本程序风速默认自动风
  29.         ConducterMode mode;
  30.         u8 temp;
  31. }IR_Sdate;
  32. typedef struct SystemData
  33. {
  34.            float curtemp;
  35.            float curhumid;
  36.            RH_State RH_Sta;
  37.            IR_Sdate IR_Sent_Data;
  38. }SysData;
  39. extern SysData SYS_Glabal_varible;
  40. extern IR_Sdate IR_SentData;
  41. #define SYSTEM_SUPPPORT_RTOS 1//FRTOS开关标准位
  42. /*  IIC_SCL时钟端口、引脚定义 */
  43. #define IIC_SCL_PORT                         GPIOB   
  44. #define IIC_SCL_PIN                         (GPIO_Pin_8)
  45. #define IIC_SCL_PORT_RCC                RCC_APB2Periph_GPIOB
  46. /*  IIC_SDA时钟端口、引脚定义 */
  47. #define IIC_SDA_PORT                         GPIOB  
  48. #define IIC_SDA_PIN                         (GPIO_Pin_9)
  49. #define IIC_SDA_PORT_RCC                RCC_APB2Periph_GPIOB
  50. #define ManualSetSYSCLK                72
  51. //#define IIC_SCL *((volatile unsigned long*)(0x42000000+((GPIOB_BASE+12)-0x40000000)*32+8*4))//写PB8
  52. //#define IIC_SDA *((volatile unsigned long*)(0x42000000+((GPIOB_BASE+12)-0x40000000)*32+9*4))//写PB9
  53. //#define PB10 *((volatile unsigned long*)(0x42000000+((GPIOB_BASE+12)-0x40000000)*32+10*4))//写PB10
  54. //#define READ_SDA  *((volatile unsigned long*)(0x42000000+((GPIOB_BASE+8)-0x40000000)*32+9*4))//读PB9
  55. //unsigned short int returntimeline(void);
  56. void SYSCLK_Config(void);
  57. #endif
复制代码
系统时钟及中断组选择
  1. /*
  2. 功能:系统初始配置
  3. 参数:无
  4. 说明:系统在执行main之前会执行SystemInit,其中包含时钟的初始化,但确保初始化成功,此处手动进行时钟及中断组选择
  5. */
  6. void SYSCLK_Config(void)
  7. {
  8.         RCC_DeInit();
  9.         RCC_HSEConfig(RCC_HSE_ON);
  10.         if (RCC_WaitForHSEStartUp() == SUCCESS)
  11.     {
  12.         // 关闭HSI(可选)
  13.         RCC_HSICmd(DISABLE);
  14.         
  15.         // 配置PLL:HSE分频1(不分频)后作为PLL输入,倍频9倍
  16.         // 注意:根据具体型号选择分频系数,此处为STM32F1系列典型配置
  17.         RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);
  18.         
  19.         // 启动PLL并等待就绪
  20.         RCC_PLLCmd(ENABLE);
  21.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
  22.         
  23.         // 切换系统时钟到PLL输出
  24.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  25.         
  26.         // 验证时钟切换是否成功
  27.         while(RCC_GetSYSCLKSource() != 0x08);
  28.         
  29.         // 配置总线分频(关键修改点)
  30.         RCC_HCLKConfig(RCC_SYSCLK_Div1);    // AHB 72MHz
  31.         RCC_PCLK1Config(RCC_HCLK_Div2);     // APB1 36MHz(不超过官方限制)
  32.         RCC_PCLK2Config(RCC_HCLK_Div1);     // APB2 72MHz
  33.                                
  34.                                 vPortRaiseBASEPRI();//开启Freertos的中断管理
  35.                                 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  36.                                
  37.     }
  38. }
复制代码
2.3 系统delay及滴答定时器初始化
  1. #include "delay.h"
  2. u8 fac_us,fac_ms;
  3. /*******************************************************************************
  4. * 函数名      : delay_Init
  5. * 功能                    : 对系统滴答定时器初始化
  6. * 参数        : SYSCLK,已设置的系统时钟频率如:72,其已在启动文件中设置
  7. * 返回值      : 无
  8. * 描述        : 无
  9. *******************************************************************************/
  10. void delay_Init(u8 SYSCLK)
  11. {
  12.         u32 reload;
  13.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//设置为HCLK不分频,本机在stm32f10x_system.c文件中定义了36MHZ系统时钟频率
  14.         fac_us=SYSCLK;//每微秒需要计的数量,nMHZ执计n次为微秒
  15.         reload=SYSCLK;
  16.         reload=(reload*1000000/configTICK_RATE_HZ);
  17.         //先乘以1000000恢复Mhz,再除以OS工作频率,得到计数次数,
  18.         //按此重装值计数的中断可得到想要的OS工作频率
  19.         fac_ms=1000/configTICK_RATE_HZ;//t=1/f(秒)
  20.         //系统频率下的最小单位时间,乘以1000因为要的是毫秒
  21.         SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
  22.         SysTick->LOAD=reload;//每1/configTICK_RATE_HZ秒中断一次
  23.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//开启SYSTICK
  24. }
  25. /*******************************************************************************
  26. * 函数名      : delay_us
  27. * 功能                    : 延时nus
  28. * 参数        : nus,要延时的微秒数
  29. * 返回值      : 无
  30. * 描述        : 因为OS的工作频率设定为1000,最小时间单位1ms,
  31.                 无法在使用OS框架内延时us级时间
  32. *******************************************************************************/
  33. void delay_us(uint32_t nus)
  34. {
  35.         u32 ticks;
  36.         u32 told ,tnow,tcnt=0;
  37.         u32 reload=SysTick->LOAD;//读取当前重装LOAD值
  38.         ticks=(nus*fac_us);//需要的节拍数
  39.         told=SysTick->VAL;//进入时的计数器值
  40.         while(1)
  41.         {
  42.                 tnow=SysTick->VAL;//读取当前值
  43.                 if(tnow!=told)//除非单片机卡死了,old值和now值没变化,那就卡死在while里等待恢复
  44.                 {
  45.                         if(tnow<told)
  46.                         {
  47.                                 tcnt+=told-tnow;//记录两次间隔的计数数量并累加
  48.                         }
  49.                         else//为特殊情况now值到0重装后突变的增加的重装值做修正
  50.                         {
  51.                                 tcnt+=(told-(tnow-reload));
  52.                         }
  53.                         told = tnow;//更新Old值
  54.                         if(tcnt>=ticks)
  55.                                 break;//时间等于或超过要延时的时间,退出while
  56.                 }
  57.         }
  58. }
  59. /*******************************************************************************
  60. * 函数名      : delay_ms
  61. * 功能                    : 延时nms
  62. * 参数        : nms,要延时的毫秒数
  63. * 返回值      : 无
  64. * 描述        : 会引起任务调度
  65. *******************************************************************************/
  66. void delay_ms(uint32_t nms)
  67. {
  68. //        if(1/*xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED*/)
  69.                 if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
  70.         {
  71.                 if(nms>=fac_ms)
  72.                 {
  73.                         vTaskDelay(nms/fac_ms);//整数倍的毫秒使用任务调度延时
  74.                 }
  75.                 nms%=fac_ms;               
  76.         }
  77.         delay_us((u32)(nms*1000));//余下部分化成微秒用普通微秒延时
  78. }
  79. /*******************************************************************************
  80. * 函数名      : delay_ms
  81. * 功能                    : 延时nms
  82. * 参数        : nms,要延时的毫秒数
  83. * 返回值      : 无
  84. * 描述        : 不会引起任务调度
  85. *******************************************************************************/
  86. void delay_xms(uint32_t nms)
  87. {
  88.         u32 i;
  89.         for(i=0;i<nms;i++)
  90.         delay_us(1000);
  91. }
  92. void Clock_Test(uint32_t ticks)
  93. {
  94.         u32 told ,tnow,tcnt=0;
  95.         u32 reload=SysTick->LOAD;//读取当前重装LOAD值
  96. //        ticks=(nus*fac_us);//需要的节拍数
  97.         told=SysTick->VAL;//进入时的计数器值
  98.         while(1)
  99.         {
  100.                 tnow=SysTick->VAL;//读取当前值
  101.                 if(tnow!=told)//除非单片机卡死了,old值和now值没变化,那就卡死在while里等待恢复
  102.                 {
  103.                         if(tnow<told)
  104.                         {
  105.                                 tcnt+=told-tnow;//记录两次间隔的计数数量并累加
  106.                         }
  107.                         else//为特殊情况now值到0重装后突变的增加的重装值做修正
  108.                         {
  109.                                 tcnt+=(told-(tnow-reload));
  110.                         }
  111.                         told=tnow;
  112.                         if(tcnt>=ticks)
  113.                                 break;//时间等于或超过要延时的时间,退出while
  114.                 }
  115.         }
  116. }
复制代码
3.红外控制
3.1 红外发射接收APP 预设参数
以下代码主要包含红外接收,各信号的时间长度宏界说,发送相关红外协议命令宏界说
  1. #ifndef __IRLED_H
  2. #define __IRLED_H
  3. #include "stm32f10x.h"                  // Device header
  4. #include "delay.h"
  5. #include "system.h"
  6. /* 红外接收相关定义 */
  7. #define IR_TIMER               TIM3
  8. #define IR_TIMER_CHANNEL       TIM_Channel_1
  9. #define IR_GPIO_PORT           GPIOB
  10. #define IR_GPIO_PIN            GPIO_Pin_4
  11. #define IR_CLOCK_FREQ          36000000  // 系统时钟72MHz,此处我设置位36MHZ,红外接收的定时计数器每计一个数位为0.5微妙
  12. #define IR_Lead_MAX            18500
  13. #define IR_Lead_MIN            15000
  14. #define IR_DATA_1_MAX          4500
  15. #define IR_DATA_1_MIN          4100
  16. #define IR_DATA_0_MAX          2300
  17. #define IR_DATA_0_MIN          2000
  18. #define SEPARATION_MAX         13000
  19. #define SEPARATION_MIN         10000
  20. //空调相关控制参数,R05D协议
  21. #define IR_A_Data                   0xB2
  22. #define IR_B_Windspeed_Auto         0xBF
  23. #define IR_B_Windspeed_Low          0x9F
  24. #define IR_B_Windspeed_Mid                       0x5F
  25. #define IR_B_Windspeed_High                      0x3F
  26. #define IR_B_OFF                    0x7B
  27. //工作模式只低占3-4位,高4位的温度区域先保留为0
  28. #define IR_C_OperationMode_Auto                        0x08
  29. #define IR_C_OperationMode_cold                        0x00
  30. #define IR_C_OperationMode_DeHumi                0x04
  31. #define IR_C_OperationMode_Heat                  0x0C
  32. #define IR_C_OperationMode_SentWind        0x04 //送风模式没有温度代码
  33. //温度控制参数,低4位都保留为0
  34. #define IR_C_temp_17                                        0x00
  35. #define IR_C_temp_18                                        0x10
  36. #define IR_C_temp_19                                        0x30
  37. #define IR_C_temp_20                                        0x20
  38. #define IR_C_temp_21                                        0x60
  39. #define IR_C_temp_22                                        0x70
  40. #define IR_C_temp_23                                        0x50
  41. #define IR_C_temp_24                                        0x40
  42. #define IR_C_temp_25                                        0xC0
  43. #define IR_C_temp_26                                        0xD0
  44. #define IR_C_temp_27                                        0x90
  45. #define IR_C_temp_28                                        0x80
  46. #define IR_C_temp_29                                        0xA0
  47. #define IR_C_temp_30                                        0xB0
  48. #define IR_C_temp_Nop                                        0xE0
  49. #define IR_C_OFF              0xE0
  50. /* 时间数据buffer */
  51. extern u16 IR_Buffer_Row[125];
  52. void IR_TIM_Init(void);
  53. u8 decode_A(u16* rowdata);
  54. u8 decode_NA(u16* rowdata);
  55. u8 decode_B(u16* rowdata);
  56. u8 decode_NB(u16* rowdata);
  57. u8 decode_C(u16* rowdata);
  58. u8 decode_NC(u16* rowdata);
  59. u8 Decode_IRDta(void);
  60. u8  Lead_cheak(u16* rowdata);
  61. u8 Separation_cheak(u16* rowdata);
  62.        
  63. void IR_Init(void);
  64. void IR_TIM3_PWM_Init(void) ;
  65. void IRLED_GPIO_Init(void);
  66. void Normal_Code(u8 A, u8 B, u8 C);
  67. void TIM3_SETLOW(void);
  68. void TIM3_SETHIG(void);
  69. void Lead_Code(void);
  70. void Stop_Code(void);
  71. void Send_0_Code(void);
  72. void Send_1_Code(void);
  73. void Send_Byte(u8 data);
  74. u8 ConducterControl(ConducterMode mode ,u8 temp);
  75. //     Normal_Code(0xB2, 0x9F, 0x00);//开机 17度
  76. #endif
复制代码
3.2 红外初始化函数
  1. /*
  2. 功能:对红外发射接收功能进行初始
  3. 参数:无
  4. 说明:不可同时启用发射接收初始化,因为他们都使用TIM3定时器
  5. */
  6. void IR_Init(void)
  7.         {
  8.       IR_TIM3_PWM_Init();//红外发射功能PWM初始化
  9.           //IR_TIM_Init();//红外接收功能初始化
  10.    }
复制代码
3.3 红外发射控制。
实现代码如下,部分代码参考了:https://blog.csdn.net/weixin_42204837/article/details/109263771
  1. /*
  2. 功能:PWM初始
  3. 参数:无
  4. */
  5. void IR_TIM3_PWM_Init(void)
  6.         {
  7.     // 使能GPIOA和TIM3时钟
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  10.     // 配置PA6为复用推挽输出(用于Q2栅极)
  11.     GPIO_InitTypeDef GPIO_InitStructure;
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  16.     // 配置TIM3
  17.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  18.     TIM_TimeBaseStructure.TIM_Period = 1894; // 38kHz PWM (72MHz / (947 + 1) = 38kHz)
  19.     TIM_TimeBaseStructure.TIM_Prescaler = 0;
  20.     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  21.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  22.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  23.     // 配置TIM3通道1为PWM模式
  24.     TIM_OCInitTypeDef TIM_OCInitStructure;
  25.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  26.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  27.     TIM_OCInitStructure.TIM_Pulse = 947; // 947 50%占空比
  28.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  29.     TIM_OC1Init(TIM3, &TIM_OCInitStructure);
  30.     // 启动TIM3
  31.     TIM_Cmd(TIM3, ENABLE);
  32. }
  33. /*
  34. 功能:红外不输出,接收器拉高,发送低
  35. 参数:无
  36. */
  37. void         TIM3_SETLOW(void)
  38. {
  39.    TIM3->CCR1 = 0;
  40. //TIM_SetCompare1(TIM3,0);
  41. }
  42. /*
  43. 功能:红外输出,接收器拉低,发送高
  44. 参数:无
  45. */
  46. void         TIM3_SETHIG()
  47. {
  48.     TIM3->CCR1 = 947;
  49. //                TIM_SetCompare1(TIM3,947);
  50. }
  51. /*
  52. 功能:发送美的红外控制引导码
  53. 参数:无
  54. */
  55. void Lead_Code(void)
  56. {
  57.         TIM3_SETHIG(); //接收器拉低,对发送就是高
  58.         delay_us(4400);
  59.         TIM3_SETLOW(); //接收器拉高,对发送就是低
  60.         delay_us(4400);
  61. }
  62. /*
  63. 功能:发送美的红外控制停止码
  64. 参数:无
  65. */
  66. void Stop_Code(void)
  67. {
  68.         TIM3_SETHIG(); //接收器拉低
  69.         delay_us(540);
  70.         TIM3_SETLOW(); //接收器拉高
  71.         delay_us(5220);
  72. }
  73. /*
  74. 功能:发送美的红外 bit 0
  75. 参数:无
  76. */
  77. void Send_0_Code(void)
  78. {
  79.         TIM3_SETHIG(); //接收器拉低
  80.         delay_us(540);
  81.         TIM3_SETLOW(); //接收器拉高
  82.         delay_us(540);
  83. }
  84. /*
  85. 功能:发送美的红外 bit 1
  86. 参数:无
  87. */
  88. void Send_1_Code(void)
  89. {
  90.         TIM3_SETHIG(); //接收器拉低
  91.         delay_us(540);
  92.         TIM3_SETLOW(); //接收器拉高
  93.         delay_us(1620);
  94. }
  95. /*
  96. 功能:发送美的红外8位byte
  97. 参数:无
  98. */
  99. void Send_Byte(u8 data)
  100. {
  101.         int i;
  102.         for(i=7;i>=0;i--)
  103.         {
  104.                 if(data & (1<<i))
  105.                 {
  106.                         Send_1_Code();
  107.                 }
  108.                 else
  109.                 {
  110.                         Send_0_Code();
  111.                 }
  112.         }
  113. }
  114. /*
  115. 功能:发送美的红外控制的一条完整信号
  116. 参数:无
  117. */
  118. void Normal_Code(u8 A, u8 B, u8 C)
  119. {
  120.         Lead_Code();
  121.         Send_Byte(A);
  122.         Send_Byte(~A);
  123.         Send_Byte(B);
  124.         Send_Byte(~B);
  125.         Send_Byte(C);
  126.         Send_Byte(~C);
  127.         Stop_Code();
  128.         Lead_Code();
  129.         Send_Byte(A);
  130.         Send_Byte(~A);
  131.         Send_Byte(B);
  132.         Send_Byte(~B);
  133.         Send_Byte(C);
  134.         Send_Byte(~C);
  135.         Stop_Code();
  136. }
  137. /*
  138. 功能:控制红外发射完成相应模式温度的信号发送
  139. 参数:mode 枚举变量,通过switch对模式进行选择
  140.      temp 通过switch对温度进行选择
  141. */
  142. u8 ConducterControl(ConducterMode mode ,u8 temp)
  143. {
  144.         u8 C_Data,ModeData,TempData;
  145.         switch(mode)
  146.   {
  147.                 case Auto     :ModeData=IR_C_OperationMode_Auto;break;
  148.                 case cold     :ModeData=IR_C_OperationMode_cold;break;
  149.                 case DeHumi   :ModeData=IR_C_OperationMode_DeHumi;break;
  150.                 case Heat     :ModeData=IR_C_OperationMode_Heat;break;
  151.                 case SentWind :ModeData=IR_C_OperationMode_SentWind;break;
  152.                 default: return 0;
  153.         }
  154.         switch(temp)
  155.         {
  156.                 case 17 : TempData=IR_C_temp_17;break;
  157.                 case 18 : TempData=IR_C_temp_18;break;
  158.                 case 19 : TempData=IR_C_temp_19;break;
  159.                 case 20 : TempData=IR_C_temp_20;break;
  160.                 case 21 : TempData=IR_C_temp_21;break;
  161.                 case 22 : TempData=IR_C_temp_22;break;
  162.                 case 23 : TempData=IR_C_temp_23;break;
  163.                 case 24 : TempData=IR_C_temp_24;break;
  164.                 case 25 : TempData=IR_C_temp_25;break;
  165.                 case 26 : TempData=IR_C_temp_26;break;
  166.                 case 27 : TempData=IR_C_temp_27;break;
  167.                 case 28 : TempData=IR_C_temp_28;break;
  168.                 case 29 : TempData=IR_C_temp_29;break;
  169.                 case 30 : TempData=IR_C_temp_30;break;
  170.                 default : TempData=IR_C_temp_Nop;break;
  171.         }
  172.         C_Data=(ModeData&0x0C)|(TempData&0xF0);
  173.         SYS_Glabal_varible.IR_Sent_Data.IR_Sent_Data[0]=0xB2;
  174.         SYS_Glabal_varible.IR_Sent_Data.IR_Sent_Data[1]=IR_B_Windspeed_Auto;
  175.         SYS_Glabal_varible.IR_Sent_Data.IR_Sent_Data[2]=C_Data;
  176.         SYS_Glabal_varible.IR_Sent_Data.temp=temp;
  177.         SYS_Glabal_varible.IR_Sent_Data.mode=mode;
  178.         Normal_Code(0xB2,IR_B_Windspeed_Auto,C_Data);
  179.         return 1;
  180. }
复制代码
4 加湿器模块
加湿器模块通过开关按键实现控制,按一下切换模式,模式有 “关”、“低”、“高” 三种模式
通过延时置位复位IO到达模拟按键的作用。
代码实现如下
  1. /*
  2. 功能:接收捕获的定时器配置
  3. 参数:无
  4. */
  5. void IR_TIM_Init(void) {
  6.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  7.     TIM_ICInitTypeDef TIM_ICInitStructure;
  8.     NVIC_InitTypeDef NVIC_InitStructure;
  9.     GPIO_InitTypeDef GPIO_InitStructure;
  10.     /* 开启时钟 */
  11.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  12.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  13.         /* 开启AFIO时钟(关键!)*/
  14.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  15.         /* 配置PB4复用为TIM3_CH1 */
  16.     GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);  // 部分重映射:TIM3_CH1->PB4
  17.     /* 配置GPIO */
  18.     GPIO_InitStructure.GPIO_Pin = IR_GPIO_PIN;
  19.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  20.     GPIO_Init(IR_GPIO_PORT, &GPIO_InitStructure);
  21.     /* 定时器基础配置 */
  22.         //APB1总线上的定时器时钟确实有一个倍频机制。当APB1的预分频系数设置为1以外的值时(即分频系数为2、4、8或16),定时器的时钟频率会是APB1频率的两倍
  23.     TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
  24.     TIM_TimeBaseStructure.TIM_Prescaler = (IR_CLOCK_FREQ/1000000) - 1; // 0.5us计数
  25.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  26.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  27.     TIM_TimeBaseInit(IR_TIMER, &TIM_TimeBaseStructure);
  28.     /* 输入捕获配置 */
  29.     TIM_ICInitStructure.TIM_Channel = IR_TIMER_CHANNEL;
  30.     TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // 双沿触发
  31.     TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  32.     TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  33.     TIM_ICInitStructure.TIM_ICFilter = 0x08; // 适当滤波
  34.     TIM_ICInit(IR_TIMER, &TIM_ICInitStructure);
  35.     /* 中断配置 */
  36.     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  37.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
  38.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  39.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  40.     NVIC_Init(&NVIC_InitStructure);
  41.     TIM_ClearITPendingBit(IR_TIMER, TIM_IT_CC1 | TIM_IT_Update);
  42.     TIM_ITConfig(IR_TIMER, TIM_IT_CC1 | TIM_IT_Update, ENABLE);
  43.     TIM_Cmd(IR_TIMER, ENABLE);
  44. }
  45. /* 中断服务函数 */
  46. void TIM3_IRQHandler(void)
  47.         {
  48. //                u16 num;
  49.     if(TIM_GetITStatus(IR_TIMER, TIM_IT_Update) != RESET)
  50.     {
  51.         TIM_ClearITPendingBit(IR_TIMER, TIM_IT_Update);
  52.                           TIM_SetCounter(IR_TIMER,0);
  53.     }
  54.    
  55.     if(TIM_GetITStatus(IR_TIMER, TIM_IT_CC1) != RESET)
  56.     {
  57.         if(enter_flag_verify)
  58.         {
  59.         
  60.         if(~GPIO_ReadInputDataBit(IR_GPIO_PORT, IR_GPIO_PIN))
  61.                           {
  62.                                             IR_Buffer_Row[Buffer_index]=TIM_GetCapture1(IR_TIMER);
  63.                                             Buffer_index++;
  64.                                             if(Buffer_index==99)
  65.                                                         {
  66.                                                                 Buffer_index=0;
  67.                                                           enter_flag_verify=0;
  68.                                                         }
  69.         }
  70.                                                         TIM_SetCounter(IR_TIMER,0);
  71.         }
  72.         else
  73.                                 {               
  74.             enter_flag_verify=1;
  75.             TIM_SetCounter(IR_TIMER,0);                               
  76.                                 }
  77.         TIM_ClearITPendingBit(IR_TIMER, TIM_IT_CC1);
  78.     }
  79.           }
  80. u8  Lead_cheak(u16* rowdata)
  81. {
  82.   if(rowdata[0]>IR_Lead_MIN&&rowdata[0]<IR_Lead_MAX)
  83.   {
  84.     frame_num=1;
  85.     return 1;
  86.   }
  87.   else
  88.       return 0;
  89.        
  90. }
  91. u8 Separation_cheak(u16* rowdata)
  92. {
  93.   if(rowdata[49]>SEPARATION_MIN&&rowdata[49]<SEPARATION_MAX)
  94.   {
  95.     frame_num=2;
  96.     return 1;
  97.   }
  98.   else
  99.     return 0;
  100.        
  101. }
  102. u8 decode_A(u16* rowdata)
  103. {          
  104.     u8 i=0;
  105.           if(frame_num==1)//解码第一帧
  106.                 {
  107.        for(i=0;i<8;i++)
  108.       {
  109. //        printf("%d\n",rowdata[i+1]);
  110.         if(rowdata[i+1]>IR_DATA_1_MIN&&rowdata[i+1]<IR_DATA_1_MAX)
  111.           ir_data[0]|=(0x80>>i);
  112.         else if (rowdata[i+1]<IR_DATA_0_MAX&&rowdata[i+1]>IR_DATA_0_MIN)
  113.           ir_data[0]&=~(0x80>>i);
  114.       }
  115.                 }else if(frame_num==2)//解码第二帧
  116.                 {
  117.                          for(i=0;i<8;i++)
  118.       {
  119. //        printf("%d\n",rowdata[i+51]);
  120.         if(rowdata[i+51]>IR_DATA_1_MIN&&rowdata[i+51]<IR_DATA_1_MAX)
  121.           ir_data[0]|=(0x80>>i);
  122.         else if (rowdata[i+51]<IR_DATA_0_MAX&&rowdata[i+51]>IR_DATA_0_MIN)
  123.           ir_data[0]&=~(0x80>>i);
  124.       }
  125.                 }
  126.     return ir_data[0];   
  127. }
  128. u8 decode_NA(u16* rowdata)
  129. {
  130.     u8 i=0;
  131.           if(frame_num==1)
  132.                 {
  133.     for(i=0;i<8;i++)
  134.     {
  135.                 //printf("%d\n",rowdata[i+9]);
  136.         if(rowdata[i+9]>IR_DATA_1_MIN&&rowdata[i+9]<IR_DATA_1_MAX)
  137.           ir_data[1]|=(0x80>>i);
  138.           else if (rowdata[i+9]<IR_DATA_0_MAX&&rowdata[i+9]>IR_DATA_0_MIN)
  139.           ir_data[1]&=~(0x80>>i);
  140.     }
  141.           }
  142.                 else if(frame_num==2)
  143.                 {
  144.                          for(i=0;i<8;i++)
  145.       {
  146. //        printf("%d\n",rowdata[i+59]);
  147.         if(rowdata[i+59]>IR_DATA_1_MIN&&rowdata[i+59]<IR_DATA_1_MAX)
  148.           ir_data[1]|=(0x80>>i);
  149.         else if (rowdata[i+59]<IR_DATA_0_MAX&&rowdata[i+59]>IR_DATA_0_MIN)
  150.           ir_data[1]&=~(0x80>>i);
  151.       }
  152.                 }
  153.     return ir_data[1];   
  154. }
  155. u8 decode_B(u16* rowdata)
  156. {
  157.     u8 i=0;
  158.           if(frame_num==1)
  159.                 {
  160.     for(i=0;i<8;i++)
  161.     {
  162.                 //printf("%d\n",rowdata[i+17]);
  163.         if(rowdata[i+17]>IR_DATA_1_MIN&&rowdata[i+17]<IR_DATA_1_MAX)
  164.           ir_data[2]|=(0x80>>i);
  165.           else if (rowdata[i+17]<IR_DATA_0_MAX&&rowdata[i+17]>IR_DATA_0_MIN)
  166.           ir_data[2]&=~(0x80>>i);
  167.     }
  168.           }else if(frame_num==2)
  169.                 {
  170.                 for(i=0;i<8;i++)
  171.       {
  172. //        printf("%d\n",rowdata[i+67]);
  173.         if(rowdata[i+67]>IR_DATA_1_MIN&&rowdata[i+67]<IR_DATA_1_MAX)
  174.           ir_data[2]|=(0x80>>i);
  175.         else if (rowdata[i+67]<IR_DATA_0_MAX&&rowdata[i+67]>IR_DATA_0_MIN)
  176.           ir_data[2]&=~(0x80>>i);
  177.       }
  178.                 }
  179.                
  180.     return ir_data[2];   
  181. }
  182. u8 decode_NB(u16* rowdata)
  183. {
  184.           
  185.     u8 i=0;
  186.         if(frame_num==1)
  187.         {
  188.     for(i=0;i<8;i++)
  189.     {
  190.                 //printf("%d\n",rowdata[i+25]);
  191.         if(rowdata[i+25]>IR_DATA_1_MIN&&rowdata[i+25]<IR_DATA_1_MAX)
  192.           ir_data[3]|=(0x80>>i);
  193.           else if (rowdata[i+25]<IR_DATA_0_MAX&&rowdata[i+25]>IR_DATA_0_MIN)
  194.           ir_data[3]&=~(0x80>>i);
  195.     }
  196.         }else if(frame_num==2)
  197.         {
  198.                 for(i=0;i<8;i++)
  199.       {
  200. //        printf("%d\n",rowdata[i+75]);
  201.         if(rowdata[i+75]>IR_DATA_1_MIN&&rowdata[i+75]<IR_DATA_1_MAX)
  202.           ir_data[3]|=(0x80>>i);
  203.         else if (rowdata[i+75]<IR_DATA_0_MAX&&rowdata[i+75]>IR_DATA_0_MIN)
  204.           ir_data[3]&=~(0x80>>i);
  205.       }
  206.         }
  207.     return ir_data[3];   
  208. }
  209. u8 decode_C(u16* rowdata)
  210. {
  211.           
  212.     u8 i=0;
  213.           if(frame_num==1)
  214.                 {
  215.     for(i=0;i<8;i++)
  216.     {
  217.                 //printf("%d\n",rowdata[i+33]);
  218.         if(rowdata[i+33]>IR_DATA_1_MIN&&rowdata[i+33]<IR_DATA_1_MAX)
  219.           ir_data[4]|=(0x80>>i);
  220.           else if (rowdata[i+33]<IR_DATA_0_MAX&&rowdata[i+33]>IR_DATA_0_MIN)
  221.           ir_data[4]&=~(0x80>>i);
  222.     }
  223.           }else if(frame_num==2)
  224.                 {
  225.           for(i=0;i<8;i++)
  226.       {
  227. //        printf("%d\n",rowdata[i+83]);
  228.         if(rowdata[i+83]>IR_DATA_1_MIN&&rowdata[i+83]<IR_DATA_1_MAX)
  229.           ir_data[4]|=(0x80>>i);
  230.         else if (rowdata[i+83]<IR_DATA_0_MAX&&rowdata[i+83]>IR_DATA_0_MIN)
  231.           ir_data[4]&=~(0x80>>i);
  232.       }
  233.                 }
  234.     return ir_data[4];   
  235. }
  236. u8 decode_NC(u16* rowdata)
  237. {
  238.     u8 i=0;
  239.         if(frame_num==1)
  240.         {
  241.     for(i=0;i<8;i++)
  242.     {
  243.                 //printf("%d\n",rowdata[i+41]);
  244.         if(rowdata[i+41]>IR_DATA_1_MIN&&rowdata[i+41]<IR_DATA_1_MAX)
  245.           ir_data[5]|=(0x80>>i);
  246.           else if (rowdata[i+41]<IR_DATA_0_MAX&&rowdata[i+41]>IR_DATA_0_MIN)
  247.           ir_data[5]&=~(0x80>>i);
  248.     }
  249.         }else if(frame_num==2)
  250.         {
  251.                 for(i=0;i<8;i++)
  252.       {
  253. //        printf("%d\n",rowdata[i+91]);
  254.         if(rowdata[i+91]>IR_DATA_1_MIN&&rowdata[i+91]<IR_DATA_1_MAX)
  255.           ir_data[5]|=(0x80>>i);
  256.         else if (rowdata[i+91]<IR_DATA_0_MAX&&rowdata[i+91]>IR_DATA_0_MIN)
  257.           ir_data[5]&=~(0x80>>i);
  258.       }
  259.         }
  260.     return ir_data[5];   
  261. }
  262. /*
  263.   功能:对接收到的原始数据进行解码
  264.   输入:IR_Buffer_Row 原始数据数组首地址
  265.   输出:ir_data[x],x=0->A,x=1->NA,x=2->B,x=3->NB,x=4->C,x=5->NC,
  266. */
  267. u8 Decode_IRDta(void)
  268. {
  269.         if(Lead_cheak(IR_Buffer_Row))//对第一帧Lead检查
  270.         {
  271.                 if((decode_A(IR_Buffer_Row)==(u8)~decode_NA(IR_Buffer_Row))&&
  272.                          (decode_B(IR_Buffer_Row)==(u8)~decode_NB(IR_Buffer_Row))&&
  273.                    (decode_C(IR_Buffer_Row)==(u8)~decode_NC(IR_Buffer_Row)))//对第一帧数据进行解码并反码校验
  274.                 {
  275.                           frame_num=0;
  276.                           return 1;
  277.                 }
  278.                 else{
  279.                             if(Separation_cheak(IR_Buffer_Row))//第一帧检查失败,进行间隔码检查
  280.                       {
  281.                                if((decode_A(IR_Buffer_Row)==(u8)~decode_NA(IR_Buffer_Row))&&
  282.                                   (decode_B(IR_Buffer_Row)==(u8)~decode_NB(IR_Buffer_Row))&&
  283.                             (decode_C(IR_Buffer_Row)==(u8)~decode_NC(IR_Buffer_Row)))//间隔码检查通过对第二帧数据进行解码并反码晓校验
  284.                                    //第二帧解码前没有对第二帧的Lead码进行验证,但我觉得没有必要,那我就不验证哒
  285.                                   {
  286.                                                                         frame_num=0;
  287.                                     return 2;
  288.                                   }else
  289.                                     {//第二帧反码也校验识别,没得玩了
  290.                                                                                 frame_num=0;
  291.                                       return 3;
  292.                                     }
  293.                       }
  294.                       else
  295.                             return 4;//间隔码检测失败
  296.                                 }
  297.         }
  298.         else
  299.         {
  300.                 frame_num=0;
  301.                 return 5;
  302.         }
  303. }
复制代码
5.串口初始化
头文件代码,主要完成串口的存储缓冲区界说
  1. #include "Humidifier.h"
  2. #include "stdio.h"
  3. /*
  4.   功能:加湿器使用IO初始化
  5.   参数:无
  6. */
  7. void RH_GPIO_Init(void)
  8. {
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  10.         GPIO_InitTypeDef GPIO_InitStruct;
  11.         GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
  12.         GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
  13.         GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
  14.         GPIO_Init(GPIOB,&GPIO_InitStruct);
  15.         GPIO_ResetBits(GPIOB, GPIO_Pin_5);
  16. }
  17. /*
  18.   功能:加湿器按键模拟
  19.   参数:num
  20.   说明:num表示按几次按键
  21. */
  22. void PressKey(u8 num)
  23. {
  24.         while(num--)
  25.         {
  26.                 GPIO_SetBits(GPIOA, GPIO_Pin_5);
  27.                 delay_ms(500);
  28.                 GPIO_ResetBits(GPIOB, GPIO_Pin_5);
  29.                 delay_ms(500);
  30.         }
  31. }
  32. /*
  33.   功能:加湿器模式控制
  34.   参数:RH_State sta 模式的枚举变量
  35.   说明:通过与最后一次模式的比较,判断需要按几次按键,以完成模式控制
  36. */
  37. void RH_Control(RH_State sta)
  38. {
  39.         RH_State laststa;
  40.    if(sta!=laststa)
  41.         {
  42.                 switch(laststa)
  43.                 {
  44.                         case State_Low: //上次是低
  45.                         {
  46.                                 if(sta==State_OFF)
  47.                                 PressKey(2);
  48.                                 else if(sta==State_High)
  49.                                 PressKey(1);
  50.                         }
  51.                         case State_OFF:
  52.                         {
  53.                                 if(sta==State_Low)
  54.                                 PressKey(1);
  55.                                 else if(sta==State_High)
  56.                                 PressKey(2);
  57.                         }
  58.                         case State_High :
  59.                         {
  60.                                 if(sta==State_OFF)
  61.                                 PressKey(1);
  62.                                 else if(sta==State_Low)
  63.                                 PressKey(2);
  64.                         }
  65.                         default: printf("Error!\n");
  66.                 }
  67.         }
  68.         laststa=sta;
  69. }
复制代码
使用USART3作为与ESP01S 通信接口,USART1 作为调试使用
[code]#include "usart.h"#include "stdio.h"#include "delay.h"int fputc(int ch,FILE *p)  //该函数用于在使用printf时发送字符到串口{        USART_SendData(USART1,(u8)ch);                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);        return ch;}           u8 USART1_RX_BUF[USART1_REC_LEN];     //自界说了一个数组,可能用于接收缓冲器//其他位可能用于表示错误状态或额外的控制信息̬//bit15接收完成标记位,当接收到完整的数据包(如以特定的竣事符结尾)时,该位被置1//bit14表示是否接收到特定的字符(如回车符\r,即0x0D)//bit13~0存储接收到的数据长度u16 USART1_RX_STA=0;       //存储串口接收的状态信息u8 USART3_RX_BUF[USART3_REC_LEN];     //自界说了一个数组,可能用于接收缓冲器//其他位可能用于表示错误状态或额外的控制信息̬//bit15接收完成标记位,当接收到完整的数据包(如以特定的竣事符结尾)时,该位被置1//bit14表示是否接收到特定的字符(如回车符\r,即0x0D)//bit13~0存储接收到的数据长度u16 USART3_RX_STA=0;       //存储串口接收的状态信息/******************************************************************************** 函数名   : USART1_Init* 功能                 : USART1初始化* 参数     : bound:串口波特率* 返回值   : 无*******************************************************************************/ void USART1_Init(u32 bound){   //GPIO的IO口、串口及中断管理结构变量界说        GPIO_InitTypeDef GPIO_InitStructure;        USART_InitTypeDef USART_InitStructure;        NVIC_InitTypeDef NVIC_InitStructure;        //开GPIO和串口时钟  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);         // 重映射USART1到PB6/PB7  GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);                /*  GPIO参数设置 */        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//TX                           //UART1的TX口设置为PB6        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;            //推挽输出        GPIO_Init(GPIOB,&GPIO_InitStructure);  /* 应用GPIO的IO参数 */        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;//RX                         //UART1的RX口设置为PB7        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;                  //设置浮空输入        GPIO_Init(GPIOB,&GPIO_InitStructure); /* 初始化UART1的接收GPIO */                //USART1 结构变量参数设置        USART_InitStructure.USART_BaudRate = bound;//串口波特率设置        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据帧的位数,此处8位        USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位数为1位        USART_InitStructure.USART_Parity = USART_Parity_No;//奇偶效验,此处关        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制选项,既通过再加一条RTS时钟线来防止数据丢失        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //串口模式,输入输出同时使用        USART_Init(USART1, &USART_InitStructure); //串口参数初始化使用                USART_Cmd(USART1, ENABLE);  //使能UART1                 USART_ClearFlag(USART1, USART_FLAG_TC);//清除UART标准位,在这里是清除UART1的发送完成标记位                        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//USART_IT_RXNE接收寄存器非空中断,串口中断配置,在这里使能了这个中断        //Usart1 NVIC 中断管理        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//选择中断函数        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级,数字越低优先级越高        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //等待优先级,在两个中断具备同等的抢占优先级时,等待优先级数字高的优先级越高        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ中断使能        NVIC_Init(&NVIC_InitStructure);        //初始化优先级}/******************************************************************************** 函数名      : USART1_IRQHandler* 功能                    : USART1接收寄存器满了发生中断* 参数        : 无* 返回值      : 无* 描述        : 接收数据,存在USART1_RX_BUF[]数组中,但是接收到回车会进入判断,若只有回车会复位USART1_RX_BUF[]数组从0开始存储,若是回车+换行则不能再接收数据*******************************************************************************/ void USART1_IRQHandler(void)                        {        u8 r;        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //如果串口接收寄存器非空标准位为1,该中断以开,即已经接收到了数据        {                r =USART_ReceiveData(USART1);//(USART1->DR);        //将接收到的数据放入r中                if((USART1_RX_STA&0x8000)==0)//还没查抄到了换行?                {                        if(USART1_RX_STA&0x4000)//是否查抄到回车                        {                                if(r!=0x0a)USART1_RX_STA=0;//若接收到的数据不为换行,则初始化串口接收状态变量,重新接收,直到接收到,0x0a是换行符                                else USART1_RX_STA|=0x8000;        //置串口接收状态变量最高位为1,表接收完成                         }                        //将USART1_RX_STA|=0x8000;表示此次数据接收任务竣事,同时设置此标记位在下次数据输入时使数据进入缓存                        else //未接收到了,回车0X0D                        {                                        if(r==0x0d)USART1_RX_STA|=0x4000;//查抄数据是否回车,将第14位置1                                else                                {                                        USART1_RX_BUF[USART1_RX_STA&0X3FFF]=r;//将数据放在缓存中,0X3FFF是将0到13位置1,实际按STA来表示数据长度                                        USART1_RX_STA++;                                        if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//若数据长度超过USART1_REC_LEN,重新开始计数数据长度,覆盖原有数据                                          }                                         }                }                            } }//int fputc(int ch, FILE *f)//{//        USART_TypeDef* USARTx =USART1;//        while((USARTx->SR&(1
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

李优秀

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表