电磁炮程序(电子设计大赛)

主程序

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "encoder.h"
#include "usart.h"	
#include "motor.h"
#include "servo.h"
#include "oled.h"
#include "DataScope_DP.h"
#include "myIIC.h"
#include "mpu6050.h"
#include "stmflash.h"
#include "display.h"
#include "timer.h"
#include "2401.h"
#include "ocsct1.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h" 
#include "adc.h"
//ALIENTEK 探索者STM32F407开发板 实验4
//串口通信实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK
//要写入到STM32 FLASH的字符串数组
extern int D,A;
extern u8 send_flag,uart_flag;
extern int DISTANCE,Angle;
extern u8 UART_FLAG;
extern int distance;
extern u8 UART_RX3[6];
extern int DDDDD;
extern int x1,y;
extern int X_TINE_COUNT;
extern u8 zc;
extern int CHANG_ANGLE;
extern u8 X_FLAG;
extern u8 TURN_flag;
extern u8 turn_flag;
void find_angle()
{
		if(x_err>=5 && x_err<=10 && TURN_flag==1)
	    {
				send_flag=1;
		}
	   if(x_err>=150 && x_err<=155 && TURN_flag==0)
	   {
				send_flag=1;
	   }
}

void send_pao()
{
		if(send_flag==1)
		{
			 send_flag=0;
			 fangdian=0;// 充电前不能开启放电
			 delay_ms(200);
			 chongdian=1;//开始充电
			 delay_ms(1500);
			 chongdian=0;//充电结束
			 delay_ms(300);
			 fangdian=1;//开始放电
			 delay_ms(200);
			 fangdian=0;//放电结束
		}
}
void init()
{
	delay_init(168);		//延时初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	KEY_Init();
	LED_Init();
	TIM1_PWM_Init(9999,335);//50HZ  精度10000
	TIM_SetCompare1(TIM1,center_X);//900 500 680 //左小右大center_X//580 790
	TIM_SetCompare2(TIM1,center_Y);//900 1230 //上下center_Y
	uart_init2(9600);
  	uart_init3(115200);
  	TIM6_Int_Init(100-1,8400-1);
	OLED_Init();
	STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)flash_read,SIZE1);
	D=flash_read[0];
	A=flash_read[1];
}
int main(void)
{ 
  init();
	while(1)
	{
		OLED_ShowCHinese(0,0,0);//电磁炮发射线装置
		OLED_ShowCHinese(16,0,1);
		OLED_ShowCHinese(32,0,2);
		OLED_ShowCHinese(48,0,3);
		OLED_ShowCHinese(64,0,4);
		OLED_ShowCHinese(80,0,5);
		OLED_ShowCHinese(96,0,6);
		
		OLED_ShowCHinese(0,2,7);
		OLED_ShowCHinese(16,2,8);
		
		OLED_ShowCHinese(64,2,9);
		OLED_ShowCHinese(80,2,10);
		
		OLED_ShowCHinese(32,4,11);
		OLED_ShowCHinese(48,4,12);
		OLED_ShowCHinese(64,4,13);;
		if(KEY4_PRES==KEY_Scan(0))
		{
			OLED_Clear();
			break;
		}
	}
	while(1)
	{ 
		display();
		send_pao();
		if(turn_flag==1)
		{
			find_angle();
		}
	}
}




OLED显示程序

#include "display.h"
#include "oled.h"
#include "key.h"
#include "stmflash.h"
extern int D;
extern int A;

//u8 miaozhi=L;//选择基础或者发挥
//u8 bianliang=D_Y;//选择改变D或A


选择改变D或A
//void change_data(u8 bb)
//{
//			switch(KEY_Scan(0))
//	   {				 
//				  case KEY1_PRES:
//               bianliang= D_Y;						
//	             OLED_Clear();
//					break;
//				  case KEY2_PRES:
//  						 bianliang= A_Y;
//               OLED_Clear();
//					break;
//					case KEY3_PRES:
//               //OLED_Clear();
//	           //judge_choose();
//					break;
//					
//		}
//}

u8 MODE_FLAG=1;
u8 find_flag=0;
u8 turn_flag=0;
extern u8 UART_FLAG;
void change_mode(u8 aa)
{
	u8 stop_flag=0;
   while(1)
	 {
		 OLED_ShowString(0,0,"D:");
		 OLED_ShowNum(20,0,D,3,16);
		 OLED_ShowString(0,2,"A:");
		 OLED_ShowNum(20,2,A,3,16);
		 OLED_ShowString(0,4,"find:");
		 OLED_ShowNum(40,4,find_flag,1,16);
		 OLED_ShowString(0,6,"turn:");
	   OLED_ShowNum(40,6,turn_flag,1,16);
  		switch(KEY_Scan(0))
	   {				 
				  case KEY2_PRES:
						  if(aa==1){
							D+=2;
							if(D>=300)
								D=300;
							flash_write[0]=D;
							}
					    if(aa==2){
							A+=1;
						  if(A>=30)
								A=30;
							flash_write[1]=A;
							}
						  if(aa==3)find_flag=1;
					    if(aa==4)turn_flag=1;
	              OLED_Clear();
					break;
				  case KEY3_PRES:
						  if(aa==1){
							D-=2;
							if(D<=200)
								D=200;
							flash_write[0]=D;
							}
					    if(aa==2){
							   A-=1;
								if(A<=-30)
								 A=-30;
							flash_write[1]=A;
							}
							if(aa==3)find_flag=0;
					    if(aa==4)turn_flag=0;
							  OLED_Clear();
					break;
					case KEY1_PRES:
						UART_FLAG=1;//允许执行中断程序
						stop_flag=1;
					break;
					
		 }
		 if(stop_flag==1)
		 {
			 STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)flash_write,SIZE1);
			 MODE_FLAG=1;
			 OLED_Clear();
			 break;
		 }
	 }
}


extern u8 send_flag;
void display()
{

		 switch(KEY_Scan(0))
	   {				 
				  case KEY2_PRES:
               MODE_FLAG++;
							 if(MODE_FLAG>4)
								 MODE_FLAG=1;
	             OLED_Clear();
					break;
				  case KEY3_PRES:
  						  MODE_FLAG--;
							 if(MODE_FLAG<1)
								 MODE_FLAG=4;
                OLED_Clear();
					break;
					case KEY4_PRES:
						   OLED_Clear();
	             change_mode(MODE_FLAG);
					break;
					case KEY5_PRES:  
						   send_flag=1;
					     OLED_Clear();
					break;
					
		 }
		 OLED_ShowString(0,0,"D:");
		 OLED_ShowNum(20,0,D,3,16);
		 OLED_ShowString(0,2,"A:");
		 OLED_ShowNum(20,2,A,3,16);
		 OLED_ShowString(0,4,"find:");
		 OLED_ShowNum(40,4,find_flag,1,16);
		 OLED_ShowString(0,6,"turn:");
		 OLED_ShowNum(40,6,turn_flag,1,16);
		 if(MODE_FLAG==1)OLED_ShowString(70,0,"1");
		 else if(MODE_FLAG==2)OLED_ShowString(70,2,"1");
		 else if(MODE_FLAG==3)OLED_ShowString(70,4,"1");
		 else OLED_ShowString(70,6,"1");
		 if(send_flag==1)OLED_ShowString(90,6,"ok");
}



 云台舵机控制程序

float servo_KP=0,servo_KI=0.085;
int X_servo_PID(int val,int aim)
{
	static int temp=0,duty=0;
  static int ThisError=0,LastError=0;
	static int pError=0,iError=0;
	static int PWM1;
  ThisError=(int)(aim-val);
  pError=ThisError-LastError;
  iError=ThisError;
  temp=(int)(servo_KP*pError+servo_KI*iError);
  LastError=ThisError; 
  duty+=temp;
	PWM1=duty+center_X;
	if(PWM1>max_X)PWM1=max_X;
  if(PWM1<min_X)PWM1=min_X;
  TIM_SetCompare1(TIM1,PWM1);
  return center_X+duty; 	
}

int Y_servo_PID(int val,int aim)
{
	static int temp1=0,duty1=0;
  static int ThisError1=0,LastError1=0;
	static int pError1=0,iError1=0;
  ThisError1=(int)(aim-val);
  pError1=ThisError1-LastError1;
  iError1=ThisError1;
  temp1=(int)(servo_KP*pError1+servo_KI*iError1);
  LastError1=ThisError1; 
  duty1+=temp1;
	if(duty1>150)duty1=150;//900
  if(duty1<-100)duty1=-100;//650
  TIM_SetCompare2(TIM1,750+duty1);//110 30 68 //左大右小	
	return duty1;
}
int Y_servo_pwm(int d)
{
	 static int Distance;
	 static int dd,last_dd;
	if(d>=200)
	{//距离需大于等于200
		 dd=d;
		 if(dd!=last_dd)
		 {
			 //云台Y轴模拟三阶比例输出
			 Distance =(int)(-0.000030*d*d*d+0.022546*d*d+-6.417342*d+1809.190229);
			// Distance=(int)(+0.000154*d*d*d+-0.034523*d*d+1.448813*d+1392.202060);
		 }
		 last_dd=dd;
		 if(Distance<min_Y) Distance=min_Y;
		 if(Distance>center_Y) Distance=center_Y;
		 TIM_SetCompare2(TIM1,Distance);//900 1230
		 return Distance;
  }
	else
	{
		TIM_SetCompare2(TIM1,center_Y);//900 1230
		return center_Y;
	}
}
int X_servo_pwm(int a)
{
	static int Pwm;
	static int aa,last_aa=1;
	aa=a;
	//云台X轴二阶比例输出
	if(aa!=last_aa)
	{
	  Pwm=(int)(0.000320*a*a+-5.503297*a+680.118881);
	}
	last_aa=aa;
	if(Pwm>max_X)Pwm=max_X;
	if(Pwm<min_X)Pwm=min_X;
	TIM_SetCompare1(TIM1,Pwm);//900 500 700 //左小右大
	return Pwm;
}

//	TIM1_PWM_Init(999,3359);
//	TIM_SetCompare1(TIM1,70);//110 30 68 //110 30 70


int ZCZC=830;
u8 TURN_flag=0;
int TIME_COUNT=0;
int CHANG_ANGLE=680;
extern u8 send_flag;
extern int x_err;
void Turn_servo(int time)
{
		TIME_COUNT++;
		if(TIME_COUNT==time)
		{
			TIME_COUNT=0;
			if(TURN_flag==0)ZCZC-=5;
			if(TURN_flag==1)ZCZC+=5;
			if(ZCZC>830)
			{
				ZCZC=830;
				TURN_flag=0;
			}
			if(ZCZC<530)
			{
				ZCZC=530;
				TURN_flag=1;
			}
			TIM_SetCompare1(TIM1,ZCZC);//900 500 680 //左小右大
		}
}

摄像头串口数据接收程序

void Optical_Flow_Receive_Prepare(u8 data)
{
    /* 局部静态变量:接收缓存 */
    static u8 RxBuffer[4];
    /* 数据长度 *//* 数据数组下标 */
    static u8  _data_cnt = 0;
    /* 接收状态 */
    static u8 state = 0;
 
    /* 帧头1 */
    if(state==0&&data==TITLE1)
    {
        state=1;
    }
    /* 帧头2 */
    else if(state==1&&data==TITLE2)
    {
        state=2;
        _data_cnt = 0;
    }
    /* 接收数据租 */
    else if(state==2)
    {
			  uart_flag=1;//数据校验没问题,开启串口接收标志
        RxBuffer[++_data_cnt]=data;
        if(_data_cnt>=2)
        {
            state = 0;
            Data_Processing(RxBuffer,_data_cnt);
        }
    }
    /* 若有错误重新等待接收帧头 */
    else
        state = 0;
}
 
 
int x_err,y_err;
void Data_Processing(u8 *data_buf,u8 num)
{
	int theta_org,rho_org;
    /* 读取偏移角度原始数据  */
    //theta_org = (int)(*(data_buf+1)<<0) | (int)(*(data_buf+2)<<8) | (int)(*(data_buf+3)<<16) | (int)(*(data_buf+4)<<24) ;
    //theta_err = theta_org;
	
	  theta_org = (char)(*(data_buf+1)<<0); //| (char)(*(data_buf+2)<<8); //| (int)(*(data_buf+3)<<16) | (int)(*(data_buf+4)<<24) ;
    x_err = theta_org;
    /* 读取偏移尺寸原始数据 */
    //rho_org = (int)(*(data_buf+5)<<0) | (int)(*(data_buf+6)<<8) | (int)(*(data_buf+7)<<16) | (int)(*(data_buf+8)<<24) ;
    //rho_err = rho_org;
	  rho_org = (char)(*(data_buf+2)<<0); //| (char)(*(data_buf+4)<<8);//| (int)(*(data_buf+7)<<16) | (int)(*(data_buf+8)<<24) ;
	  y_err = rho_org;
	  
}

u8  UART_RX2[9];
u8 uart_flag=0;
u8 numzz;
void USART2_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res2;
//	u8 t2;	
//	u8 len2;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		//uart_flag=1;
		Res2 =USART_ReceiveData(USART2);//(USART1->DR);	//读取接收到的数据
		Optical_Flow_Receive_Prepare(Res2);
//		if((USART_RX_STA2&0x8000)==0)//接收未完成
//		{
//			if(USART_RX_STA2&0x4000)//接收到了0x0d
//			{
//				if(Res2!=0x0a)USART_RX_STA2=0;//接收错误,重新开始
//				else USART_RX_STA2|=0x8000;	//接收完成了 
//			}
//			else //还没收到0X0D
//			{	
//				if(Res2==0x0d)USART_RX_STA2|=0x4000;
//				else
//				{
//					USART_RX_BUF2[USART_RX_STA2&0X3FFF]=Res2 ;
//					USART_RX_STA2++;
//					if(USART_RX_STA2>(USART_REC_LEN-1))USART_RX_STA2=0;//接收数据错误,重新开始接收	  
//				}		 
//			}
//		}
//    if(USART_RX_STA2&0x8000)
//		 {					   
//				len2=USART_RX_STA2&0x3fff;//得到此次接收到的数据长度
//				for(t2=0;t2<len2;t2++)
//				{//接收OPENMV1
//					 UART_RX2[t2]=USART_RX_BUF2[t2];
//					 USART_RX_BUF2[t2]=0;
//				}
//			  USART_RX_STA2=0;
//		 }		
  } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
}

测距模块数据接收程序

u16 UART_RX3[9];
u8 DistanceBuff[6];
u8 numzc=0;
int DDDDD=0;
u8 zc;
extern u8 X_FLAG;
int distance;
void USART3_IRQHandler(void)                	//串口1中断服务程序
{
  static u8 seri_count=0;
  u16 check_sum=0;
  u8 i;
  static u8 flag;
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
		      zc=1;
          USART_ClearFlag(USART3, USART_FLAG_RXNE);
          USART_ClearITPendingBit(USART3, USART_IT_RXNE);
          if(USART_ReceiveData(USART3)==Data_Head)
          {
                        flag=1;
          }
					 if( flag==1)
					 {
                        UART_RX3[seri_count++]=USART_ReceiveData(USART3);
                        if(seri_count == 9)
                        {
                                if(UART_RX3[0]==Data_Head && UART_RX3[1]==Data_Head)
                                {
                                        for(i=0;i<9-1;i++)
                                        {
                                                check_sum+=UART_RX3[i];
                                        }
                                        if((check_sum & 0x00ff)==UART_RX3[8])
                                        {
                                                distance=UART_RX3[2]+UART_RX3[3]*256;
                                                seri_count=0;
                                                flag=0;
																				}
																	}
												}
						}
		}
}

中断处理函数

int x1,y;
extern u8 uart_flag;
extern int D,A;
int DISTANCE,Angle;
u8 UART_FLAG;
u8 TURN_OFF=0;
u8 X_FLAG=1,Y_FLAG;
int X_TINE_COUNT=0;
extern int DDDDD;
extern u8 send_flag;
extern int distance;
void camera_send1(void)
{
		if(TURN_OFF==1)
		{
			X_TINE_COUNT++;
		}
		if(X_TINE_COUNT==X_TIME)
		{//摄像头循迹关闭,打开激光测距
					X_FLAG=0;//摄像头循迹关闭,打开激光测距
					DDDDD= distance;
					if(DDDDD>330)DDDDD=330;
					if(DDDDD<230)DDDDD=230;
					DISTANCE=Y_servo_pwm(DDDDD-30);
		}
		 if(X_TINE_COUNT==SEND_TIME)
		 {
			 X_TINE_COUNT=0;
			 TURN_OFF=0;
			 UART_FLAG=0;
			 if(send_flag==0)
			 {
			 send_flag=1;//发射电磁炮
			 }
		 }
		if(X_FLAG==1)
		{//X轴摄像头循迹打开,关闭激光测距
			 if(uart_flag==1)//接到数据开始处理
			 {
				//uart_flag=0;	
				x1=X_servo_PID(x_err,X);	
				//X_TINE_COUNT++;
				TURN_OFF=1;	//关闭舵机自动打角				 
			 }
			 else
			 {//没有接受到数据,打角找坐标
				 if(TURN_OFF==0)
				 {
						Turn_servo(10);
				 }
			 }
	  }
}

extern u8 find_flag;
extern u8 turn_flag;
void TIM6_DAC_IRQHandler(void)
{ 
	if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
	{
		if(UART_FLAG==1)
		{//允许执行中断程序
        		if(find_flag==1)
				{
					camera_send1();
				}
				else if(turn_flag==1)
				{
					Turn_servo(10);
					DISTANCE=Y_servo_pwm(255);//1141	
				}
				else
				{
				  DISTANCE=Y_servo_pwm(D);
		          Angle=X_servo_pwm(A);
				}
		}
	}
	TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值