基于便携式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元领取:扫码进群领资料
- 赞