当前位置: 首页 > news >正文

【毕业设计】便携式STM32的红外信号分析仪 - 单片机 物联网 嵌入式

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 设计原理
  • 5 部分核心代码
  • 5 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

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

🥇学长这里给一个题目综合评分(每项满分5分)

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

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


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 最后

相关文章:

  • 广州地铁将在十三号线、二十一号线新增5个地铁口,位置在这里
  • 孙卫琴的《精通Vue.js》读书笔记-Vuex中异步操作
  • Java设计模式之策略模式
  • 【HMS core】【FAQ】音频编辑服务、推送服务、AR Engine典型问题合集
  • Android毕业论文选题基于Uniapp+Springboot实现的智能患者服药提醒APP处方药方
  • 详解Mysql中日期比较大小的方法
  • Java性能优化:Stream如何提高遍历集合效率?
  • SSM岭师旧书回收系统毕业设计-附源码041921
  • Java开发中常用的框架有哪些?
  • 如何快速在线扫描文档?Web TWAIN SDK 教你轻松解决
  • JSONredis
  • 与5G一起过中秋,天涯变咫尺
  • 进入docker容器命令行
  • java实战项目视频,2022年大厂Java高级面试题分享
  • Jira - create project
  • 【Leetcode】101. 对称二叉树
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • Create React App 使用
  • C学习-枚举(九)
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS学习笔记——闭包
  • react-native 安卓真机环境搭建
  • Redis在Web项目中的应用与实践
  • Vue2 SSR 的优化之旅
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 微信小程序设置上一页数据
  • 源码安装memcached和php memcache扩展
  • Spring Batch JSON 支持
  • 昨天1024程序员节,我故意写了个死循环~
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (分布式缓存)Redis分片集群
  • *p++,*(p++),*++p,(*p)++区别?
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET4.0并行计算技术基础(1)
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • ??在JSP中,java和JavaScript如何交互?
  • @ComponentScan比较
  • @Service注解让spring找到你的Service bean
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [ JavaScript ] JSON方法
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色
  • [Android]通过PhoneLookup读取所有电话号码
  • [Angularjs]ng-select和ng-options
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [bzoj4240] 有趣的家庭菜园
  • [C++]二叉搜索树
  • [CareerCup] 17.8 Contiguous Sequence with Largest Sum 连续子序列之和最大
  • [elastic 8.x]java客户端连接elasticsearch与操作索引与文档