|
本帖最后由 lb8820265 于 2015-5-6 16:12 编辑
先上视频:
视屏中使用lpc54100开发板为主控制器,VC编写的上位机空调节相关参数和显示相关数据和姿态,这次的软件较上一次的有了改进,由之前的采用SerialPort类变成了使用软件自带的mscomm串口控件,这个控件更加稳定,然后能够实现同时收发。然后增加了OpenGL显示姿态。修改了不少Bug,增加了Bug显示区域。同时msp430的上位机接收机也做了改进,增加了可靠性,提高了主频。 视屏中的小车只有姿态控制而没有速度控制,然后上位机调参窗口中,第一个是小车初始角度,第二个是姿态控制P参数,第三个是姿态控制D参数。在小车的显示屏上能够显示相关参数。通过查看小车传回来的PWM输出,小车速度,小车姿态以及小车的实际情况来调节参数。 下面是相关代码与解释: main函数: - int32_t main(void)
- {
- // Setup SystemCoreClock and any needed board code
- SystemCoreClockUpdate();
- //SysTick_Config(SystemCoreClock/TICKRATE_HZ);
- Board_SetupMuxing();
- I2C_Config();
- while(!MPUchack());
- Init_MPU6050();
- SPI_INIT();
- while(NRF24L01_Check());
- NRF24L01_RT_Init();
- Board_UART_Init ( LPC_USART0, 115200, &UART0arg );
- Chip_SCTPWM_Init(SCT_PWM);//初始化STC
- Chip_SCTPWM_SetRate(SCT_PWM, 10000);//波特率为10K
- //四个引脚的功能设定为SCT0_OUT0
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 7, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 8, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 29, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 30, IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
- Chip_SCTPWM_SetOutPin(SCT_PWM, 1, 0);//P0_7引脚,设置标号为1
- Chip_SCTPWM_SetOutPin(SCT_PWM, 2, 1);//P0_8引脚,设置标号为2
- Chip_SCTPWM_SetOutPin(SCT_PWM, 3, 2);//P0_29引脚,设置标号为3
- Chip_SCTPWM_SetOutPin(SCT_PWM, 4, 3);//P0_30引脚,设置标号为4
- Chip_SCTPWM_Start(SCT_PWM);
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 2,Chip_SCTPWM_PercentageToTicks(LPC_SCT, 0));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 1,Chip_SCTPWM_PercentageToTicks(LPC_SCT, 0));
- SetDisplay(Grey,Black,White);
- DisplayTitle(" lb8820265.");
- SetColor(Yellow, Grey);
- Chip_MRT_Init();
- Chip_MRT_SetDisabled(Chip_MRT_GetRegPtr(0));
- // DLY(120000);
- NVIC_EnableIRQ(MRT_IRQn);
- setupMRT(0, MRT_MODE_REPEAT, 125);
- while(1){
- for(a=0;a<15;a++) show[a]=0;
- if(car_angle_set<0){temp=-car_angle_set;
- show[0]=45;}
- else {show[0]=48;temp=car_angle_set;}
- show[1]=((int )temp%100)/10+48;
- show[2]=(int )temp%10+48;
- show[3]=32;
- show[4]=(int )g_fAngleControlP/100+48;
- show[5]=((int )g_fAngleControlP%100)/10+48;
- show[6]=(int )g_fAngleControlP%10+48;
- show[7]=32;
- show[8]=(int )g_fAngleControlD/100+48;
- show[9]=((int )g_fAngleControlD%100)/10+48;
- show[10]=(int )g_fAngleControlD%10+48;
- show[11]=32;
- show[12]=(int )SYS_ms/100+48;
- show[13]=((int )SYS_ms%100)/10+48;
- show[14]=(int )SYS_ms%10+48;
- GLCD_DisplayString(130, 160, 2, 1, show ); //参数显示
- }
- }
复制代码定时中断服务函数: - void MRT_IRQHandler(void)
- {
- uint32_t int_pend;
- char b[3];
- int_pend = Chip_MRT_GetIntPending();
- Chip_MRT_ClearIntPending(int_pend);
- if (int_pend & MRTn_INTFLAG(0)) {
- Nrf_Check_Event();//nrf24l01相关操作
- SYS_ms++;
- readdmp(); //mpu6050数据读取
- getquaternion();
- getgyro();
- getaccel();
- getyawpitchroll();
- AngleControl();//角度控制
- if(g_fAngleControlOut>0){//PWM控制电机输出
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 1, Chip_SCTPWM_PercentageToTicks(LPC_SCT, (int)g_fAngleControlOut));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 2,Chip_SCTPWM_PercentageToTicks(LPC_SCT, 0));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM,3 , Chip_SCTPWM_PercentageToTicks(LPC_SCT, (int)g_fAngleControlOut));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 4,Chip_SCTPWM_PercentageToTicks(LPC_SCT, 0));
- }
- else{
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 1, Chip_SCTPWM_PercentageToTicks(LPC_SCT, 0));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 2,Chip_SCTPWM_PercentageToTicks(LPC_SCT, (int)-g_fAngleControlOut));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM,3 , Chip_SCTPWM_PercentageToTicks(LPC_SCT,0));
- Chip_SCTPWM_SetDutyCycle(SCT_PWM, 4,Chip_SCTPWM_PercentageToTicks(LPC_SCT, (int)-g_fAngleControlOut));
- }
- }
- }
复制代码Nrf_Check_Event函数: - void Nrf_Check_Event(void)
- {
- uchar sta = NRF24L01_Read_Reg(READ_REG + STATUS);
- if(sta & (RX_OK))//接收中断
- {
- uchar rx_len = NRF24L01_Read_Reg(R_RX_PL_WID);
- NRF24L01_Read_Buf(RD_RX_PLOAD,NRF24L01_RXDATA,rx_len);
- //NRF_TxPacket_AP(NRF24L01_RXDATA,rx_len);
- if(NRF24L01_RXDATA[0]=='b')//如果接收到的第一个字符是‘b’
- lb_put_parameter();//将要发送的相关参数放到将要发送的寄存器中
- else if(NRF24L01_RXDATA[0]=='l')//如果接收到的第一个字符是‘l’
- lb_put_original();//将参数的值放到将要发送的寄存器中
- else if(NRF24L01_RXDATA[0]=='s')//如果接收到的第一个字符是‘s’
- lb_get_parameter();//将接收到的值修改目前的参数
- }
- if(sta & (TX_OK))
- {
- }
- if(sta & (MAX_TX))
- {
- if(sta & 0x01) //TX FIFO FULL
- {
- NRF24L01_Write_Reg(FLUSH_TX,0xff);
- }
- }
- NRF24L01_Write_Reg(WRITE_REG + STATUS, sta);//
- sta = NRF24L01_Read_Reg(READ_REG + STATUS);
- }
复制代码lb_put_parameter函数,其他两个函数差不多不再贴出 - void lb_put_parameter(void)
- {
- unsigned char check;
- char tx[27];
- int temp[4];
- float temp2[4];
- char *p;
- int i=0;
- temp[0]=g_fAngleControlOut;//将PWM输出值放到int型数组中,将会在示波器曲线1中显示
- temp[1]=g_fAngleSpeed;//将小车速度放到一个int型数组中,将会在示波器曲线2中显示
- temp[2]=0;
- temp[3]=g_fCarAngle;//将小车偏角放到一个int型数组中,将会在示波器曲线4中显示
- temp2[0]=(float)yprf[0];//将欧拉角放到一个float型数组中,将会在OpenGL图像中显示
- temp2[1]=(float)yprf[1];//将欧拉角放到一个float型数组中,将会在OpenGL图像中显示
- temp2[2]=(float)yprf[2];//将欧拉角放到一个float型数组中,将会在OpenGL图像中显示
- temp2[3]=0;
- for(i=0;i<4;i++){//将整数型数据变成字符型
- if(temp[i]<0)
- temp[i]=65536+temp[i];
- tx[2*i+2]=(temp[i]%256);
- tx[2*i+3]=(temp[i]/256);
- }
- for(i=0;i<4;i++){//将浮点型数据变成字符型
- p=(char *)&temp2[i];
- tx[10+i*4]=*p;
- tx[11+i*4]=*(p+1);
- tx[12+i*4]=*(p+2);
- tx[13+i*4]=*(p+3);
- }
- tx[0]='s';//数据头
- tx[1]='t';//数据头
- check = 0;
- for(i = 2; i < 26; i++) check += tx[i];//采用求和校验
- tx[26] = check+NRF24L01_Read_Reg(0x09); //将NRF4l01的信号强度放到求和校验中
- if(check==255)tx[26]=255;//防止错误
- NRF_TxPacket_AP(tx,27);//将要发送的27为char型数据放到将要ack发送的寄存器中
- }
复制代码
|
|