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

基于STM32手势识别智能家居系统

基于STM32手势识别

(程序+原理图+PCB)

功能介绍

具体功能:

①选择小功率风扇、8位RGB全彩灯带、MP3音乐播放器以及DS18B20温度传感器来模拟一个小型的智能家居系统;

②选择手势识别的方式进行控制。基于PAJ7620能够识别的九种手势,配合一个两挡的拨动开关实现了两种工作模式的自由切换;

主要功能:

通过拨动开关可以使系统在以下两种工作模式下自由切换:

1、MP3音乐播放模式:

up:音量+

down:音量-

left:上一曲

right:下一曲

forward:播放

backward:暂停

2、智能控制模式:

forward:打开风扇(默认进入自动温控调速)

backward:关闭风扇

up:风扇手动加速

down:风扇手动减速

clockwise:打开RGB灯

anticlockwise:关闭RGB灯

right:RGB灯切换到下一种颜色

left:切换回上一种颜色

添加图片注释,不超过 140 字(可选)

程序

/* 包含头文件 ----------------------------------------------------------------*/
#include "main.h"
#include "delay.h"
#include "fan.h"
#include "ds18b20.h"
#include "usart.h"
#include "i2c.h"
#include "oled.h"
#include "MY1690.h"
#include "simu_i2c.h"
#include "paj7620.h"
#include "paj7620_led.h"
#include "WS2812.h"
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
/***微信公众号:木子单片机****/
/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
uint8_t Flag_SystemMode = 0;  //上电初始化为0,实时更新!   Flag = 1:工作模式1(MP3播放模式)   2:工作模式2(控制模式)
uint8_t Flag_FanMode = 0;  //上电初始化为0,工作模式2下更新   Flag = 0:风扇关闭   1:温控自动调速    2:手动调速
uint8_t Flag_RGBMode = 0;  //上电初始化为0,工作模式2下更新   Flag = 0:RGB灯关闭  1:RGB灯开启uint8_t FanSpeed = 0;  //风扇速度(可在140~200之间设置)
uint8_t RGB_Flash = RGB_red;  //缓存当前RGB彩灯的颜色
/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形声明 ----------------------------------------------------------*/
void SystemClock_Config(void);  //系统时钟配置
void SYSTEM_MODE_Init(void);  //配置工作模式选择引脚PA6/* 函数体 --------------------------------------------------------------------*/
/*** 函数功能: 主函数.* 输入参数: 无* 返 回 值: 无* 说    明: 无*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//*初始化--------------------------------------------------------------------*/HAL_Init();  //Reset of all peripherals, Initializes the Flash interface and the Systick./*系统初始化----------------------------------------------------------------*/SystemClock_Config();  //Configure the system clock./*用户的初始化程序(Initialize all configured peripherals)-------------------*//* GPIO Ports Clock (of SystemClock) Enable */__HAL_RCC_GPIOD_CLK_ENABLE();/* GPIO Ports Clock (of SW) Enable */__HAL_RCC_GPIOA_CLK_ENABLE();/* USER CODE BEGIN 2 */HAL_Delay(200);   //上电之后等待所有元器件就绪//尤其是MY1690芯片,如果上电之后不等待电压稳定就给它发指令,它是无法正确响应的Delay_Init();  //初始化延时函数SYSTEM_MODE_Init();  //配置工作模式选择引脚PA6I2C_EEPROM_Init();        //先初始化I2COLED_Init();              //再初始化OLEDOLED_DISPLAY_LIT(150);    //屏幕亮度设置OLED_PAGEStart();         //显示开机界面Read_Temperature();  //上电先读一次温度数据WS2812_Init();  //WS2812端口初始化FAN_Init();  //调速风扇初始化PAJ_LED_Init();  //手势指示灯初始化while(!paj7620u2_init())  //PAJ7620U2传感器初始化{//如果初始化失败则手势指示灯闪烁报警PAJ_LED_CTRL(LED_PORT, LE_PIN | RI_PIN | UP_PIN | DO_PIN|CW_PIN | AW_PIN | FW_PIN | BW_PIN, ON); //手势指示灯开delay_ms(300);PAJ_LED_CTRL(LED_PORT, LE_PIN | RI_PIN | UP_PIN | DO_PIN|CW_PIN | AW_PIN | FW_PIN | BW_PIN, OFF); //手势指示灯关delay_ms(300);}MY1690_Init();  //MP3芯片初始化/* USER CODE END 2 *//* Infinite loop */while (1){//检测用户当前选择的工作模式if(SYSTEM_MODE == MODE1){  //MP3播放模式switch(Flag_SystemMode){case 0:case 2:OLED_PAGEMode1();break;case 1:break;default:  break;}Flag_SystemMode=1;}else{  //智能控制模式switch(Flag_SystemMode){case 0:case 1:OLED_PAGEMode2();break;case 2:break;default:  break;}Flag_SystemMode=2;}//工作模式1(音乐模式)if(Flag_SystemMode == 1)  {Gesture_Recognition();  //读取手势数据if(gesture_data){switch(gesture_data){case GES_UP:                 PAJ_LED_CTRL(LED_PORT,UP_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*5, 26);OLED_DISPLAY_16x16(3, 8*7, 27);OLED_DISPLAY_8x16(3, 8*10, '+');  //OLED显示:音量 +delay_ms(500);PAJ_LED_CTRL(LED_PORT,UP_PIN,OFF);MY1690_VUP();      //音量+delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向上case GES_DOWM:               PAJ_LED_CTRL(LED_PORT,DO_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*5, 26);OLED_DISPLAY_16x16(3, 8*7, 27);OLED_DISPLAY_8x16(3, 8*10, '-');  //OLED显示:音量 -delay_ms(500);PAJ_LED_CTRL(LED_PORT,DO_PIN,OFF);MY1690_VDOWN();    //音量-delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向下case GES_LEFT:               PAJ_LED_CTRL(LED_PORT,LE_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*5, 20);OLED_DISPLAY_16x16(3, 8*7, 42);OLED_DISPLAY_16x16(3, 8*9, 28);  //OLED显示:上一曲delay_ms(500);PAJ_LED_CTRL(LED_PORT,LE_PIN,OFF);MY1690_PREV();     //上一首delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向左case GES_RIGHT:              PAJ_LED_CTRL(LED_PORT,RI_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*5, 21);OLED_DISPLAY_16x16(3, 8*7, 42);OLED_DISPLAY_16x16(3, 8*9, 28);  //OLED显示:下一曲delay_ms(500);PAJ_LED_CTRL(LED_PORT,RI_PIN,OFF);MY1690_NEXT();     //下一首delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向右case GES_FORWARD:            PAJ_LED_CTRL(LED_PORT,FW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*6, 14);OLED_DISPLAY_16x16(3, 8*8, 15);  //OLED显示:播放delay_ms(500);PAJ_LED_CTRL(LED_PORT,FW_PIN,OFF);MY1690_PLAY();	    //播放delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向前case GES_BACKWARD:           PAJ_LED_CTRL(LED_PORT,BW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*6, 32);OLED_DISPLAY_16x16(3, 8*8, 33);  //OLED显示:暂停delay_ms(500);PAJ_LED_CTRL(LED_PORT,BW_PIN,OFF);MY1690_PAUSE();    //暂停delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode1();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向后
//          case GES_CLOCKWISE:          PAJ_LED_CTRL(LED_PORT,CW_PIN,ON);
//                                       delay_ms(500);
//                                       PAJ_LED_CTRL(LED_PORT,CW_PIN,OFF);
//                                       break;                         //顺时针
//          case GES_COUNT_CLOCKWISE:    PAJ_LED_CTRL(LED_PORT,AW_PIN,ON);
//                                       delay_ms(500);
//                                       PAJ_LED_CTRL(LED_PORT,AW_PIN,OFF);
//                                       break;                         //逆时针
//					case GES_WAVE:    break;  //挥动(未使用,暂时屏蔽不做处理)default:   break;}gesture_data=0;  //处理完一个手势立即清除}delay_ms(50);  //读取手势数据的频率不能过于频繁,否则会影响PAJ7620对手势动作的正常识别}//工作模式2(控制模式)if(Flag_SystemMode == 2)  {Gesture_Recognition();  //读取手势数据if(gesture_data) {switch(gesture_data){case GES_UP:                 PAJ_LED_CTRL(LED_PORT,UP_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*3, 38);OLED_DISPLAY_16x16(3, 8*5, 39);OLED_DISPLAY_16x16(3, 8*7, 43);OLED_DISPLAY_16x16(3, 8*9, 37);OLED_DISPLAY_8x16(3, 8*12, '+');  //OLED显示:风扇转速 +delay_ms(500);PAJ_LED_CTRL(LED_PORT,UP_PIN,OFF);Flag_FanMode = 2;  //风扇切换为手动调速模式if(FanSpeed <= 195) FanSpeed+=5;delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向上case GES_DOWM:               PAJ_LED_CTRL(LED_PORT,DO_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*3, 38);OLED_DISPLAY_16x16(3, 8*5, 39);OLED_DISPLAY_16x16(3, 8*7, 43);OLED_DISPLAY_16x16(3, 8*9, 37);OLED_DISPLAY_8x16(3, 8*12, '-');  //OLED显示:风扇转速 -delay_ms(500);PAJ_LED_CTRL(LED_PORT,DO_PIN,OFF);Flag_FanMode = 2;  //风扇切换为手动调速模式if(FanSpeed >= 145) FanSpeed-=5;delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向下case GES_LEFT:               PAJ_LED_CTRL(LED_PORT,LE_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*3, 41);OLED_DISPLAY_16x16(3, 8*5, 50);OLED_DISPLAY_16x16(3, 8*7, 44);OLED_DISPLAY_16x16(3, 8*9, 45);OLED_DISPLAY_8x16(3, 8*12, '-');  //OLED显示:灯光颜色 -delay_ms(500);PAJ_LED_CTRL(LED_PORT,LE_PIN,OFF);if(Flag_RGBMode == 1)  //只有当RGB灯处于开启状态时,切换颜色的指令才会生效{if(RGB_Flash == 1) RGB_Flash=3;else RGB_Flash--;switch(RGB_Flash)  //读取当前RGB颜色缓存{case RGB_red:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[0]));//红break;case RGB_blue:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[1]));//蓝break;case RGB_green:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[2]));//绿break;default:  break;}}delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向左case GES_RIGHT:              PAJ_LED_CTRL(LED_PORT,RI_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*3, 41);OLED_DISPLAY_16x16(3, 8*5, 50);OLED_DISPLAY_16x16(3, 8*7, 44);OLED_DISPLAY_16x16(3, 8*9, 45);OLED_DISPLAY_8x16(3, 8*12, '+');  //OLED显示:灯光颜色 +delay_ms(500);PAJ_LED_CTRL(LED_PORT,RI_PIN,OFF);if(Flag_RGBMode == 1)  //只有当RGB灯处于开启状态时,切换颜色的指令才会生效{if(RGB_Flash == 3) RGB_Flash=1;else RGB_Flash++;switch(RGB_Flash)  //读取当前RGB颜色缓存{case RGB_red:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[0]));//红break;case RGB_blue:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[1]));//蓝break;case RGB_green:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[2]));//绿break;default:  break;}}delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向右case GES_FORWARD:            PAJ_LED_CTRL(LED_PORT,FW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(1, 8*2, 36);OLED_DISPLAY_16x16(1, 8*4, 37);OLED_DISPLAY_16x16(1, 8*6, 38);OLED_DISPLAY_16x16(1, 8*8, 39);OLED_DISPLAY_16x16(1, 8*12, 48);  //OLED显示:调速风扇 开OLED_DISPLAY_8x16(5, 8*1, '(');OLED_DISPLAY_16x16(5, 8*2, 51);OLED_DISPLAY_16x16(5, 8*4, 52);OLED_DISPLAY_16x16(5, 8*6, 53);OLED_DISPLAY_16x16(5, 8*8, 54);OLED_DISPLAY_16x16(5, 8*10, 36);OLED_DISPLAY_16x16(5, 8*12, 37);OLED_DISPLAY_8x16(5, 8*14, ')');  //OLED显示:(自动温控调速)delay_ms(500);PAJ_LED_CTRL(LED_PORT,FW_PIN,OFF);Flag_FanMode = 1;  //打开风扇,并且默认进入温控调速模式EN_FAN(1);  //电扇使能端口,高电平使能delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向前case GES_BACKWARD:           PAJ_LED_CTRL(LED_PORT,BW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_16x16(3, 8*2, 36);OLED_DISPLAY_16x16(3, 8*4, 37);OLED_DISPLAY_16x16(3, 8*6, 38);OLED_DISPLAY_16x16(3, 8*8, 39);OLED_DISPLAY_16x16(3, 8*12, 49);  //OLED显示:调速风扇 关delay_ms(500);PAJ_LED_CTRL(LED_PORT,BW_PIN,OFF);Flag_FanMode = 0;  //关闭风扇EN_FAN(0);  //电扇失能端口,低电平失能delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //向后case GES_CLOCKWISE:          PAJ_LED_CTRL(LED_PORT,CW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_8x16(3, 8*3, 'R');OLED_DISPLAY_8x16(3, 8*4, 'G');OLED_DISPLAY_8x16(3, 8*5, 'B');OLED_DISPLAY_16x16(3, 8*6, 40);OLED_DISPLAY_16x16(3, 8*8, 41);OLED_DISPLAY_16x16(3, 8*11, 48);  //OLED显示:RGB彩灯 开delay_ms(500);PAJ_LED_CTRL(LED_PORT,CW_PIN,OFF);Flag_RGBMode=1;  //打开RGB灯switch(RGB_Flash)  //读取当前RGB颜色缓存{case RGB_red:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[0]));//红break;case RGB_blue:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[1]));//蓝break;case RGB_green:WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[2]));//绿break;default:  break;}delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //顺时针case GES_COUNT_CLOCKWISE:    PAJ_LED_CTRL(LED_PORT,AW_PIN,ON);OLED_DISPLAY_CLEAR();OLED_DISPLAY_8x16(3, 8*3, 'R');OLED_DISPLAY_8x16(3, 8*4, 'G');OLED_DISPLAY_8x16(3, 8*5, 'B');OLED_DISPLAY_16x16(3, 8*6, 40);OLED_DISPLAY_16x16(3, 8*8, 41);OLED_DISPLAY_16x16(3, 8*11, 49);  //OLED显示:RGB彩灯 关delay_ms(500);PAJ_LED_CTRL(LED_PORT,AW_PIN,OFF);Flag_RGBMode=0;  //关闭RGB灯WS2812_Set_ALLColor(WS2812_RGB_Color(&colorful[3]));//灭delay_ms(Adjustable_parameter1);Gesture_Recognition();  //读取手势数据,清除手势识别中断标志寄存器1,避免连续误触发其他指令OLED_PAGEMode2();  //切回主界面,之后就可以给下一个手势指令了!系统响应一个手势指令之后,在切回主界面之前再给手势是不响应的!break;                         //逆时针//					case GES_WAVE:    break;  //挥动(未使用,暂时屏蔽不做处理)default:   break;}gesture_data=0;  //处理完一个手势立即清除}delay_ms(50);  //读取手势数据的频率不能过于频繁,否则会影响PAJ7620对手势动作的正常识别//调速风扇控制部分:
///*****************用户代码,更加符合实际使用需求*******************/
//      //风扇调速
//      if(Flag_FanMode == 1)  //如果系统处于温控自动调速模式下
//      {
//        Read_Temperature();  //更新温度数据
//        if(Tempbuffer[1] > 30){
//          FanSpeed=200;  //温度高于30摄氏度,则风扇达到满转速
//        }else if(Tempbuffer[1] > 28){
//          FanSpeed=190;
//        }else if(Tempbuffer[1] > 26){
//          FanSpeed=180;
//        }else if(Tempbuffer[1] > 24){
//          FanSpeed=170;
//        }else if(Tempbuffer[1] > 22){
//          FanSpeed=160;
//        }else if(Tempbuffer[1] > 20){
//          FanSpeed=150;
//        }else{
//          FanSpeed=140;  //温度低于20摄氏度,则风扇最低速度
//        }
//      }
///*****************用户代码,更加符合实际使用需求*******************//*****************调试代码,更明显地看出实时温控自动调速效果*******************///风扇调速if(Flag_FanMode == 1)  //如果系统处于温控自动调速模式下{Read_Temperature();  //更新温度数据if(Tempbuffer[1] > 25){FanSpeed=200;  //温度高于25摄氏度,则风扇达到满转速}else{FanSpeed=140;  //温度低于25摄氏度,则风扇最低速度}}
/*****************调试代码,更明显地看出实时温控自动调速效果*******************/__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, FanSpeed);  //设置PWM输出占空比为FanSpeed/200; 当占空比为100%时,电扇供电电压为12V,达到满转速//本设计用到的调速风扇有最小驱动电压限制,FanSpeed(比较寄存器的值)低于140时就无法驱动风扇转动了}}
}/*** 函数功能: 系统时钟配置* 输入参数: 无* 返 回 值: 无* 说    明: 无*/
void SystemClock_Config(void)
{ RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;HAL_RCC_OscConfig(&RCC_OscInitStruct);RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHzRCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟:72MHzRCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1时钟:36MHzRCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2时钟:72MHzHAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);HAL_RCC_EnableCSS();  //Enables the Clock Security System // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次// HAL_RCC_GetHCLKFreq()/100000	 10us中断一次// HAL_RCC_GetHCLKFreq()/1000000 1us中断一次HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器/* 系统滴答定时器时钟源 */HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* 系统滴答定时器中断优先级配置 */HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}/* USER CODE BEGIN 4 */
void SYSTEM_MODE_Init(void)  //配置工作模式选择引脚PA6
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = SYSTEM_MODE_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(SYSTEM_MODE_GPIO_Port, &GPIO_InitStruct);
}
/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}
*****//完整资料
*****//***微信公众号:木子单片机****/
#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{ /* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

硬件设计

使用元器件:

单片机:STM32F103;

添加图片注释,不超过 140 字(可选)

设计资料

01原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)

02程序

本设计使用软件Keil5 MDK版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

03PCB

本系统pcb采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

04设计资料

全部资料包括程序(含注释)、AD原理图、PCB、实物图等。具体内容如下,全网最全! !

添加图片注释,不超过 140 字(可选)

点赞分享一起学习成长。

http://www.xdnf.cn/news/1023391.html

相关文章:

  • 抖音AI数字人对口型软件LatentSync最新版整合包,音频驱动口型讲话
  • echarts图封装 自动切换 大屏 swiper 切换里面放echarts图,注意不要开循环 否则出不来
  • 图像处理算法的学习笔记
  • SpringBoot的Web应用开发——Web缓存利器Redis的应用!
  • 【UEFI系列】PEI阶段讲解
  • 生产环境LVM存储降级方案
  • Python训练营---DAY53
  • Git 前后端 Java Vue 项目的 .gitignore 配置分享
  • Linux环境下安装和使用RAPIDS平台的cudf和cuml - pip 安装方法
  • java集合(八) ---- Vector 类
  • 电磁铁性能检测所需工具
  • DataGrip 安装和连接Mysql
  • Eslint、Prettier、.vscode 配置
  • 阳台光伏新风口!安科瑞ADL200N-CT/D16-WF防逆流电表精准护航分布式发电
  • NLP学习路线图(四十三):零样本学习
  • 分布式爬虫系统设计与实现:跨节点MySQL存储方案
  • 导出支付宝账单步骤
  • 3款工具打造递进图:快速入门与个性化定制的实用指南
  • 帆软报表超级链接将查询控件的参数传递到子页面查询控件上
  • 谷歌具身智能VLA大模型 —— Gemini Robotics : 将人工智能带入到物理世界
  • 停产料PC28F128J3F75A存储芯片Micron镁光NOR Flash存储器工业级 电子元器件解析
  • AI LLM大模型逆向环境搭建radare2 + r2mcp + r2ghidra
  • AD左边工程面板消失重新打开
  • ansible常用内置模块
  • 13.18 Ollama+LLaMA3企业级部署实战:6步打造私有化大模型高效引擎
  • 【JVM】- 类加载与字节码结构1
  • AXI4-Stream Clock Converter IP
  • 封装python的docker镜像
  • 前端JavaScript面试题(2)
  • 面经总结池