stm32之智能垃圾桶实战

之前用过51做过一个垃圾桶的小项目,这里用32重新搞了一下。视频的效果和之前一样,可参考这个垃圾桶效果 。

一、项目描述(同51)

项目主要是模拟不用手动打开垃圾桶盖,而进行自动操作。自动打开的条件如下:

  • 1、垃圾桶检测到有人靠时自动打开桶盖
  • 2、发生震动时会自动打开
  • 3、可以手动按下按钮打开

二、项目用到的模块(同51)

  1. HC-SR04(超声波模块)
  2. SG90(舵机模块)
  3. MH-sensor-series(振动传感器)
  4. 蜂鸣器,一个指示灯

三,模拟引脚配置说明

  • HC-SR04trig <---> PB6(output), echo <---> PB7(input),TIM2 用于定时
  • SG90:PWM(黄色线) <---> PB9(TIM_CH4)
  • MH-sensor-series: D0<--->PB5(外部中断)
  • key: PA0(外部中断)
  • led1: PB8

下面是大致的配置说明

stm32之智能垃圾桶实战_第1张图片

stm32之智能垃圾桶实战_第2张图片

stm32之智能垃圾桶实战_第3张图片

四、代码

完整代码

main函数主要代码如下:

int opened = 0;
	
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{
	/* 使能定时器2计数 */
	__HAL_TIM_ENABLE(&htim2);
	__HAL_TIM_SetCounter(&htim2, 0);
	while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
	/* 关闭定时器2计数 */
	__HAL_TIM_DISABLE(&htim2);
}


double getDistance() {
	int count = 0;
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	TIM2_Delay_us(20);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);
	HAL_TIM_Base_Start(&htim2);
	__HAL_TIM_SetCounter(&htim2,0);
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);
	HAL_TIM_Base_Stop(&htim2);
	count = __HAL_TIM_GetCounter(&htim2);
	return 340 * 0.000001 * count * 100 / 2;
}

void beep() {
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
	HAL_Delay(100);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
}

/* sg90 -----------------------------------------------*/

void initSG90() {
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);
}

void openDusbin() {
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);
	HAL_Delay(2000);
}

void closeDusbin() {
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);
	opened = 0;
	HAL_Delay(150);
}

/* led -----------------------------------------------*/
void openStausLight() {
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
}

void closeStausLight() {
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}

void tryToOpenDusbin() {
	if(opened) {
		HAL_Delay(2000);
		return;
	}
	opened = 1;
	beep();
	openDusbin();
}

void tryToCloseBusbin() {
	opened = 0;
	closeDusbin();
}

/* key exti -----------------------------------------------*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
	if(GPIO_Pin == GPIO_PIN_0 || GPIO_Pin == GPIO_PIN_5) {
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_Pin) == GPIO_PIN_SET
			|| HAL_GPIO_ReadPin(GPIOB, GPIO_Pin) == GPIO_PIN_RESET
		) {
			openStausLight();
			tryToOpenDusbin();
		}
	}
}

int main(void)
{
  double distance;

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_TIM2_Init();
  initSG90();
	
  HAL_NVIC_SetPriority(SysTick_IRQn,0,0);

  while (1)
  {
    distance = getDistance();
		if(distance < 10) {
			openStausLight();
			tryToOpenDusbin();
		} else {
			closeStausLight();
			tryToCloseBusbin();
		}
		HAL_Delay(100);
  }
}
问题点记录:

1、CubeMX生成的注释不要手贱随便删除,否则如果配置更改了,重新利用CubeMx生成代码,可能会把之前的代码给删除了。

2、将stm32 滴答定时器的优先调高(项目里调到最高,默认15最低),同时把外部中断的优先级降低(项目里设置成2,默认是0最高),否则会造成卡死

3、一个函数的功能不做过于集中,比如项目中的openDusbin,拆成了tryToOpenDusbin(可以加些业务逻辑)+ openDusbin.

4、keil5 问题,光标输入错乱,F12进不了代码,关闭重新打开工程(O(∩_∩)O哈哈~

你可能感兴趣的:(stm32,嵌入式硬件,单片机)