一种具有三轴圆周64个圆球的弹道导弹变质心装置 一种具有三轴圆周64个圆球的弹道导弹变质心装置 技术领域 本实用新型涉及一种具有三轴圆周64个圆球的弹道导弹变质心装置,尤其是弹道导弹变质心装置。 背景技术 现有常规弹道导弹变质心装置是利用内部圆球的滚动来改变导弹质量中心的,它们都很难实现自由灵活的快速改变导弹的质量中心。一种具有三轴圆周64个圆球的弹道导弹变质心装置利用一个圆周上面的64个圆球在这个圆环的圆周上的滚动来改变导弹质量中心的目的。同时它具有3个圆环,分别是X、Y、Z,它们就像空间中的坐标轴一样两两相交90度。而且每个圆环上面都有64个圆球,这63个圆球在这个圆周上面滚动就可以改变导弹的质量中心。 实用新型内容 为了解决常规弹道导弹变质心装置很难灵活方便的改变导弹质心的目的,一种具有三轴圆周64个圆球的弹道导弹变质心装置提供了一种非常容易快速改变导弹质心的装置。这个装置是一种利用三个圆周上面的64个圆球在圆周上面的滚动来改变导弹质心的装置。这三个圆周按照空间中的X、Y、Z三个轴一样分布,它们两两垂直90度。 本实用新型解决其技术问题所采用的技术方案是:一种具有三轴圆周64个圆球的弹道导弹变质心装置,是安装在弹道导弹弹体中部的一个圆环型装置。该弹道导弹的弹头(1)安装在导弹单体(2)上部,变质心装置的圆环(3)安装在导弹弹体中部,火箭发动机(4)安装在导弹底部。如图1所示,变质心装置由圆环和安装在圆环上面的64个圆球组成,这64个圆球可以在圆环上面滚动,进而改变导弹的质心。如图2所示,64个圆球(5)安装在导弹变质心装置的一个圆环(3)上面。这64个圆球分别安装在相互垂直的3个圆环(7),(8),(9)上面。64个圆球(5)分别用圆环圆心处的圆杆(6)和圆环的圆心相连,64个圆球(5)被和圆环圆心相连的圆杆(6)拉着在圆环(3)上面滚动,就会使导弹单体的质心发生改变,进而会使打导弹的质心发生改变。如图3所示,3个圆环(7),(8),(9)分别控制着空间中X,Y,Z三个轴的质心,利用圆杆(6)围绕圆环(7),(8),(9)圆心的转动,进而改变圆球(5)在圆环上面的滚动,就会改变这个圆环的质心,进而改变导弹的质心。 同时可以讲相邻的8个圆球分为一组,这样就可以将每个圆环上面的64个圆球分为8组,只要同时改变8个圆球在圆环上面的滚动方向就可以改变一个方向上面的质心。同时利用电磁铁代替圆球,同时增大或减少8个相邻电磁铁的电压,就会使8组电磁铁之间的电磁力减小或增大,进而就会改变一个方向上面的质心,进而就会改变导弹的质心。 利用单片机STC8A8K64S4A12控制8路PWM波形的占空比增大或者减小,再利用PWM驱动电路,将PWM的5V电压升高为24V,就会代替64圆球的64个电磁铁的磁性增大或者减小,进而改变圆环在一个方向上面的质心,进而改变导弹在一个方向上面的质心。如图4所示,单片机STC8A8K64S4A12产生8路PWM波形。L298N驱动一路PWM波形使电磁铁产生电磁力。单片机STC8A8K64S4A12的控制程序可以在百度网盘上面下载微云文件分享:变质心下载地址:
程序的源代码如下: #include "config.h" #include "STC8xxx_PWM.H" #include "eeprom.h" #include "Exti.h" #include "time.h" #include <math.H> //#include "EEPROM.H" #include "USART.h" #include "delay.h" #define EE_ADDRESS1 0x0100 #define CMD_IDLE 0 #define CMD_READ 1 #define CMD_PROGRAM 2 #define CMD_ERASE 3 #define Baudrate1 115200UL #define ENABLE_IAP 0x80 //if SYSCLK<30MHz extern int xdata g_x,g_y,g_z; //陀螺仪矫正参数 extern float xdata a_x,a_y; //角度矫正参数 extern float data AngleX,AngleY; /************* 本地常量声明 / u8 code T_Strings[]={"去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。"}; / 本地变量声明 / u8 xdata tmp[1]; u16 addr; u8 data h; int data speed0=0,speed1=0,speed2=0,speed3=0; /机速度参数 int data PWM0=0,PWM1=0,PWM2=0,PWM3=0,PWM4=0,PWM5=0,PWM6=0,PWM7=0; //加载至PWM模块的参数 u8 xdata tmp1[1]; u8 i; #define EE_ADDRESS2 0x0300 void Timer0_Config(void); void Timer1_Config(void); void DisableEEPROM(void); void EEPROM_read_n(u16 EE_address,u8 DataAddress,u16 number); void EEPROM_write_n(u16 EE_address,u8 DataAddress,u16 number); void EEPROM_SectorErase(u16 EE_address); /*****************************/ /************* 外部函数和变量声明 *****************/ u8 CheckData(u8 dat) { if((dat >= '0') && (dat <= '9')) return (dat-'0'); if((dat >= 'A') && (dat <= 'F')) return (dat-'A'+10); if((dat >= 'a') && (dat <= 'f')) return (dat-'a'+10); return 0xff; } u16 GetAddress(void) { u16 address; u8 i; address = 0; if(COM1.RX_Cnt < 3) return 65535; //error if(COM1.RX_Cnt <= 5) //5个字节以内是扇区操作,十进制, 支持命令: E 0, E 12, E 120 // W 0, W 12, W 120 // R 0, R 12, R 120 { for(i=2; i<COM1.RX_Cnt; i++) {
if(CheckData(RX1_Buffer[i]) > 9) return 65535; //error address = address * 10 + CheckData(RX1_Buffer[i]); } if(address < 124) //限制在0~123扇区 { address <<= 9;
return (address); } } else if(COM1.RX_Cnt == 8) //8个字节直接地址操作,十六进制, 支持命令: E 0x1234, W 0x12b3, R 0x0A00 { if((RX1_Buffer[2] == '0') && ((RX1_Buffer[3] == 'x') || (RX1_Buffer[3] == 'X'))) { for(i=4; i<8; i++) { if(CheckData(RX1_Buffer[i]) > 0x0F) return 65535; //error address = (address << 4) + CheckData(RX1_Buffer[i]); } if(address < 63488) return (address); //限制在0~123扇区 } } return 65535; //error } //姿态计算***************************** void PWM_int (void) interrupt 22 //PWM中断函数 { PWMCFG = 0; //CBIF; //清除中断标志 } void PWMGO(void) { // int i=1; //设置需要使用的PWM输出口为强推挽模式 P20 = 0; P21 = 0; P22 = 0; P23 = 0; // P24 = 0; // P25 = 0; // P26 = 0; // P27 = 0; P2n_push_pull(0x0f); // PWM0-P2.0 PWM1-P2.1 PWM2-P2.2 PWM3-P2.3 PWM4-P2.4 PWM5-P2.5 PWM6-P1.6 PWM7-P1.7 //以上为I/0初始化** //使用定时器2作为时钟源 EAXSFR(); //访问XFR PWMCFG = 0x00; // 7位 6位 5位 4位 3位 2位 1位 0位 // CBIF //1 计数器归零中断标志 计数器归零触发ADC - - - - - - //0 归零时不触发ADC PWMIF = 0x00; // 7位 6位 5位 4位 3位 2位 1位 0位 // C7IF C6IF C5IF C4IF C3IF C2IF C1IF C0IF //相应PWM中断标志 PWMFDCR = 0x00; // 7位 6位 5位 4位 3位 2位 1位 0位 // INVCMP INVIO ENFD FLTFLIO EFDI FDCMP FDIO FDIF PWMCKS = 11; //7位6位5位 4位 3位 2位 1位 0位 // 置0 0-系统时钟分频 分频参数设定
// 1-定时器2溢出 时钟=系统时钟/([3:0]+1) //PWMC = 16000; // 15位寄存器,决定PWM周期,数值为1-32767,单位:脉冲时钟 PWMC = 10000; // 以下为每个PWM输出口单独设置 PWM0CR = 0x80; // 7位 6位 5位 4位3位 2位 1位 0位 // ENCnO CnINI - Cn_S ECnI ECnT2SI ECnT1SI //1: 允许PWM 初始高电平 IO选择 允许中断 允许T2点中断 允许T1点中断
//0: 禁止PWM 初始低电平 IO选择 禁止中断 禁止T2点中断 禁止T1点中断 PWM1CR = 0x80; PWM2CR = 0x80; PWM3CR = 0x80; PWM4CR = 0x80; PWM5CR = 0x80; PWM6CR = 0x80; PWM7CR = 0x80; /* PWM0HLD = 0x00; PWM1HLD = 0x00; PWM2HLD = 0x00; PWM3HLD = 0x00; PWM4HLD = 0x00; PWM5HLD = 0x00; PWM6HLD = 0x00; PWM7HLD = 0x00; / PWM0T1 = 2000+PWM010; PWM1T1 = 2000+PWM110; PWM2T1 = 2000+PWM210; PWM3T1 = 2000+PWM310; PWM4T1 = 2000+PWM410; PWM5T1 = 2000+PWM510; PWM6T1 = 2000+PWM610; PWM7T1 = 2000+PWM7*10; // PWM0T1 = 2000; // PWM1T1 = 2000; // PWM2T1 = 2000; // PWM3T1 = 2000; // PWM4T1 = 4000; // PWM5T1 = 4000; // PWM6T1 = 4000; // PWM7T1 = 4000; PWM0T2 = 2000; PWM1T2 = 2000; PWM2T2 = 2000; PWM3T2 = 2000; PWM4T2 = 2000; PWM5T2 = 2000; PWM6T2 = 2000; PWM7T2 = 2000; PWMCR = 0x80; //允许PWM EAXRAM(); //恢复访问XRAM } void UART_config(void) { COMx_InitDefine COMx_InitStructure; //结构定义 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx COMx_InitStructure.UART_BRT_Use = BRT_Timer1; //使用波特率, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2) COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE
COMx_InitStructure.UART_Polity = PolityLow; //中断优先级, PolityLow,PolityHigh COMx_InitStructure.UART_P_SW = UART1_SW_P30_P31; //切换端口, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17(必须使用内部时钟) COMx_InitStructure.UART_RXD_TXD_Short = DISABLE; //内部短路RXD与TXD, 做中继, ENABLE,DISABLE USART_Configuration(USART1, &COMx_InitStructure); //初始化串口1 USART1,USART2 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BaudRate = 57600ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE COMx_InitStructure.UART_Polity = PolityLow; //中断优先级, PolityLow,PolityHigh COMx_InitStructure.UART_P_SW = UART2_SW_P10_P11; //切换端口, UART2_SW_P10_P11,UART2_SW_P46_P47 USART_Configuration(USART2, &COMx_InitStructure); //初始化串口2 USART1,USART2 PrintString1("STC15F2K60S2 UART1 Test Prgramme!\r\n"); //SUART1发送一个字符串 PrintString2("STC15F2K60S2 UART2 Test Prgramme!\r\n"); //SUART2发送一个字符串 } // ===================== 主函数 ===================== void main(void) { //所有I/O口全设为准双向,弱上拉模式 P0M0=0x00; P0M1=0x00; P1M0=0x00; P1M1=0x00; P2M0=0x00; P2M1=0x00; P3M0=0x00; P3M1=0x00; P4M0=0x00; P4M1=0x00; P5M0=0x00; P5M1=0x00; P6M0=0x00; P6M1=0x00; P7M0=0x00; P7M1=0x00; PWMGO(); // u8 i; UART_config(); PWMCR = 0xc0;//ECBI; //允许PWM计数器归零中断 EA = 1; //允许总中断 while (1) { delay_ms(1); if(COM1.RX_TimeOut > 0) //超时计数 { if(--COM1.RX_TimeOut == 0) { if(COM1.RX_Cnt > 0) { for(i=0; i<COM1.RX_Cnt; i++) TX1_write2buff(RX1_Buffer[i]); //收到的数据原样返回 // EEPROM_SectorErase(0X0100); EEPROM_write_n(0X0100,RX1_Buffer,64);
EEPROM_read_n(0X0100,tmp1,64); P0=tmp1; //tmp[i]=RX1_Buffer[i]; // IAP_Gyro() ; // IAPRead(); // PWMAA(); // PWMBB(); if(!P00) { PWM0=PWM0-10; } else { PWM0=0; } if(!P01) { PWM1=PWM1-10; } else { PWM1=0; } if(!P02) { PWM2=PWM2-10; } else { PWM2=0; } if(!P03) { PWM3=PWM3-10; } else { PWM3=0; } if(!P04) { PWM4=PWM4-10; } else { PWM4=0; }
if(!P05) { PWM5=PWM5-10; } else { PWM5=0; } if(!P06) { PWM6=PWM6-10; } else { PWM6=0; } if(!P07) { PWM7=PWM7-10; } else { PWM7=0; } // PWM0=tmp[1]+tmp[2];
// PWM1=tmp[3]+tmp[4]; // PWM2=tmp[5]+tmp[6]; // PWM3=tmp[7]+tmp[8]; // PWM0=tmp[1]; // PWM1=tmp[2]; // PWM2=tmp[3]; // PWM3=tmp[4]; PWMGO(); } COM1.RX_Cnt = 0; } } if(COM2.RX_TimeOut > 0) //超时计数 { if(--COM2.RX_TimeOut == 0) { if(COM2.RX_Cnt > 0) { for(i=0; i<COM2.RX_Cnt; i++) TX2_write2buff(RX2_Buffer[i]); //收到的数据原样返回 // tmp[i]=RX1_Buffer[i]; tmp[i]=RX1_Buffer[i]; // EEPROM_SectorErase(0X0100); EEPROM_write_n(0X0100,RX1_Buffer,64); EEPROM_read_n(0X0100,tmp1,64); P0=tmp1; if(!P00) { PWM0=PWM0+10; } else { PWM0=0; } if(!P01) { PWM1=PWM1+10; } else { PWM1=0; } if(!P02) { PWM2=PWM2+10; } else { PWM2=0; } if(!P03) { PWM3=PWM3+10; } else { PWM3=0; } if(!P04) { PWM4=PWM4+10; } else { PWM4=0; } if(!P05) { PWM5=PWM5+10;
} else { PWM5=0; } if(!P06) { PWM6=PWM6+10; } else { PWM6=0; } if(!P07) { PWM7=PWM7+10; } else { PWM7=0; } PWMGO(); } COM2.RX_Cnt = 0; } } } } //======================================================================== // 函数: void ISP_Disable(void) // 描述: 禁止访问ISP/IAP.
// 参数: non. // 返回: non. // 版本: V1.0, 2012-10-22 //======================================================================== void DisableEEPROM(void) { ISP_CONTR = 0; //禁止ISP/IAP操作 ISP_CMD = 0; //去除ISP/IAP命令 ISP_TRIG = 0; //防止ISP/IAP命令误触发 ISP_ADDRH = 0xff; //清0地址高字节 ISP_ADDRL = 0xff; //清0地址低字节,指向非EEPROM区,防止误操作 } //======================================================================== // 函数: void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number) // 描述: 从指定EEPROM首地址读出n个字节放指定的缓冲. // 参数: EE_address: 读出EEPROM的首地址. // DataAddress: 读出数据放缓冲的首地址. // number: 读出的字节长度. // 返回: non. // 版本: V1.0, 2012-10-22 //======================================================================== void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number) { EA = 0; //禁止中断 ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //设置等待时间,允许ISP/IAP操作,送一次就够 ISP_READ(); //送字节读命令,命令不需改变时,不需重新送命令 do { ISP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址) ISP_ADDRL = EE_address % 256; //送地址低字节 ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP触发寄存器,每次都需要如此 //送完A5H后,ISP/IAP命令立即被触发启动
//CPU等待IAP完成后,才会继续执行程序。 nop(); DataAddress = ISP_DATA; //读出的数据送往 EE_address++; DataAddress++; }while(--number); DisableEEPROM(); EA = 1; //重新允许中断 } /******************* 扇区擦除函数 *****************/ //======================================================================== // 函数: void EEPROM_SectorErase(u16 EE_address) // 描述: 把指定地址的EEPROM扇区擦除. // 参数: EE_address: 要擦除的扇区EEPROM的地址. // 返回: non. // 版本: V1.0, 2013-5-10 //======================================================================== void EEPROM_SectorErase(u16 EE_address) { EA = 0; //禁止中断 //只有扇区擦除,没有字节擦除,512字节/扇区。 //扇区中任意一个字节地址都是扇区地址。 ISP_ADDRH = EE_address / 256; //送扇区地址高字节(地址需要改变时才需重新送地址) ISP_ADDRL = EE_address % 256; //送扇区地址低字节 ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //设置等待时间,允许ISP/IAP操作,送一次就够
ISP_ERASE(); //送扇区擦除命令,命令不需改变时,不需重新送命令 ISP_TRIG(); nop(); DisableEEPROM(); EA = 1; //重新允许中断 } //======================================================================== // 函数: void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number) // 描述: 把缓冲的n个字节写入指定首地址的EEPROM. // 参数: EE_address: 写入EEPROM的首地址. // DataAddress: 写入源数据的缓冲的首地址. // number: 写入的字节长度. // 返回: non. // 版本: V1.0, 2012-10-22 //======================================================================== void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number) { EA = 0; //禁止中断 ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //设置等待时间,允许ISP/IAP操作,送一次就够 ISP_WRITE(); //送字节写命令,命令不需改变时,不需重新送命令 do { ISP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址) ISP_ADDRL = EE_address % 256; //送地址低字节 ISP_DATA = *DataAddress; //送数据到ISP_DATA,只有数据改变时才需重新送 ISP_TRIG(); nop(); EE_address++; DataAddress++; }while(--number); DisableEEPROM(); EA = 1; //重新允许中断 }
#include "USART.h" COMx_Define COM1,COM2; u8 xdata TX1_Buffer[COM_TX1_Lenth]; //发送缓冲 u8 xdata RX1_Buffer[COM_RX1_Lenth]; //接收缓冲 u8 xdata TX2_Buffer[COM_TX2_Lenth]; //发送缓冲 u8 xdata RX2_Buffer[COM_RX2_Lenth]; //接收缓冲 u8 USART_Configuration(u8 UARTx, COMx_InitDefine *COMx) { u8 i; u32 j; if(UARTx == USART1) { COM1.id = 1; COM1.TX_read = 0; COM1.TX_write = 0; COM1.B_TX_busy = 0; COM1.RX_Cnt = 0; COM1.RX_TimeOut = 0; COM1.B_RX_OK = 0; for(i=0; i<COM_TX1_Lenth; i++) TX1_Buffer[i] = 0; for(i=0; i<COM_RX1_Lenth; i++) RX1_Buffer[i] = 0; if(COMx->UART_Mode > UART_9bit_BRTx) return 2; //模式错误 if(COMx->UART_Polity == PolityHigh) PS = 1; //高优先级中断 else PS = 0; //低优先级中断 SCON = (SCON & 0x3f) | COMx->UART_Mode; if((COMx->UART_Mode == UART_9bit_BRTx) ||(COMx->UART_Mode == UART_8bit_BRTx)) //可变波特率 { j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //按1T计算 if(j >= 65536UL) return 2; //错误 j = 65536UL - j;
if(COMx->UART_BRT_Use == BRT_Timer1) { TR1 = 0; AUXR &= ~0x01; //S1 BRT Use Timer1; TMOD &= ~(1<<6); //Timer1 set As Timer TMOD &= ~0x30; //Timer1_16bitAutoReload; AUXR |= (1<<6); //Timer1 set as 1T mode TH1 = (u8)(j>>8); TL1 = (u8)j; ET1 = 0; //禁止中断 TMOD &= ~0x40; //定时 INT_CLKO &= ~0x02; //不输出时钟 TR1 = 1; } else if(COMx->UART_BRT_Use == BRT_Timer2) { AUXR &= ~(1<<4); //Timer stop AUXR |= 0x01; //S1 BRT Use Timer2; AUXR &= ~(1<<3); //Timer2 set As Timer AUXR |= (1<<2); //Timer2 set as 1T mode TH2 = (u8)(j>>8); TL2 = (u8)j; IE2 &= ~(1<<2); //禁止中断 AUXR &= ~(1<<3); //定时
AUXR |= (1<<4); //Timer run enable } else return 2; //错误 } else if(COMx->UART_Mode == UART_ShiftRight) { if(COMx->BaudRateDouble == ENABLE) AUXR |= (1<<5); //固定波特率SysClk/2 else AUXR &= ~(1<<5); //固定波特率SysClk/12 } else if(COMx->UART_Mode == UART_9bit) //固定波特率SysClk*2^SMOD/64 { if(COMx->BaudRateDouble == ENABLE) PCON |= (1<<7); //固定波特率SysClk/32 else PCON &= ~(1<<7); //固定波特率SysClk/64 } if(COMx->UART_Interrupt == ENABLE) ES = 1; //允许中断 else ES = 0; //禁止中断 if(COMx->UART_RxEnable == ENABLE) REN = 1; //允许接收 else REN = 0; //禁止接收 P_SW1 = (P_SW1 & 0x3f) | (COMx->UART_P_SW & 0xc0); //切换IO if(COMx->UART_RXD_TXD_Short == ENABLE) PCON2 |= (1<<4); //内部短路RXD与TXD, 做中继, ENABLE,DISABLE else PCON2 &= ~(1<<4); return 0; } if(UARTx == USART2) { COM2.id = 2; COM2.TX_read = 0; COM2.TX_write = 0; COM2.B_TX_busy = 0; COM2.RX_Cnt = 0; COM2.RX_TimeOut = 0; COM2.B_RX_OK = 0; for(i=0; i<COM_TX2_Lenth; i++) TX2_Buffer[i] = 0; for(i=0; i<COM_RX2_Lenth; i++) RX2_Buffer[i] = 0;
if((COMx->UART_Mode == UART_9bit_BRTx) ||(COMx->UART_Mode == UART_8bit_BRTx)) //可变波特率 { if(COMx->UART_Polity == PolityHigh) IP2 |= 1; //高优先级中断 else IP2 &= ~1; //低优先级中断 if(COMx->UART_Mode == UART_9bit_BRTx) S2CON |= (1<<7); //9bit else S2CON &= ~(1<<7); //8bit j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //按1T计算 if(j >= 65536UL) return 2; //错误 j = 65536UL - j; AUXR &= ~(1<<4); //Timer stop AUXR &= ~(1<<3); //Timer2 set As Timer AUXR |= (1<<2); //Timer2 set as 1T mode
TH2 = (u8)(j>>8); TL2 = (u8)j; IE2 &= ~(1<<2); //禁止中断 AUXR |= (1<<4); //Timer run enable } else return 2; //模式错误 if(COMx->UART_Interrupt == ENABLE) IE2 |= 1; //允许中断 else IE2 &= ~1; //禁止中断 if(COMx->UART_RxEnable == ENABLE) S2CON |= (1<<4); //允许接收 else S2CON &= ~(1<<4); //禁止接收 P_SW2 = (P_SW2 & ~1) | (COMx->UART_P_SW & 0x01); //切换IO } } /*************** 装载串口发送缓冲 *******************************/ void TX1_write2buff(u8 dat) //写入发送缓冲,指针+1 { TX1_Buffer[COM1.TX_write] = dat; //装发送缓冲 if(++COM1.TX_write >= COM_TX1_Lenth) COM1.TX_write = 0; if(COM1.B_TX_busy == 0) //空闲 { COM1.B_TX_busy = 1; //标志忙 TI = 1; //触发发送中断 } } void TX2_write2buff(u8 dat) //写入发送缓冲,指针+1 { TX2_Buffer[COM2.TX_write] = dat; //装发送缓冲 if(++COM2.TX_write >= COM_TX2_Lenth) COM2.TX_write = 0; if(COM2.B_TX_busy == 0) //空闲 { COM2.B_TX_busy = 1; //标志忙 SET_TI2(); //触发发送中断 } } void PrintString1(u8 *puts) { for (; *puts != 0; puts++) TX1_write2buff(*puts); //遇到停止符0结束 } void PrintString2(u8 *puts) { for (; *puts != 0; puts++) TX2_write2buff(puts); //遇到停止符0结束 } / void COMx_write2buff(COMx_Define *COMx, u8 dat) //写入发送缓冲,指针+1 { if(COMx->id == 1) TX1_write2buff(dat); if(COMx->id == 2) TX2_write2buff(dat); }
void PrintString(COMx_Define COMx, u8 puts) { for (; puts != 0; puts++) COMx_write2buff(COMx,puts); //遇到停止符0结束 } / /**************** UART1中断函数************************/ void UART1_int (void) interrupt UART1_VECTOR { if(RI) { RI = 0; if(COM1.B_RX_OK == 0) { if(COM1.RX_Cnt >= COM_RX1_Lenth) COM1.RX_Cnt = 0; RX1_Buffer[COM1.RX_Cnt++] = SBUF; COM1.RX_TimeOut = TimeOutSet1; } } if(TI) { TI = 0; if(COM1.TX_read != COM1.TX_write) {
SBUF = TX1_Buffer[COM1.TX_read]; if(++COM1.TX_read >= COM_TX1_Lenth) COM1.TX_read = 0; } else COM1.B_TX_busy = 0; } } /********************* UART2中断函数************************/ void UART2_int (void) interrupt UART2_VECTOR { if(RI2) { CLR_RI2(); if(COM2.B_RX_OK == 0) { if(COM2.RX_Cnt >= COM_RX2_Lenth) COM2.RX_Cnt = 0; RX2_Buffer[COM2.RX_Cnt++] = S2BUF; COM2.RX_TimeOut = TimeOutSet2; } } if(TI2) { CLR_TI2(); if(COM2.TX_read != COM2.TX_write) { S2BUF = TX2_Buffer[COM2.TX_read]; if(++COM2.TX_read >= COM_TX2_Lenth) COM2.TX_read = 0; } else COM2.B_TX_busy = 0; } } #include "delay.h" void delay_ms(unsigned char ms) { unsigned int i; do{ i = MAIN_Fosc / 13000; while(--i) ; //14T per loop }while(--ms); } 使用KEILL4软件编译上述程序,同时,用台湾宏晶科技有限公司的单片机下载程序stc-isp-15xx-v6.86下载程序选择24M频率下载程序,在串口设置为 波特率115200,数据位8,校验位N,停止位1,无校验,进行通讯,在串口1发送任意16进制字符,8路PWM波形的占空比增加,在串口2发送任意字符,8路PWM波形的占空比减小。 如图5所示使用SOLIDWORKS软件对导弹做静态应力分析,导弹的安全系数是3903.33,子弹头不为变形量最大,为0.1mm。 上述的一种具有三轴圆周64个圆球的弹道导弹变质心装置,所述的是一种安装在弹道导弹弹体中部的圆环装置。 附图说明 下面结合附图和实施例对本实用新型进一步说明。 图1为本实用新型结构图。 图2为本实用新型装置结构图。 图3为本实用新型三轴结构图。 图4为本实用新型控制电路图。 图5为本实用新型单片机下载PWM驱动电路图。 图6为本实用新型单片机下载PWM驱动电路图静态应力分析图。 图7为本实用新型控制电路图。 图8为本实用新型控制电路图。 图9为本实用新型控制电路图。 图1中,1.导弹弹头,2. 导弹弹体,3.变质心装置上的圆环,4,火箭发动机。 图2中,3. 变质心装置上的圆环,5. 变质心装置上的圆球,6. 变质心装置上的圆杆。 图3中,7. Y轴圆环,8. X轴圆环,9. Z轴圆环。 图4中,单片机STC8A8K64S4A12有2个串口。 具体实施方式 图1中,弹道导弹的弹头(1)安装在导弹单体(2)上部,变质心装置的圆环(3)安装在导弹弹体中部,火箭发动机(4)安装在导弹底部。
图2中,64个圆球(5)安装在导弹变质心装置的一个圆环(3)上面。这64个圆球分别安装在相互垂直的3个圆环(7),(8),(9)上面。64个圆球(5)分别用圆环圆心处的圆杆(6)和圆环的圆心相连,64个圆球(5)被和圆环圆心相连的圆杆(6)拉着在圆环(3)上面滚动,就会使导弹单体的质心发生改变,进而会使导弹的质心发生改变。 图3中X轴圆环,Y轴圆环,Z轴圆环相互垂直。每个圆环上面安装64个位置可调的圆球。
图1
图2
图3
图4 图5
图6