基于便攜式STM32的紅外信號分析儀 - 單片機 物聯(lián)網(wǎng) 嵌入式(含代碼)

便攜式STM32的紅外信號分析儀

  • 難度系數(shù):3分
  • 工作量:3分
  • 創(chuàng)新點:5分

1 簡介

由STM32F411CEU6作為主控芯片的帶有姿態(tài)感應,紅外輸入,紅外輸出,可根據(jù)任意錄入的紅外信號進行存儲,然后發(fā)出紅外線控制各種電器設備, 并具有測電流,電壓,電阻,電容能力的手表,是對于電子工程師來說具有較強實用性的小工具。

2 主要器件

  • STM32F411CEU6主控芯片
  • ACS712電流傳感器芯片
  • TC單片機

3 實現(xiàn)效果


4 設計原理

硬件

  • 電壓檢測電路,主要是將外部-15v15v的電壓通過幾個限壓電阻根據(jù)KCL和KVL轉(zhuǎn)化成03.3v,再由ADC芯片采集;
  • 電阻檢測電路,根據(jù)簡單的分壓原理,將待測電阻通過模擬開關(guān)分別與1k和1M歐高精度電阻串聯(lián)測得分壓,從而實現(xiàn)精確測量較大范圍內(nèi)的電阻阻值;
  • 電容檢測電路,根據(jù)電容的一階零狀態(tài)響應,算出時間常數(shù),再根據(jù)串聯(lián)的電阻計算出接入電容的電容值;
  • )紅外接收發(fā)射電路,采用外加一塊STC單片機(一個模塊~~~~),里面預先燒錄紅外解碼程序,再通過串口與STM32通訊,實現(xiàn)對外部輸入紅外信號的解碼和調(diào)制發(fā)射;

軟件

  • 姿態(tài)解算算法,實現(xiàn)步數(shù)計算,抬手感應,翻腕感應,LCD虛擬觸屏;
  • 針對不同紅外信號的解碼和發(fā)射算法,紅外信號存儲算法等;
  • 電阻,電容測量算法;
  • 自制定時器系統(tǒng)任務調(diào)度算法。

主要原理圖

5 部分核心代碼

#include "main.h" /********************變量聲明區(qū)_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;		//加速度傳感器原始數(shù)據(jù)

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};		//顯示紅外碼存儲區(qū)是否為空:0-空 1-有
uint16_t time_set_Pos[4] = {54, 102, 150, 2};
uint16_t clock_set_Pos[3] = {5, 135, 1};

/**  * @brief 決定系統(tǒng)狀態(tài)的選擇  * @param 菜單;紅外收發(fā)模式;紅外通道選擇模式;陀螺儀模式;模擬量測試模式;
 */
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;
/********************變量聲明區(qū)_END********************/



/********************API聲明區(qū)_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聲明區(qū)_END********************/



/********************************************************************************************************* * 函    數(shù): 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);  } }





/********************************************************************************************************* * 內(nèi)部函數(shù)實現(xiàn) *********************************************************************************************************/
/********************************************************************************************************* * 函數(shù)名稱: Proc2msTask * 函數(shù)功能: 處理2ms任務 * 輸入?yún)?shù): void * 輸出參數(shù): 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();  } }

/********************************************************************************************************* * 函數(shù)名稱: Proc50msTask * 函數(shù)功能: 處理50ms任務 * 輸入?yún)?shù): void * 輸出參數(shù): 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);//設置系統(tǒng)中斷優(yōu)先級分組2  delay_init(104);  			//初始化延時函數(shù)  uart_init(115200);			//初始化串口  InitTimer();				//初始化任務調(diào)度定時器  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);  }  //紅外收發(fā)模式  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);  }  //紅外收發(fā)模式  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); } 

完整代碼可進群免費領(lǐng)取。


5 最后

嵌入式物聯(lián)網(wǎng)的學習之路非常漫長,不少人因為學習路線不對或者學習內(nèi)容不夠?qū)I(yè)而錯失高薪offer。不過別擔心,我為大家整理了一份150多G的學習資源,基本上涵蓋了嵌入式物聯(lián)網(wǎng)學習的所有內(nèi)容。點擊下方鏈接,0元領(lǐng)取學習資源,讓你的學習之路更加順暢!記得點贊、關(guān)注、收藏、轉(zhuǎn)發(fā)哦!

點擊這里找小助理0元領(lǐng)取:掃碼進群領(lǐng)資料


the end

評論(0)