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 感应开盖垃圾桶的主要内容,如果未能解决你的问题,请参考以下文章