新手学习tm4c的四轴飞行器(提供了飞行程序),买了个光流px4flow,想通过光流读取数据并发送到地面站,但是地面站怎么也接收不到,因为自己初学tm4c,怀疑是自己程序写得不完善(是在原始程序上修改的)。请教大家我写的程序哪里不够完善。
光流接uart1 tx rx,MAVLINK 协议接收数据 ,“FE”作为起始标志。以下为自己添加的程序。
px4flow.c文件的程序如下:
void PX4Flow_init()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
GPIOPinConfigure(GPIO_PB0_U1RX); //配置输出引脚
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PB1_U1TX); //配置输出引脚
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_1);
UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(),115200,
UART_CONFIG_WLEN_8 |UART_CONFIG_STOP_ONE| UART_CONFIG_PAR_NONE); //设置通信参数,波特率115200,8N1
SysCtlDelay(40);
UARTFIFODisable(UART1_BASE);
UARTIntEnable(UART1_BASE, UART_INT_RX);
IntMasterEnable();
IntEnable(INT_UART1);
}
void FLOW_MAVLINK(unsigned char data)
{
static uint8 s_flow=0,data_cnt=0;
uint8 cnt_offset=0; uint8 get_one_fame=0;
char floattobyte[4];
switch(s_flow)
{
case 0: if(data==0xFE)
s_flow=1;
break;
case 1: if(data==0x1A||data==0x2C)
{ s_flow=2;}
else
s_flow=0;
break;
case 2:
if(data_cnt<4)
{s_flow=2; FLOW_STATE[data_cnt++]=data;}
else
{data_cnt=0;s_flow=3;flow_buf[data_cnt++]=data;}
break;
case 3:
if(FLOW_STATE[3]==100)
{
if(data_cnt<26)
{s_flow=3; flow_buf[data_cnt++]=data;}
else
{data_cnt=0;s_flow=4;}
}
else if(FLOW_STATE[3]==106)
{
if(data_cnt<44)
{s_flow=3; flow_buf_rad[data_cnt++]=data;}
else
{data_cnt=0;s_flow=4;}
}
else
{data_cnt=0;s_flow=0;}
break;
case 4:get_one_fame=1;s_flow=0;data_cnt=0;break;
default:s_flow=0;data_cnt=0;break;
}//–end of s_uart
if(get_one_fame)
{
// USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
if(FLOW_STATE[3]==100)
{
uint64_t flow_buf_cp[8]={0};
char cp_xy[4]={5,1,2,3};
int i=0;
for(i=0;i<=7;i++)
{
flow_buf_cp[i]=flow_buf[i];
}
flow.time_sec=(flow_buf_cp[7]<<64)|(flow_buf_cp[6]<<56)|(flow_buf_cp[5]<<48)|(flow_buf_cp[4]<<40)
|(flow_buf_cp[3]<<32)|(flow_buf_cp[2]<<16)|(flow_buf_cp[1]<<8)|(flow_buf_cp[0]);
floattobyte[0]=flow_buf[8];
floattobyte[1]=flow_buf[9];
floattobyte[2]=flow_buf[10];
floattobyte[3]=flow_buf[11];
// x1=(floattobyte[3]|(floattobyte[2]<<8)|(floattobyte[1]<<16)|(floattobyte[0]<<24));
flow.flow_comp_x.originf =ByteToFloat(floattobyte);
floattobyte[0]=flow_buf[12];
floattobyte[1]=flow_buf[13];
floattobyte[2]=flow_buf[14];
floattobyte[3]=flow_buf[15];
flow.flow_comp_y.originf =ByteToFloat(floattobyte);
floattobyte[0]=flow_buf[16];
floattobyte[1]=flow_buf[17];
floattobyte[2]=flow_buf[18];
floattobyte[3]=flow_buf[19];
flow.hight.originf=ByteToFloat(floattobyte);//ground_distance float Ground distance in m. Positive value: distance known. Negative value: Unknown distance flow.flow_x.origin=(int16_t)((flow_buf[20])|(flow_buf[21]<<8));
flow.flow_y.origin=(int16_t)((flow_buf[22])|(flow_buf[23]<<8));
flow.id=flow_buf[24];
flow.quality=flow_buf[25]; //Optical flow quality / confidence. 0: bad, 255: maximum quality
// flow_fix.flow_x.average = IIR_I_Filter(flow_fix.flow_x.origin , InPut_IIR[0], OutPut_IIR[0], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
// flow.flow_y.average = IIR_I_Filter(flow.flow_y.origin , InPut_IIR[1], OutPut_IIR[1], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
// flow.flow_comp_x.average = IIR_I_Filter(flow.flow_comp_x.originf , InPut_IIR[2], OutPut_IIR[2], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
// flow.flow_comp_y.average = IIR_I_Filter(flow.flow_comp_y.originf , InPut_IIR[3], OutPut_IIR[3], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
x1=flow.flow_x.origin;
Aumx1=Aumx1+x1;
y1=flow.flow_y.origin;
Aumy1=Aumy1+y1;
}
/* if(flow.flow_x.origin>=27)
{
x1=flow.flow_x.origin/10;
}
if(flow.flow_x.origin<=-27)
{
x1=flow.flow_x.origin/10;
}
if(flow.flow_x.origin<27 & flow.flow_x.origin>-27)
x1=0;
Aumx1=Aumx1+x1; //这是希望发送到地面站的数据
if(flow.flow_y.origin>=27) {
y1=flow.flow_y.origin/10;
}
if(flow.flow_y.origin<=-27){
y1=flow.flow_y.origin/10;
}
if(flow.flow_y.origin<27 & flow.flow_y.origin>-27)
y1=0;
Aumy1=Aumy1+y1; //这是希望发送到地面站的数据
} */
else if(FLOW_STATE[3]==106)
{
flow_rad.time_usec=(flow_buf_rad[7]<<64)|(flow_buf_rad[6]<<56)|(flow_buf_rad[5]<<48)|(flow_buf_rad[4]<<40)
|(flow_buf_rad[3]<<32)|(flow_buf_rad[2]<<16)|(flow_buf_rad[1]<<8)|(flow_buf_rad[0]);
flow_rad.integration_time_us=(flow_buf_rad[11]<<32)|(flow_buf_rad[10]<<16)|(flow_buf_rad[9]<<8)|(flow_buf_rad[8]);
floattobyte[0]=flow_buf_rad[12];
floattobyte[1]=flow_buf_rad[13];
floattobyte[2]=flow_buf_rad[14];
floattobyte[3]=flow_buf_rad[15];
flow_rad.integrated_x=ByteToFloat(floattobyte);
floattobyte[0]=flow_buf_rad[16];
floattobyte[1]=flow_buf_rad[17];
floattobyte[2]=flow_buf_rad[18];
floattobyte[3]=flow_buf_rad[19];
flow_rad.integrated_y=ByteToFloat(floattobyte);
floattobyte[0]=flow_buf_rad[20];
floattobyte[1]=flow_buf_rad[21];
floattobyte[2]=flow_buf_rad[22];
floattobyte[3]=flow_buf_rad[23];
flow_rad.integrated_xgyro=ByteToFloat(floattobyte);
floattobyte[0]=flow_buf_rad[24];
floattobyte[1]=flow_buf_rad[25];
floattobyte[2]=flow_buf_rad[26];
floattobyte[3]=flow_buf_rad[27];
flow_rad.integrated_ygyro=ByteToFloat(floattobyte);
floattobyte[0]=flow_buf_rad[28];
floattobyte[1]=flow_buf_rad[29];
floattobyte[2]=flow_buf_rad[30];
floattobyte[3]=flow_buf_rad[31];
flow_rad.integrated_zgyro=ByteToFloat(floattobyte);
flow_rad.time_delta_distance_us=(flow_buf_rad[35]<<32)|(flow_buf_rad[34]<<16)|(flow_buf_rad[33]<<8)|(flow_buf_rad[32]);
floattobyte[0]=flow_buf_rad[36];
floattobyte[1]=flow_buf_rad[37];
floattobyte[2]=flow_buf_rad[38];
floattobyte[3]=flow_buf_rad[39];
flow_rad.distance=ByteToFloat(floattobyte);
flow_rad.temperature=(flow_buf_rad[41]<<8)|(flow_buf_rad[40]);
flow_rad.sensor_id=(flow_buf_rad[42]);
flow_rad.quality=(flow_buf_rad[43]);
flow_fix.flow_x.origin =flow.flow_x.origin + flow_rad.integrated_ygyro*flow_fix.scale_rad_fix;
flow_fix.flow_y.origin =flow.flow_y.origin – flow_rad.integrated_xgyro*flow_fix.scale_rad_fix;
flow_fix.flow_comp_x.originf =flow.flow_comp_x.originf – flow_rad.integrated_ygyro*flow_fix.scale_rad_fix_comp;
flow_fix.flow_comp_y.originf =flow.flow_comp_y.originf + flow_rad.integrated_xgyro*flow_fix.scale_rad_fix_comp;
} }
}
IRQhandler.c 添加中断
void UART1_IRQHandler()
{
uint32_t ui32Status;
ui32Status = ROM_UARTIntStatus(UART1_BASE, true);
ROM_UARTIntClear(UART1_BASE, ui32Status);
while(ROM_UARTCharsAvail(UART1_BASE))
{
UART_FIFO[UART_P_W]=ROM_UARTCharGet(UART1_BASE); //这一步是直接在程序UART5的基础上修改的,我怀疑是这里出了问题,但不知道如何修改
UART_P_W++;
}
}
MAIN.C 加初始化
uart_init(115200,UART1_IRQHandler);
nrf传输
Nrf_Buf_Out.Data_int[4]=Aumx1;
Nrf_Buf_Out.Data_int[5]=Aumy1;
除了光流的Aumx和Aumy ,其他飞行参数都可以实时传输,应该是我添加的程序问题,没有调用FLOW_MAVLINK?请教大家如何完善。
Maka Luo:
首先UART通信是正常的吗?
Hu bin Hu:
回复 Maka Luo:
UART 用串口助手调试,能够接收数据。其实是没有调用 void FLOW_MAVLINK(unsigned char data) 这个函数,自然是接收不到数据的,我看到stm32上的调用是这么写的,
int Rx_addr=1;UartData Uart_In;UartData Uart_Out;unsigned char data1[8];void USART1_IRQHandler(void){ unsigned char ch; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { ch = USART_ReceiveData(USART1); FLOW_MAVLINK(ch); if(Rx_addr==1) { if(ch==0xfe) { data1[1]=ch; Rx_addr=2; } } else if(Rx_addr==2) { data1[2]=ch; Rx_addr=3; } else if(Rx_addr>=3 && Rx_addr<=7) { data1[Rx_addr]=ch; Rx_addr++; } Rx_addr=1; } }
请问在tm4c上应该怎么仿照这个来写呢?新手想了很久,也没有头绪啊。
xyz549040622:
回复 Hu bin Hu:
照猫画虎,你也可以把这个函数放在TM4C的串口中断中。关于中断的配置,可以参考官方的例程。