STM32 感应开盖垃圾桶

Posted 一只小阿大:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 感应开盖垃圾桶相关的知识,希望对你有一定的参考价值。

软件平台

Keil uVision5
Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。

硬件平台

stm32最小系统

所需硬件

SG90电机,STM32最小系统,超声波模块,ttl转usb


超声波原理


距离公式: 高电平持续时间 * 声速(340/秒) / 2

超声波测距步骤

1.配置GPIO引脚结构体(Trig,Echo)。
2.配置定时器结构体
3.配置定时器中断结构体
4.开启时钟(定时器,GPIO)
5.Trig引脚输出高电平(10us以上),然后关闭
6.等待Echo引脚输入高电平开始,定时器打开—>开启计数器计数
7.等待Echo引脚输入高电平结束,定时器关闭—>停止计数器计数
8.通过计数器的值计算得出超声波测量距离

代码

超声波测距小于20cm,转动舵机

usart.h

#include "stm32f10x.h"
#include <stdio.h>

void usart_init(void);
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data);
void usartSendStr(USART_TypeDef* USARTx,char *str);

usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
	GPIO_InitTypeDef  gpio_init;
	USART_InitTypeDef usartStruct;
	NVIC_InitTypeDef  nvic_initStruct;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//2.ÅäÖÃGPIOµÄ½á¹¹Ìå
	//2.1 TX
	gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio_init.GPIO_Pin = GPIO_Pin_9;
	gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//2.2 RX
	gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio_init.GPIO_Pin = GPIO_Pin_10;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
	usartStruct.USART_BaudRate = 115200;
	usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	usartStruct.USART_Parity = USART_Parity_No;
	usartStruct.USART_StopBits = USART_StopBits_1;
	usartStruct.USART_WordLength = USART_WordLength_8b;
	
	USART_Init(USART1,&usartStruct);
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//ÅäÖô®¿ÚÖжÏ
	USART_Cmd(USART1, ENABLE );
	
	nvic_initStruct.NVIC_IRQChannel = USART1_IRQn;
	nvic_initStruct.NVIC_IRQChannelPreemptionPriority = 1;
	nvic_initStruct.NVIC_IRQChannelSubPriority = 1;
	nvic_initStruct.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&nvic_initStruct);

	
}

//·â×°ÁËһϷ¢ËÍ×Ö·û
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
	USART_SendData(USARTx,Data);
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

}

//·¢ËÍ×Ö·û´®
void usartSendStr(USART_TypeDef* USARTx,char *str)
{
	uint16_t i = 0;
	do{
		usartSendByte(USARTx,*(str+i));
		i++;
	}while(*(str+i) != '\\0');

	//ÅжÏÊÇ·ñ·¢ËÍÍê
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}

int fputc(int ch,FILE *f)
{
	USART_SendData(USART1,(uint8_t)ch);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	
	return (ch);
}

int fgetc(FILE *f)
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
	
	return (int) USART_ReceiveData(USART1);
}

motor.h

#include "stm32f10x.h"
void motor_Init(void);

motor.c

#include "stm32f10x.h"
#include "motor.h"
/*
    1.GPIO½á¹¹Ìå
		2.ͨÓö¨Ê±Æ÷½á¹¹Ìå
		3.PWM½á¹¹Ìå
		4.´ò¿ªÊ±ÖÓ
*/

//ʹÓõÄÊÇPB_5Òý½Å,ÖØÓ³ÉäTIM3£¬Í¨µÀ2

void motor_Init(void)
{
		GPIO_InitTypeDef 					Motor_GPiostruct;
		TIM_TimeBaseInitTypeDef   Motor_TIMStruct;
		TIM_OCInitTypeDef         Motor_TIMPWMStruct; 
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//Òý½ÅµÄʱÖÓ
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //¶¨Ê±Æ÷ʱÖÓ
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //ÖØÓ³ÉäÐèÒªµÄʱÖÓ

		GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//¿ªÆôÖØÓ³Éä
																											 //PartialRemap²¿·ÖÖØÓ³Éä
																											 //FullRemapÍêÈ«ÖØÓ³Éä
	
		Motor_GPIOStruct.GPIO_Mode         = GPIO_Mode_AF_PP;  //ÍÆÍ츴ÓÃÊä³ö(ÖØÓ³Éä)
		Motor_GPIOStruct.GPIO_Pin          = GPIO_Pin_5;       //Òý½Å 5
		Motor_GPIOStruct.GPIO_Speed        = GPIO_Speed_10MHz; 
	  GPIO_Init(GPIOB,&Motor_GPIOStruct);

		Motor_TIMStruct.TIM_ClockDivision  = TIM_CKD_DIV1;      //ÉèÖÃʱÖӷָTIM_CKD_DIV1ÊDz»·Ö¸î
	  Motor_TIMStruct.TIM_CounterMode    = TIM_CounterMode_Up;//TIMÏòÉϼÆÊýģʽ
	  Motor_TIMStruct.TIM_Period         = 200  - 1;					//ÉèÖÃÔÚϸö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔØÖµ
	  Motor_TIMStruct.TIM_Prescaler      = 7200 - 1;					//TIMxʱÖÓƵÂÊÔ¤·ÖƵֵ
		TIM_TimeBaseInit(TIM3,&Motor_TIMStruct);

		Motor_TIMPWMStruct.TIM_OCMode      = TIM_OCMode_PWM1;       //Ñ¡Ôñ¶¨Ê±Æ÷ģʽΪ±ßÑضÔÆëģʽ
		Motor_TIMPWMStruct.TIM_OutputState = TIM_OutputState_Enable;//±È½ÏÊä³öʹÄÜ
	  Motor_TIMPWMStruct.TIM_OCPolarity  = TIM_OCPolarity_Low;    //Ñ¡ÔñÓÐЧÊä³ö¼«ÐÔ
		TIM_OC2Init(TIM3,&Motor_TIMPWMStruct);//OC2´ú±íͨµÀ2  TIM3ͨµÀ2
		TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//ʹÄÜԤװÔؼĴæÆ÷
	  TIM_Cmd(TIM3,ENABLE);

}

ultrasonic.h

#ifndef __ULTRASONIC_H
#define __ULTRASONIC_H

#include "stm32f10x.h"

#define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)
											//Èç¹ûΪ1À­¸ßµçƽ£¬Îª0À­µÍµçƽ
#define TRIG_Send(a)  if(a) \\
											GPIO_SetBits(GPIOB,GPIO_Pin_11);\\
											else  \\
											GPIO_ResetBits(GPIOB,GPIO_Pin_11)

void ultrasonic_Config(void);
void Open_tim4(void);
void Close_tim4(void);
int GetEcho_time(void);
float Getlength(void);
											
#endif	/* __ULTRASONIC_H */	

ultrasonic.c

#include "stm32f10x.h"
#include "ultrasonic.h"
#include "SysTick.h"

/*
		1.ÅäÖÃGPIOÒý½Å½á¹¹Ìå(Trig PB11,Echo PB10)
		2.ÅäÖö¨Ê±Æ÷½á¹¹Ìå
		3.ÅäÖö¨Ê±Æ÷ÖжϽṹÌå
		4.¿ªÆôʱÖÓ(¶¨Ê±Æ÷£¬GPIO)
*/

uint16_t mscount;

void ultrasonic_Config(void)
{
		//½á¹¹Ìå³õʼ»¯
		GPIO_InitTypeDef        GPIO_UltrasonicInit;
		TIM_TimeBaseInitTypeDef TIM_UltrasonicInit;
		NVIC_InitTypeDef        NVIC_UltrasonicInit;
	
		//¿ªÆôʱÖÓ
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
		
		//´´½¨ÓÅÏȼ¶×é
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
		//Trig PB11
		GPIO_UltrasonicInit.GPIO_Mode  = GPIO_Mode_Out_PP;
		GPIO_UltrasonicInit.GPIO_Pin   = GPIO_Pin_11;
		GPIO_UltrasonicInit.GPIO_Speed = GPIO_Speed_10MHz;
	  GPIO_Init(GPIOB, &GPIO_UltrasonicInit);
	
		//Echo PB10
		GPIO_UltrasonicInit.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
		GPIO_UltrasonicInit.GPIO_Pin   = GPIO_Pin_10;
	  GPIO_Init(GPIOB, &GPIO_UltrasonicInit);
	
		//ÅäÖö¨Ê±Æ÷
		TIM_UltrasonicInit.TIM_ClockDivision = TIM_CKD_DIV1;
		TIM_UltrasonicInit.TIM_CounterMode   = TIM_CounterMode_Up;
		TIM_UltrasonicInit.TIM_Period        = 1000 - 1;
		TIM_UltrasonicInit.TIM_Prescaler     = 72  - 1;
	
		TIM_TimeBaseInit(TIM4,&TIM_UltrasonicInit);
	  TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
		TIM_Cmd(TIM4,DISABLE);

		//ÅäÖÃÖжÏ
		NVIC_UltrasonicInit.NVIC_IRQChannel                    = TIM4_IRQn;
		NVIC_UltrasonicInit.NVIC_IRQChannelPreemptionPriority  = 1;
		NVIC_UltrasonicInit.NVIC_IRQChannelSubPriority         = 1;
		NVIC_UltrasonicInit.NVIC_IRQChannelCmd                 = ENABLE;
		NVIC_Init(&NVIC_UltrasonicInit);

	
}

//´ò¿ª¶¨Ê±Æ÷4
void Open_tim4(void)
{
	  TIM_SetCounter(TIM4,0);//´Ó0¿ªÊ¼¼ÆÊý
		mscount = 0;
		TIM_Cmd(TIM4,ENABLE);
	
}

//¹Ø±Õ¶¨Ê±Æ÷4
void Close_tim4(void)
{
	  TIM_Cmd(TIM4,DISABLE);
	
}

//¶¨Ê±Æ÷4ÖжϺ¯Êý
void TIM4_IRQHandler(void)
{
		if(TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET){
				TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
				mscount++;
		}

}

//»ñÈ¡¶¨Ê±Æ÷¼ÆÊýÆ÷µÄÖµ
int GetEcho_time(void)
{
		uint32_t t = 0;
		t = mscount * 1000;
		t += TIM_GetCounter(TIM4);
		TIM4->CNT = 0;
		ms_delay(50);
	
		return t;
}

//»ñÈ¡³¬Éù²¨²â¾à¾àÀë
float Getlength(void)
{
		int i = 0;
		uint16_t t = 0;
		float length = 0;
		float total = 0;

		for(i = 0;i<5;i++)
		{
				TRIG_Send(1);
				us_delay(20);
				TRIG_Send(0);
		
				while(ECHO_Reci == 0);
				Open_tim4();
				
				while(ECHO_Reci == 1);
				Close_tim4();
				t = GetEcho_time();
				length = ((float)t / 58.0);
				total += length;
			
		}
		
		length = total/5.0;
		
		return length;
}

main.c

#include "stm32f10x.h"
#include "usart.h"
#include "motor.h"
#include "ultrasonic.h"

void delay(uint16_t time)
{
	uint16_t i =0;
	while(time--){
		i=12000;
		while(i--);
	}
}

int main()
{
		float Length = 0;

		usart_init();
		motor_Init();
		ultrasonic_Config();

//³¬Éù²¨¿ØÖƶæ»ú
		while(1)
		{
				Length = Getlength();
				if(Length <= 20){
						TIM_SetCompare2(TIM3,195);
						printf("SG90 OK!");
				}else{
						TIM_SetCompare2(TIM3,185);
				}
				
				printf("Length = %.3fcm\\r\\n",Length);
				ms_delay(500);
		
		}

}

遇到的问题

extern表明变量或者函数是定义在其他其他文件中
本来给mscount加了extern出现了Undefined symbol mscount (referred from ultrasonic.o).错误,开始以为是
1、没有将包含该函数的头文件包含进来。
2、没有头文件里面声明该函数
3、没有将该函数的.C文件加入工程里面

对照了三步好像都没啥问题,然后把extern删除就好了

注意:extern表明变量或者函数是定义在其他其他文件中

以上是关于STM32 感应开盖垃圾桶的主要内容,如果未能解决你的问题,请参考以下文章

STM32震动感应灯

Arduino智能垃圾桶

Arduino智能垃圾桶

Arduino智能垃圾桶

STM32震动感应控制继电器

基于STM32设计的智能插座+人体感应灯(ESP8266+人体感应+手机APP)