基于便携式STM32的红外信号分析仪 - 单片机 物联网 嵌入式(含代码)

便携式STM32的红外信号分析仪

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

1 简介

由STM32F411CEU6作为主控芯片的带有姿态感应,红外输入,红外输出,可根据任意录入的红外信号进行存储,然后发出红外线控制各种电器设备, 并具有测电流,电压,电阻,电容能力的手表,是对于电子工程师来说具有较强实用性的小工具。

2 主要器件

  • STM32F411CEU6主控芯片
  • ACS712电流传感器芯片
  • TC单片机

3 实现效果


4 设计原理

硬件

  • 电压检测电路,主要是将外部-15v15v的电压通过几个限压电阻根据KCL和KVL转化成03.3v,再由ADC芯片采集;
  • 电阻检测电路,根据简单的分压原理,将待测电阻通过模拟开关分别与1k和1M欧高精度电阻串联测得分压,从而实现精确测量较大范围内的电阻阻值;
  • 电容检测电路,根据电容的一阶零状态响应,算出时间常数,再根据串联的电阻计算出接入电容的电容值;
  • )红外接收发射电路,采用外加一块STC单片机(一个模块~~~~),里面预先烧录红外解码程序,再通过串口与STM32通讯,实现对外部输入红外信号的解码和调制发射;

软件

  • 姿态解算算法,实现步数计算,抬手感应,翻腕感应,LCD虚拟触屏;
  • 针对不同红外信号的解码和发射算法,红外信号存储算法等;
  • 电阻,电容测量算法;
  • 自制定时器系统任务调度算法。

主要原理图

5 部分核心代码

#include "main.h" /********************变量声明区_START********************/
u8 flag_Power_On = 1, flag_MPU_Refresh = 0;
bool LCD_Already_Updated = false;
uint8_t RTC_hour = 23, RTC_minute = 14, RTC_second = 10;
u8 IR_flag = 0, IR_Channel = 0x01, flag_BEEP = 0, flag_ADS_readC = 0, flag_ADS_readR = 0;

u8 Arm_Position = -1;

short aacx, aacy, aacz;		//加速度传感器原始数据

bool Raised_Flag = false;
bool Reversed_Flag = false;

u8 flag_of_STATE = 0;
uint16_t Menu_Pointer[7] = {1, 35, 69, 103, 137, 171, 205};
u8 Fill_IR_Code[4] = {0, 0, 0, 0};		//显示红外码存储区是否为空:0-空 1-有
uint16_t time_set_Pos[4] = {54, 102, 150, 2};
uint16_t clock_set_Pos[3] = {5, 135, 1};

/**  * @brief 决定系统状态的选择  * @param 菜单;红外收发模式;红外通道选择模式;陀螺仪模式;模拟量测试模式;
 */
enum STATUS {  MENU = 0,  TIMERUN,  TIME_SET,  CLOCK_SET,  IR_REMOTE,  IR_CHANNEL_CHOOSE,  MPU6050,  AD_VAL, } STATE; #define  PUT_UP     1 #define  LAY_DOWN   2 //mpu6050
short cnt_up = 0;
short cnt_down = 0;
short cnt_reverse = 0;
short cnt_raising = 0;

short Stale_aacx_Data = NULL;
short Stale_aacy_Data = NULL;

short Reverse_status = 0;
/********************变量声明区_END********************/



/********************API声明区_START********************/
static  void  Proc2msTask(void);    //处理2ms任务
static  void  Proc50msTask(void);   //处理50ms任务
static  void  InitSoftware(void);
static  void  InitHardware(void);


void ST7789_SHOW(void);
void KEY_Process(void);

static  void  Get_Arm_Position(short* aacx, short* aacy, short* aacz, u8* Arm_Position, bool* Raised_Flag);
static  bool  Judge_Wrist_Reverse(short* aacx, short* aacy, short* aacz, u8* Arm_Position);
void MPU6050_Process(void);

static  void  Page0_Menu(void);
static  void  Page1_TimeRunning(void);
static  void  Page2_Timeset(void);
//static  void  Page3_Clockset1(void);
static  void  Page4_Clockset2(void);
static  void  Page5_IR_Remote(void);
static  void  Page7_AD_VAL(void);
/********************API声明区_END********************/



/********************************************************************************************************* * 函    数: main * 注    意: 作者为了让main看起来更漂亮,整了些花里胡哨的API QWQ *********************************************************************************************************/
int main(void) {  InitSoftware();  InitHardware();  STATE = MENU;  ST7789_Fill_Color(WHITE);  while(1) {  if(flag_Power_On)Proc2msTask();  if(flag_MPU_Refresh == 1) {  flag_MPU_Refresh = 0;  ST7789_Fill_Color(BLACK);  if(flag_Power_On){  LCD_Already_Updated = false;  ST7789_Fill_Color(WHITE);  }  }  Proc50msTask();  delay_ms(10);  } }





/********************************************************************************************************* * 内部函数实现 *********************************************************************************************************/
/********************************************************************************************************* * 函数名称: Proc2msTask * 函数功能: 处理2ms任务 * 输入参数: void * 输出参数: void * 返 回 值: void * 注    意: *********************************************************************************************************/
static void Proc2msTask(void) {  if(Get2msFlag()) {  static u8 tmp_t = 0;  if(!LCD_Already_Updated) {  ST7789_SHOW();  }  if(flag_BEEP == 1) {  BEEP();  flag_BEEP = 0;  } else if (flag_BEEP == 2) {  for(int i = 0; i < 5; i++) {  BEEP();  }  flag_BEEP = 0;  }  if(tmp_t == 5) {  KEY_Process();  tmp_t = 0;  }  tmp_t++;  Clr2msFlag();  } }

/********************************************************************************************************* * 函数名称: Proc50msTask * 函数功能: 处理50ms任务 * 输入参数: void * 输出参数: void * 返 回 值: void * 注    意: *********************************************************************************************************/
static  void  Proc50msTask(void) {  if(Get50msFlag()) {  MPU6050_Process();  Clr50msFlag();  } }



static  void  InitSoftware(void) {

}

static  void  InitHardware(void) {  SystemInit();  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2  delay_init(104);  			//初始化延时函数  uart_init(115200);			//初始化串口  InitTimer();				//初始化任务调度定时器  GPIO_ALLInit();				//初始化蜂鸣器,LED,KEY外设  five_keys_exti_config();	//初始化五向按键  ST7789_Init();				//初始化LCD-ST7789  MPU_Init();					//初始化MPU6050  My_RTC_Init();  RTC_Set_WakeUp(RTC_WakeUpClock_CK_SPRE_16bits, 0);		//配置WAKE UP中断,1秒钟中断一次  while(mpu_dmp_init()) {  printf("MPU6050 Init Error!\r\n");  delay_ms(200);  }  printf("Init OK\r\n"); }



void ST7789_SHOW(void) {  switch(STATE) {  case MENU: {  SPI_ChangeConfig(LCD);  Page0_Menu();  LCD_Already_Updated = true;  break;  }  case TIMERUN: {  SPI_ChangeConfig(LCD);  Page1_TimeRunning();  LCD_Already_Updated = true;  break;  }  case TIME_SET: {  SPI_ChangeConfig(LCD);  Page2_Timeset();  LCD_Already_Updated = true;  break;  }  case CLOCK_SET: {  SPI_ChangeConfig(LCD);  Page4_Clockset2();  LCD_Already_Updated = true;  break;  }  case IR_REMOTE: {  SPI_ChangeConfig(LCD);  Page5_IR_Remote();  LCD_Already_Updated = true;  break;  }  case IR_CHANNEL_CHOOSE: {  SPI_ChangeConfig(LCD);  ST7789_DrawImage(0, 0, 240, 240, (uint16_t *)IR_ChannelChoosing);  LCD_Already_Updated = true;  break;  }  case AD_VAL: {  SPI_ChangeConfig(ADS);  cin_get_cap_init();  ADS1118GPIOInit();  ADS1118_Init(ADS1118_SS_NONE, ADS1118_MODE_LX, ADS1118_DR_128, ADS1118_PULL_UP_EN_E, ADS1118_NOP_W);  SPI_ChangeConfig(LCD);  Page7_AD_VAL();  break;  }  default : {  LCD_Already_Updated = true;  break;  }  } }



void KEY_Process(void) {  u8 key = 0;  key = KEY_Scan(0);//得到键值  if(key) {  switch(key) {  case KEY1_PRES:  //红外选择通道:1/2/3/4  if(STATE == IR_CHANNEL_CHOOSE) {  IR_Channel = 0x01;  STATE = MENU;  LCD_Already_Updated = false;  ST7789_Fill_Color(WHITE);  }  //红外收发模式  else if(STATE == IR_REMOTE) {  IR_flag = !IR_flag;  if(IR_flag) {  LED2 = 0;  memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF));  USART1_Tx_Puts(cmd_stor_buffer1, IR_Channel);  } else {  LED2 = 1;  if(flag_USART_Get) {  Fill_IR_Code[IR_Channel - 1] = 1;  LCD_Already_Updated = false;  flag_USART_Get = 0;  } else {  Fill_IR_Code[IR_Channel - 1] = 0;  LCD_Already_Updated = false;  flag_USART_Get = 1;  }  //print_buffer;  }  } else if(STATE == AD_VAL) {  flag_ADS_readC = 1;  LCD_Already_Updated = false;  } else BEEP();  break;  case KEY2_PRES:  //红外选择通道:1/2/3/4  if(STATE == IR_CHANNEL_CHOOSE) {  IR_Channel = 0x02;  STATE = MENU;  LCD_Already_Updated = false;  ST7789_Fill_Color(WHITE);  }  //红外收发模式  else if(STATE == IR_REMOTE) {  USART1_Tx_Puts(cmd_send_buffer1, IR_Channel);  } else if(STATE == AD_VAL) {  flag_ADS_readR = 1;  LCD_Already_Updated = false;  } else BEEP();  break;  case KEY3_PRES:  //红外选择通道:1/2/3/4  if(STATE == IR_CHANNEL_CHOOSE) {  IR_Channel = 0x03;  STATE = MENU;  LCD_Already_Updated = false;  ST7789_Fill_Color(WHITE);  } else if(STATE == TIME_SET) {  ST7789_DrawRectangle(time_set_Pos[time_set_Pos[3]], 110,  time_set_Pos[time_set_Pos[3]] + 36, 148, WHITE);  time_set_Pos[3] = (time_set_Pos[3] == 0) ? 2 : (time_set_Pos[3] - 1);  LCD_Already_Updated = false;  } else if(STATE == CLOCK_SET) {  ST7789_DrawRectangle(clock_set_Pos[clock_set_Pos[2]], 50,  clock_set_Pos[clock_set_Pos[2]] + 100, 150, WHITE);  clock_set_Pos[2] = (clock_set_Pos[2] == 0) ? 1 : 0;  LCD_Already_Updated = false;  } else BEEP();  break;  case KEY4_PRES:  //红外选择通道:1/2/3/4  if(STATE == IR_CHANNEL_CHOOSE) {  IR_Channel = 0x04;  STATE = MENU;  LCD_Already_Updated = false;  ST7789_Fill_Color(WHITE);  } else if(STATE == TIME_SET) {  if(time_set_Pos[3] == 2) {  RTC_second = (RTC_second == 59) ? 0 : RTC_second + 1;  } else if(time_set_Pos[3] == 1) {  RTC_minute = (RTC_minute == 59) ? 0 : RTC_minute + 1;  } else {  RTC_hour = (RTC_hour == 23) ? 0 : RTC_hour + 1;  }  LCD_Already_Updated = false;  } else if(STATE == CLOCK_SET) {  if(clock_set_Pos[2] == 1) {  RTC_minute = (RTC_minute == 59) ? 0 : RTC_minute + 1;  } else {  RTC_hour = (RTC_hour == 23) ? 0 : RTC_hour + 1;  }  LCD_Already_Updated = false;  } else BEEP();  break;  }  LCD_Already_Updated = false;  } //else delay_ms(10); } 

完整代码可进群免费领取。


5 最后

嵌入式物联网的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而错失高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击下方链接,0元领取学习资源,让你的学习之路更加顺畅!记得点赞、关注、收藏、转发哦!

点击这里找小助理0元领取:扫码进群领资料


the end

评论(0)