无人机开发-投放装置-运输-钓鱼打窝

无人机开发-投放装置-运输-钓鱼打窝

·本人是个钓鱼佬,打窝经常不准,又麻烦,所以想到了用无人机打窝实现精准打窝

·适用于所有带有接收机的多旋翼/固定翼的简易投放装置


目录

无人机开发-投放装置-运输-钓鱼打窝

一、主要器件​

二、原理

三、代码

四、投放装置接线

五、结果


一、主要器件

飞控、PX4

任何带接收机飞控都可以使用不局限于PX4

无人机开发-投放装置-运输-钓鱼打窝_第1张图片

接收机、futeba   

接收机第八通道B/8是电源通道 分别从上到下对应是  信号 VCC GND ,接收机模式1/即默认模式 S.BUS和通道模式 

无人机开发-投放装置-运输-钓鱼打窝_第2张图片

遥控器、futeba

无人机开发-投放装置-运输-钓鱼打窝_第3张图片

次处理器、stm32f1

无人机开发-投放装置-运输-钓鱼打窝_第4张图片

uln2003芯片

此芯片可容纳更大的电压相比stm32直接驱动情况下,也可根据情况更换电机

无人机开发-投放装置-运输-钓鱼打窝_第5张图片

升降电机

无人机开发-投放装置-运输-钓鱼打窝_第6张图片

投放装置- 

简单的利用升降电机来达到开关效果

无人机开发-投放装置-运输-钓鱼打窝_第7张图片

还有无人机的相关配件这里就不一一写出了


二、原理

·ULN2003原理介绍

·STM32捕获原理介绍

·原理简单来说就是捕获遥控器通道信号stm32处理后给uln2003芯片 带动电机

无人机开发-投放装置-运输-钓鱼打窝_第8张图片

 

三、代码

main.

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"
#include "usart.h"
/*
经过打印测试得知 三个PWM信号时长分别是 2067~2068 1517~1518  967~968
捕获输入口------PA0
*/
extern u8  TIM2CH1_CAPTURE_STA;		//输入捕获状态		    				
extern u16	TIM2CH1_CAPTURE_VAL;	//输入捕获值
 int main(void)
 {	
	 
	u32 temp=0; 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	delay_init();	    	 //延时函数初始化
	LED_Init();              
	uart_init(9600);	 			//9600	 
 	TIM2_Cap_Init(0XFFFF,72-1);		//以1Mhz的频率计数 
   	while(1)
	{
 		delay_ms(10);
		TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);
		if(temp>2060&&temp<2080)	//判断输入通道
			{
				GPIO_SetBits(GPIOA,GPIO_Pin_8);//输出高
				GPIO_SetBits(GPIOD,GPIO_Pin_2);
				delay_ms(10);
			}
			else
			{
				
				GPIO_ResetBits(GPIOA,GPIO_Pin_8);	//输出低电平
				GPIO_ResetBits(GPIOD,GPIO_Pin_2);
			}
		if(TIM_GetCapture1(TIM1)==300)TIM_SetCompare1(TIM1,0);		 
		if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
		{
			temp=TIM2CH1_CAPTURE_STA&0X3F;
			temp*=65536;					//溢出时间总和
			temp+=TIM2CH1_CAPTURE_VAL;		//得到总的高电平时间
			printf("当前高电平时间:%d us\r\n",temp);	//打印总的高点平时间
 			TIM2CH1_CAPTURE_STA=0;			//开启下一次捕获
 		}
	}
}

定时器中断配置

#include "timer.h"
#include "led.h"
#include "usart.h"
#include "sys.h"
//arr:自动重装值
//psc:时钟预分频数

//定时器2通道1输入捕获配置
TIM_ICInitTypeDef  TIM2_ICInitStructure;

void TIM2_Cap_Init(u16 arr,u16 psc)
{	 
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能TIM2时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  //PA0 清除之前设置  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);						 //PA0 下拉
	
	//初始化定时器2 TIM2	 
	TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 	//预分频器   
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  
	//初始化TIM2输入捕获参数
	TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 	选择输入端 IC1映射到TI1上
  	TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕获
  	TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  	TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //配置输入分频,不分频 
  	TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
  	TIM_ICInit(TIM2, &TIM2_ICInitStructure);
	
	//中断分组初始化
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
	
	TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断	
	
  TIM_Cmd(TIM2,ENABLE ); 	//使能定时器2
 
}


u8  TIM2CH1_CAPTURE_STA=0;	//输入捕获状态		    				
u16	TIM2CH1_CAPTURE_VAL;	//输入捕获值
 
//定时器中断服务程序	 
void TIM2_IRQHandler(void)
{ 

 	if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获	
	{	  
		if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
		 
		{	    
			if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
			{
				if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
				{
					TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
					TIM2CH1_CAPTURE_VAL=0XFFFF;
				}else TIM2CH1_CAPTURE_STA++;
			}	 
		}
	if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
		{	
			if(TIM2CH1_CAPTURE_STA&0X40)		//捕获到一个下降沿 		
			{	  			
				TIM2CH1_CAPTURE_STA|=0X80;		//标记成功捕获到一次上升沿
				TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
		   		TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
			}else  								//还未开始,第一次捕获上升沿
			{
				TIM2CH1_CAPTURE_STA=0;			//清空
				TIM2CH1_CAPTURE_VAL=0;
	 			TIM_SetCounter(TIM2,0);
				TIM2CH1_CAPTURE_STA|=0X40;		//标记捕获到了上升沿
		   		TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);		//CC1P=1 设置为下降沿捕获
			}		    
		}			     	    					   
 	}
 
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
 
}

LED灯初始化

void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);	 //使能PA,PD端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //LED0-->PA.8 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA.8
 GPIO_SetBits(GPIOA,GPIO_Pin_8);				 		 //PA.8 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	    		 //LED1-->PD.2 端口配置, 推挽输出
 GPIO_Init(GPIOD, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOD,GPIO_Pin_2); 						 //PD.2 输出高 
}
 

 

四、投放装置接线

stm32 PA0--接收机通道口(需要接电 5V)

接收机B/8  接电源  通道信号口接STM32 PA0

ULN2003 1B接PD2  1C接电机负极 


五、结果

无人机开发-投放装置-运输-钓鱼打窝_第9张图片

无人机开发-投放装置-运输-钓鱼打窝_第10张图片

无人机开发-投放装置-运输-钓鱼打窝_第11张图片

结果完全满足 短距离投放等.

最后建议:无人机起飞全重不要超过7KG也不要在人多的地方飞行.注意重心调试

此文只供学习

 

 

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