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

news/2024/10/30 19:32:32/

主程序

#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);//设置系统中断优先级分组2KEY_Init();LED_Init();TIM1_PWM_Init(9999,335);//50HZ  精度10000TIM_SetCompare1(TIM1,center_X);//900 500 680 //左小右大center_X//580 790TIM_SetCompare2(TIM1,center_Y);//900 1230 //上下center_Yuart_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;//900if(duty1<-100)duty1=-100;//650TIM_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){//距离需大于等于200dd=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 1230return Distance;}else{TIM_SetCompare2(TIM1,center_Y);//900 1230return 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 70int 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);}}/* 若有错误重新等待接收帧头 */elsestate = 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();    
#endifif(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);
}


http://www.ppmy.cn/news/213004.html

相关文章

基于米思齐的电磁炮基础代码

主程序&#xff1a; 代码&#xff1a; #include <Servo.h>volatile int 按钮; volatile int 充电继电器; volatile int 发射继电器; volatile int 充电继电器状态; volatile int 发射继电器状态; volatile int 舵机1角度; volatile int 舵机2角度; Servo servo_6; Serv…

冲刺电赛之电磁炮的制作-控制层

来了来了&#xff0c;有点迟&#xff0c;今天给大家讲一下电磁炮控制层的代码。首先人机交互&#xff0c;我这里和题目要求的有一点点的不一样&#xff0c;题目说是用键盘控制&#xff0c;我选择用的是蓝牙&#xff0c;型号HC-08&#xff0c;这是我用过HC系列最好用的&#xff…

2019年电赛电磁炮,冲刺国赛

先自报家门吧&#xff0c;本人大二&#xff0c;来自双一流大学&#xff0c;具体那个大学就不介绍了&#xff0c;在大一的时候就进入了专业实验室&#xff0c;本参与实验的培训&#xff0c;学习了很多关于单片机的知识&#xff0c;在今年&#xff0c;学校组织参加电赛&#xff0…

模拟电磁炮国一设计资料【2019电赛H题国一作品】

经历重重测试&#xff0c;从初赛杀进综测再到去上海复测&#xff0c;真是一路坎坷啊&#xff01;回顾电赛准备阶段&#xff0c;在实验室基地的我们熬了多少个夜&#xff0c;废寝忘食的学习…仅仅是为了能更有信心的面对电赛&#xff1b;在电赛的四天三夜中我们经历了太多&#…

2019年全国大学生电子竞赛 | 电磁炮制作教程

​ 需要此套件的联系我。 原文链接&#xff1a;https://mp.weixin.qq.com/s/T6xCl9XbWBi3ap1FagtjIA

STM32模拟电磁炮设计_STM32F103ZET6(程序+原理图+PCB+论文报告)

本设计&#xff1a; 基于STM32模拟电磁炮设计_STM32F103ZET6&#xff08;程序原理图PCB论文报告&#xff09; 原理图&#xff1a;Altium Designer 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 编号C0029 设计说明&#xff1a; 该系统方案主要由 STM32f103zet6单片…

【电赛合集】19电磁炮.zip、17板球.zip、15风力摆.zip、13倒立摆.zip、(1994-2021)全国大学生电子设计竞赛历年真题.zip

【电赛合集】19电磁炮.zip、17板球.zip、15风力摆.zip、13倒立摆.zip、&#xff08;1994-2021&#xff09;全国大学生电子设计竞赛历年真题.zip 电赛宝藏链接&#xff1a; 四天三夜&#xff0c;那布满着未知与紧迫感的气息让荷尔蒙无比兴奋&#xff0c;挑战着脑力与体力的极限…