基于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 字(可选)
点赞分享一起学习成长。