🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 便携式STM32的红外信号分析仪
🥇学长这里给一个题目综合评分(每项满分5分)
🧿 选题指导, 项目分享:
由STM32F411CEU6作为主控芯片的带有姿态感应,红外输入,红外输出,可根据任意录入的红外信号进行存储,然后发出红外线控制各种电器设备, 并具有测电流,电压,电阻,电容能力的手表,是对于电子工程师来说具有较强实用性的小工具。
硬件
软件
主要原理图
#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);
}