自动门锁
因为最近一直在忙毕设,所以STM32 Nucleo-C031C6的小项目开发有所耽搁,本次自动门锁的小项目设计,采用STM32 Nucleo-C031C6、HC-SR505、0.96寸OLED、SG90舵机共同完成。
利用HC-SR505进行AD信息采集,当人体靠近时,HC-SR505采集到数据信息并反馈给单片机,单片机通过分析数据,进行0.96寸OLED数据显示,SG90舵机旋转等操作,并实时将数据在串口助手上进行打印。
串口打印信息:
整体连线:
整体操作流程:
单片机上电后,通过判断按键是否按下,选择是否开始工作。按键1按下,led常亮,进入功能1。
功能1:人体经过红外传感器,进行数据采集,上传给单片机后,单片机控制舵机旋转(舵机模拟门锁),并在OLED屏上进行开门提示。当红外传感器没有采集到人体信息,关闭舵机,并在OLED屏上进行关门提醒。
再次按下按键1,led熄灭,进入功能2。
功能2:关闭所有功能,进入待机状态,并在OLED屏上进行关机提示,2秒过后,OLED屏关闭显示。
芯片引脚使用情况:
主函数代码:
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM3_Init(); HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4); OLED_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ OLED_ShowString(1, 1, "hello world!"); OLED_ShowString(2, 1, "Program loading."); OLED_ShowString(3, 1, " --1-- "); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,500); printf("功能选择中...\r\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(k==1) { HAL_ADC_Start_IT(&hadc1); i=ADC_Value/4000; n++; sum=sum+i; if(n>500)//采集500个数进行判断消抖 { if(sum>333)//采集到数据信息 { if(t==0) { t=1; OLED_Clear(); OLED_ShowString(1, 1, "identified!"); OLED_ShowString(2, 1, "open"); OLED_ShowString(3, 1, " --1-- "); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,1500); printf("门已开启,通行中...\r\n"); } i=0; n=0; sum=0; } else { if(t==1) { t=0; OLED_Clear(); OLED_ShowString(1, 1, "nothing!"); OLED_ShowString(2, 1, "close"); OLED_ShowString(3, 1, " --1-- "); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,500); printf("门已关闭,请耐心等待...\r\n"); } i=0; n=0; sum=0; } n=0; sum=0; } } else if(k==2) { if(k==2) { OLED_Clear(); OLED_ShowString(1, 1, "shutting down"); OLED_ShowString(3, 1, " --2-- "); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,500); HAL_Delay(2000); printf("正在关机...\r\n"); HAL_Delay(2000); OLED_Clear(); k=3; printf("已关机...\r\n"); } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
中断代码:
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_13) { LED_TOGGLE(); if(k==0) k=1; else if(k==1) k=2; else { k=1; printf("系统数据正在加载中,请耐心等待...\r"); OLED_ShowString(1, 1, "loading..."); } printf("系统功能转换中,转换至[功能%d]...\r\n",k); } }//中断配置按键 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)//中断回调函数--ad采集 { if(hadc->Instance == ADC1) { ADC_Value = HAL_ADC_GetValue(&hadc1); ADC_Volt = ADC_Value * 3300 / 4096; //UR1_Send_Info(); } }
本次基于STM32 Nucleo-C031C6设计的小项目均由手边现有的模块构成,hal库的学习也均采用STM32 Nucleo-C031C6当作学习板,所以本项目若存在什么缺陷,欢迎大家在评论区指出,本人会根据大家的意见继续改进项目,优化代码。
增加:因原代码中采用硬件i2c与pwm起冲突,所以将硬件i2c更改成了软件i2c,代码有些许不同,但源代码逻辑正常无需更改,只需更改部分oled代码。