STM32感应垃圾桶
学习最重要的是学会学以致用,基于学习的一些简单串口、定时器、中断…
来做一个简单的感应垃圾桶,在制作过程中也提高了自己调试能力,虽然说是简单的串口打印测试还是花了很久时间,感谢自己的坚持和学长的帮助。最终还是成功完成了该小项目(冲冲冲)
所需硬件
miniSTM32 |
---|
HCSR04超声波 |
SG90舵机 |
若干杜邦线 |
USB转TTL |
直接上代码
//1.HCSR04 配置部分
#include "stm32f10x.h"
//宏定义相应的引脚
#define HCSR04_PORT GPIOB
#define HCSR04_CLK RCC_APB2Periph_GPIOB
#define HCSR04_TRIG GPIO_Pin_11
#define HCSR04_ECHO GPIO_Pin_10
//定义一个变量来记录定时器的值
u16 msHcCount = 0;
//中断配置
void hcsr04_NVIC()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//超声波配置¯
void Hcsr04Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器结构体
GPIO_InitTypeDef GPIO_InitStructure; //GPIO结构体
RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE); //时钟使能
// trig pb11
GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
//echo pb10
GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //定时器时钟
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = (1000-1);
TIM_TimeBaseStructure.TIM_Prescaler =(72-1);
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //定时器中断配置这个千万不要忘记配置了
hcsr04_NVIC();
TIM_Cmd(TIM4,DISABLE);
}
//打开定时器
static void OpenTimerForHc()
{
TIM_SetCounter(TIM4,0); //初始化开始计数
msHcCount = 0;
TIM_Cmd(TIM4, ENABLE);
}
//关闭定时器
static void CloseTimerForHc()
{
TIM_Cmd(TIM4, DISABLE);
}
//定时器4中断函数
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update );
msHcCount++;
}
}
//获取时间
u32 GetEchoTimer(void)
{
u32 t = 0;
t = msHcCount*1000;
t += TIM_GetCounter(TIM4);
TIM4->CNT = 0;
delay_ms(50);
return t;
}
//计算测量距离
float Hcsr04GetLength(void )
{
u32 t = 0;
int i = 0;
float lengthTemp = 0;
float sum = 0;
while(i!=5)
{
TRIG_Send = 1;
delay_us(20);
TRIG_Send = 0;
while(ECHO_Reci == 0);
OpenTimerForHc();
i = i + 1;
while(ECHO_Reci == 1);
CloseTimerForHc();
t = GetEchoTimer();
lengthTemp = ((float)t/58.0);//cm
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
}
SG90配置
//motor.h
#include "stm32f10x.h"
void Motor_Init(void);
//SG90.c
#include "motor.h"
#include "stm32f10x.h"
void Motor_Init(void)
{
//GPIO结构体配置
GPIO_InitTypeDef GPIO_Config;
//定时器结构体
TIM_TimeBaseInitTypeDef TIME_Config;
//复用配置
TIM_OCInitTypeDef TIMEPWM_Config ;
//时钟使能
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 , ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 ,ENABLE); //部分映射
GPIO_Config.GPIO_Mode = GPIO_Mode_AF_PP ;//¸´ÓÿªÂ¥
GPIO_Config.GPIO_Pin = GPIO_Pin_5 ;
GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_Config);
TIME_Config.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIME_Config.TIM_CounterMode = TIM_CounterMode_Up ;
TIME_Config.TIM_Period = 200 - 1;
TIME_Config.TIM_Prescaler = 7200 - 1;
TIM_TimeBaseInit( TIM3, &TIME_Config);
TIMEPWM_Config .TIM_OCMode = TIM_OCMode_PWM1 ;
TIMEPWM_Config .TIM_OutputState = TIM_OutputState_Enable ;
TIMEPWM_Config .TIM_OCPolarity = TIM_OCPolarity_Low ;
TIM_OC2Init( TIM3, &TIMEPWM_Config);
TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Enable);
TIM_Cmd( TIM3, ENABLE);
}
Usart串口代码
//Usart.h
#include"stm32f10x.h"
void Usart_Init(void);
#include "usart.h"
#include "stm32f10x.h"
void Usart_Init(void)
{
GPIO_InitTypeDef Gpio_Init;
USART_InitTypeDef Usart_Init ;
NVIC_InitTypeDef nvic_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 ,ENABLE);
//tx A9
Gpio_Init.GPIO_Mode = GPIO_Mode_Out_PP;
Gpio_Init.GPIO_Pin = GPIO_Pin_9 ;
Gpio_Init.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA ,&Gpio_Init); //³õʼ»¯GPIO
//rx A10
Gpio_Init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
Gpio_Init.GPIO_Pin = GPIO_Pin_10 ;
GPIO_Init(GPIOA ,&Gpio_Init);
Usart_Init.USART_BaudRate = 115200;
Usart_Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None ;
Usart_Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ; /
Usart_Init.USART_Parity = USART_Parity_No ;
Usart_Init.USART_StopBits = USART_StopBits_1;
Usart_Init.USART_WordLength = USART_WordLength_8b ;
USART_Init (USART1 , &Usart_Init);
USART_ITConfig( USART1, USART_IT_RXNE , ENABLE);
USART_Cmd (USART1 ,ENABLE );
nvic_init.NVIC_IRQChannel = EXTI1_IRQn;
nvic_init.NVIC_IRQChannelCmd = ENABLE ;
nvic_init.NVIC_IRQChannelPreemptionPriority =1;
nvic_init.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvic_init);
}
//打印当个字符
void USARTSendChar(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
{
USARTSendChar(USARTx ,*(str+i));
i++;
}while(*(str+i)!='\0');
while(USART_GetITStatus( USARTx,USART_FLAG_TC) == RESET) ; //判断是否接受完成
}
//重定义Printf
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));
}
main.c主函数
#include "stm32f10x.h"
#include "usart.h"
#include "motor.h"
#include "hcsr04.h"
//主函数
int main(void)
{
float length;
int pwmval = 195 ;
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组
Hcsr04Init();
Motor_Init();
printf("xaio yin serial test\r\n");
Hcsr04Init();
printf("超声波初始化成功!\n");
while(1)
{
pwmval = 155 ; //设定最初舵机值
length = Hcsr04GetLength();
printf("%.3fcm\n\n",length); //打印距离
printf("\n");
delay_ms(1000);
if(length < 5)
{
for (pwmval = 195 ; pwmval >= 155 ; pwmval -=15)
{
TIM_SetCompare2(TIM3 , pwmval);
delay_ms(1000);
}
}
else if( pwmval >5)
{
TIM_SetCompare2(TIM3 , pwmval -20);
delay_ms(1000);
}
}
}
加油加油