TI MSPM0 MPU6050代码

if(sys_time % 20 == 0){
			//MPU6050
			NVIC_DisableIRQ(UART_0_INST_INT_IRQN);
			NVIC_DisableIRQ(GPIOA_INT_IRQn);
			if(mpu_dmp_get_data(&pitch, &roll, &yaw) == 0){
				yaw = yaw - PianYi;
				//yaw = yaw - 0.0004f*(float)sys_time - 0.49f;
				//yaw = yaw - 7;
        // 定义数据包:帧头(1) + float数据(4) + 校验位(1) + 帧尾(1),共7字节
        uint8_t packet[7];
        uint8_t checksum = 0;
        int i = 0;
        
        // 1. 添加帧头
        packet[i++] = 0xA5;
        
        // 2. 将float拆分为4个字节并添加到数据包
        // 使用指针将float转换为字节数组(注意大小端问题)
        uint8_t* yaw_bytes = (uint8_t*)&yaw;
        for(int j = 0; j < 4; j++){
            packet[i++] = yaw_bytes[j];
            checksum += yaw_bytes[j];  // 累加数据字节计算校验和
        }
        
        // 3. 添加校验位(只取低8位)
        packet[i++] = checksum & 0xFF;
        
        // 4. 添加帧尾
        packet[i++] = 0x5A;
        
        // 发送完整数据包(共7字节)
        for(int j = 0; j < 7; j++){
            uart0_send_char(packet[j]);
        }
        } else {
            // 发送错误标记数据包
            const char err_packet[] = {0xA5, 'E', 'r', 'r', 0x03, 0x5A}; // 0x03是"Err"的校验和
            for(int j = 0; j < sizeof(err_packet); j++){
                uart0_send_char(err_packet[j]);
            }
}
        
        //uart0_send_string(buffer);
				//uart0_send_string(buffer);
				//uart0_send_char((char)yaw);
				
			NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
			NVIC_EnableIRQ(GPIOA_INT_IRQn);
}

switch(tag){
	case 0:
		TargetAngle=Target;
		go_mpu(yaw + TargetAngle);
		if( Trace_get() != 0){
delay_ms(20);
if( Trace_get() != 0){

DL_GPIO_clearPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);

if(Target == Angle1){
motor(0,1000);
delay_ms(300);
}else{
motor(1000,0);
delay_ms(300);
}

DL_GPIO_setPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);

tag = 1;
}
}
		break;
	case 1:
		go_xunji();
		if(Trace_get() == 0){
motor(500,500);
DL_GPIO_clearPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);

delay_ms(200);
DL_GPIO_setPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);



if(Trace_get() == 0 ){
	tag = 0;
	if(Target == Angle1){
Target = Angle2;
}else{
Target = Angle1;
//if(PianYi < 10.5){
//PianYi+= 1.3;
//}
}
}
}
		break;
}
/*
 * Copyright (c) 2021, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "ti_msp_dl_config.h"
#include "board.h"
#include "tb6612.h"
#include "xunji.h"
#include "mpu6050.h"
#include "inv_mpu.h"
#include <stdio.h>
#include <string.h>

#include "oled_software_i2c.h"

// 数据包格式:共11字节
// 0xA5(1字节) + float1(4字节) + float2(4字节) + 校验位(1字节) + 0x5A(1字节)
#define PACKET_LEN 11
#define HEADER 0xA5
#define TAIL 0x5A
// 接收状态机
typedef enum {
    RX_WAIT_HEADER,    // 等待包头0xA5
    RX_RECV_FLOAT1,    // 接收第一个float(4字节)
    RX_RECV_FLOAT2,    // 接收第二个float(4字节)
    RX_RECV_CHECKSUM,  // 接收校验位
    RX_RECV_TAIL       // 接收包尾0x5A
} RxState;
// 接收缓冲区与状态变量(需加volatile,防止编译器优化)
static volatile uint8_t rx_buf[PACKET_LEN];  // 存储完整数据包
static volatile uint8_t rx_idx = 0;          // 当前接收位置索引
static volatile RxState rx_state = RX_WAIT_HEADER;  // 初始状态
static volatile uint8_t checksum_calc = 0;   // 计算的校验和
static volatile uint8_t packet_ok = 0;       // 数据包接收完成且有效标志
// 解析后的数据(第一个float赋值给P)
float P;                  // 目标变量:存储第一个float


uint8_t flag = 0;

//编码器
volatile long long _countB = 0;//临时右轮
volatile long long countB = 0;//准确
volatile long long _countA = 0;//临时左轮
volatile long long countA = 0;//准确
volatile long long countA_ = 0;//总计数
volatile long long countB_ = 0;//总计数
//3.1416 × 44mm ≈ 138.23mm 138.23mm ÷ 530 ≈ 0.2608mm

volatile int speedA=0;
volatile int speedB=0;
volatile int speed=0;

int sys_time = 0;
float pitch=0,roll=0,yaw=0;

uint8_t tag=0;//动作标签
int Angle1=40; //第一转向--
int Angle2=145;//第二转向--
int TargetAngle=40;
int Target=40;
float PianYi=7.59;//MPU6050偏移 2.5 7.59

char buffer[20];
//MPU6050转向
void go_mpu(int angle){

						
if(TargetAngle == Angle2 && yaw > 0){
angle = -180;
}
            float correction = PID_Calculate(angle);//-45向左 +45向右
            
            // 基础速度
            const int base_speed = 600;
            
            // 应用PID修正
            int left_speed = base_speed - correction;
            int right_speed = base_speed + correction;
            
            // 驱动电机
						motor(left_speed, right_speed);

}
void go_xunji(void){
				    int32_t pos = xunji();
            if(pos >= 6 || pos <= -6){
}
            // PID计算转向修正值
            float correction = PID_Calculate(pos);
            
            // 基础速度
            const int base_speed = 600;
            
            // 应用PID修正
            int left_speed = base_speed - correction;
            int right_speed = base_speed + correction;
            
            // 驱动电机
            motor(left_speed, right_speed);

}

int main(void)
{

    SYSCFG_DL_init();
    NVIC_EnableIRQ(GPIOA_INT_IRQn);
		//NVIC_EnableIRQ(TIMER_TICK_INST_INT_IRQN);
		//NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
		//NVIC_DisableIRQ(UART_0_INST_INT_IRQN);
		NVIC_EnableIRQ(UART_0_INST_INT_IRQN);

    //BEEP
		DL_GPIO_clearPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);
//OLED
OLED_Init();
OLED_ShowString(10,0,(uint8_t*)"Start",16);


		PID_Init(100.0f, 0.0f, 0.0f, 30.0f); // Kp, Ki, Kd
		

		
//		MPU6050_Init();

//		while(mpu_dmp_init()){
//		delay_ms(200);
//}
//CalibrateMPU(); // 在这里调用校准函数!
//PianYi+=5;
uart0_send_string("start");


//BEEP
DL_GPIO_setPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);




char buffer[10];
char oled_buffer[32];

snprintf(oled_buffer,sizeof(oled_buffer),"Flag=%d",flag);
OLED_ShowString(64,0,(uint8_t*)oled_buffer,16);
OLED_ShowChinese(112,6,0,16);


    while (1) {


if(sys_time % 20 == 0){
//OLED_Clear();


snprintf(oled_buffer,sizeof(oled_buffer),"Flag=%d",flag);
OLED_ShowString(64,0,(uint8_t*)oled_buffer,16);

snprintf(oled_buffer, sizeof(oled_buffer), "EN=%-6lldcm", (long long)((float)countA_ * 0.02608f));
OLED_ShowString(10,2,(uint8_t*)oled_buffer,16);

snprintf(oled_buffer, sizeof(oled_buffer), "EN=%-6lldcm", (long long)((float)countB_ * 0.02608f));
OLED_ShowString(10,4,(uint8_t*)oled_buffer,16);

snprintf(oled_buffer, sizeof(oled_buffer), "Angle=%-4lld", (long long)yaw);
OLED_ShowString(10,6,(uint8_t*)oled_buffer,16);
}
			sys_time++;
//			if(sys_time % 20 == 0){
//				if(countA != 0 ){
//				motor(400,0);
//}else{
//				motor(0,0);
//}

//}		

			//delay_cycles(CPUCLK_FREQ / 1000 * 2);//时间基准2ms

//操作1
if(flag == 1){
  go_xunji();
}
//操作2
if(flag == 2){
		

}
if(flag == 0){

}
        
}
}


//串口的中断服务函数
void UART_0_INST_IRQHandler(void)
{
volatile unsigned char uart_data = 0;
    //如果产生了串口中断
    switch( DL_UART_getPendingInterrupt(UART_0_INST) )
    {
        case DL_UART_IIDX_RX://如果是接收中断
            //接发送过来的数据保存在变量中
            uart_data = DL_UART_Main_receiveData(UART_0_INST);
//switch (rx_state) {
//            case RX_WAIT_HEADER:
//                // 等待包头0xA5,收到则初始化接收
//                if (uart_data == HEADER) {
//                    rx_buf[rx_idx++] = uart_data;  // 存储包头
//                    checksum_calc = 0;             // 校验和不含包头,重置
//                    rx_state = RX_RECV_FLOAT1;     // 切换到接收第一个float
//                }
//                break;

//            case RX_RECV_FLOAT1:
//                // 接收第一个float(4字节),并累加校验和
//                rx_buf[rx_idx++] = uart_data;
//                checksum_calc += uart_data;  // 校验和包含float1的所有字节
//                // 第一个float接收完成(包头1字节 + 4字节 = 5字节)
//                if (rx_idx == 5) {
//                    rx_state = RX_RECV_FLOAT2;  // 切换到接收第二个float
//                }
//                break;

//            case RX_RECV_FLOAT2:
//                // 接收第二个float(4字节),继续累加校验和
//                rx_buf[rx_idx++] = uart_data;
//                checksum_calc += uart_data;  // 校验和包含float2的所有字节
//                // 第二个float接收完成(5 + 4 = 9字节)
//                if (rx_idx == 9) {
//                    rx_state = RX_RECV_CHECKSUM;  // 切换到接收校验位
//                }
//                break;

//            case RX_RECV_CHECKSUM:
//                // 接收校验位并对比计算值
//                rx_buf[rx_idx++] = uart_data;
//                // 校验位 = (float1所有字节 + float2所有字节)的低8位
//                if (uart_data == (checksum_calc & 0xFF)) {
//                    rx_state = RX_RECV_TAIL;  // 校验通过,等待包尾
//                } else {
//                    // 校验失败,重置状态(丢弃错误包)
//                    rx_state = RX_WAIT_HEADER;
//                    rx_idx = 0;
//                }
//                break;

//            case RX_RECV_TAIL:
//                // 接收包尾0x5A,确认完整数据包
//                if (uart_data == TAIL) {
//                    rx_buf[rx_idx++] = uart_data;  // 存储包尾
//                    packet_ok = 1;                 // 标记数据包有效
//                    
//                    memcpy(&P, &rx_buf[1], 4);
////PID_Init(50, P, 10, 30.0f); // Kp, Ki, Kd
//DL_GPIO_setPins(GPIOB, TRACE_PIN_BEEP_PIN);
//delay_ms(200);
//DL_GPIO_clearPins(GPIOB, TRACE_PIN_BEEP_PIN);

//                }
//                // 无论包尾是否正确,都重置状态准备下一次接收
//                rx_state = RX_WAIT_HEADER;
//                rx_idx = 0;
//                break;

//            default:
//                // 异常状态,强制重置
//                rx_state = RX_WAIT_HEADER;
//                rx_idx = 0;
//                break;
//        }

            //将保存的数据再发送出去
            //uart0_send_char(uart_data);

//static int speed = 600;
//						if(uart_data == 'A'){
//motor(speed,speed);
//}else if(uart_data == 'Z'){
//motor(0,0);
//}else if(uart_data == 'C'){
//motor(speed,-speed);
//}else if(uart_data == 'G'){
//motor(-speed,speed);
//}else if(uart_data == 'E'){
//motor(-speed,-speed);
//}else if(uart_data == 'B'){
//motor(speed,speed - 200);
//}else if(uart_data == 'H'){
//motor(speed - 200,speed);
//}else if(uart_data == 'F'){
//motor(-speed + 200,-speed);
//}else if(uart_data == 'D'){
//motor(-speed,-speed + 200);
//}else if(uart_data == 'X'){
//speed += 100;
//}else if(uart_data == 'Y'){
//speed -= 100;
//}else if(uart_data == 'a'){
//DL_GPIO_clearPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);
//delay_ms(200);
//DL_GPIO_setPins(BEEP_PORT, BEEP_PIN_BEEP_PIN);
//}


            break;

        default://其他的串口中断
            break;
    }
}



void GROUP1_IRQHandler(void)//Group1的中断服务函数
{
    //读取Group1的中断寄存器并清除中断标志位
		//DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1);
		


	uint32_t gpio_status;
	
	//获取中断信号情况
	gpio_status = DL_GPIO_getEnabledInterruptStatus(ENCODE_PORT, ENCODE_EA1_PIN | ENCODE_EA2_PIN | KEY_PIN_18_PIN | ENCODE_EB1_PIN | ENCODE_EB2_PIN);
  DL_GPIO_clearInterruptStatus(ENCODE_PORT, gpio_status); // 清除已触发的中断标志
		if((gpio_status & KEY_PIN_18_PIN) == KEY_PIN_18_PIN )
		{
				flag++;
				if(flag == 3) flag = 0;
				motor(0,0);//切换状态停止电机
		}
//	//编码器A相上升沿触发
//	if((gpio_status & ENCODE_EA1_PIN) == ENCODE_EA1_PIN)
//	{
//		
//		//如果在A相上升沿下,B相为低电平
//		if(!DL_GPIO_readPins(ENCODE_PORT,ENCODE_EA2_PIN))
//		{
//			_countB--;countB_--;
//		}
//		else
//		{
//			_countB++;countB_++;
//		}
//	}//编码器B相上升沿触发
//	else if((gpio_status & ENCODE_EA2_PIN)==ENCODE_EA2_PIN)
//	{
//		//如果在B相上升沿下,A相为低电平
//		if(!DL_GPIO_readPins(ENCODE_PORT,ENCODE_EA1_PIN))
//		{
//			_countB++;countB_++;
//		}
//		else
//		{
//			_countB--;countB_--;
//		}
//	}else if((gpio_status & ENCODE_EB1_PIN)==ENCODE_EB1_PIN){//左轮EB
//        if(!DL_GPIO_readPins(ENCODE_PORT,ENCODE_EB2_PIN)){//如果B低电平
//            _countA++;countA_++;
//        }else{
//            _countA--;countA_--;
//        }
//    }else if((gpio_status & ENCODE_EB2_PIN)==ENCODE_EB2_PIN){
//        if(!DL_GPIO_readPins(ENCODE_PORT,ENCODE_EB1_PIN)){
//            _countA--;countA_--;
//        }else{
//            _countA++;countA_++;
//        }
//    }
	//清除状态/
	DL_GPIO_clearInterruptStatus(ENCODE_PORT,ENCODE_EA1_PIN|ENCODE_EA2_PIN | KEY_PIN_18_PIN | ENCODE_EB1_PIN | ENCODE_EB2_PIN);
}


void TIMER_TICK_INST_IRQHandler(void)
{
	if( DL_TimerA_getPendingInterrupt(TIMER_TICK_INST) == DL_TIMER_IIDX_ZERO )
	{
		
		countA = _countA;
        countB = _countB;
		_countA = 0;
        _countB = 0;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值