基于RT1064的电磁巡线小车

基于RT1064的电磁巡线小车


本文章是基于RT1064让智能小车实现电磁巡线。


提示:以下是本篇文章正文内容,下面案例可供参考

使用步骤

1.初始化参数

代码如下(示例):

    DisableGlobalIRQ();
    board_init();
      //电机初始化
      //右轮转动方向设置
      gpio_init(D12, GPO, 0, GPIO_PIN_CONFIG);
      gpio_init(D13, GPO, 0, GPIO_PIN_CONFIG);
      //左轮转动方向设置
      gpio_init(D14, GPO, 0, GPIO_PIN_CONFIG);
      gpio_init(D15, GPO, 0, GPIO_PIN_CONFIG);
     //初始化电机PWN
      pwm_init(PWM1_MODULE3_CHB_D1, 1000, 10000);
      pwm_init(PWM1_MODULE3_CHA_D0, 1000, 10000);
      
      //舵机初始化
      pwm_init(PWM4_MODULE2_CHA_C30, 50, 800); 
      
      //初始化ADC模块
      adc_init(ADC_1,ADC1_CH4_B15,ADC_8BIT);
      adc_init(ADC_1,ADC1_CH3_B14,ADC_8BIT);
      
      //中断初始化
      pit_init();
      pit_interrupt_ms(PIT_CH1, 10);
      
    EnableGlobalIRQ(0);

2.中断函数

代码如下(示例):

      //AD采集
      for(int i=0;i<10;i++)
      {
        adcnumber_right_value[i]=adc_convert(ADC_1,ADC1_CH4_B15);
        adcnumber_left_value[i]=adc_convert(ADC_1,ADC1_CH3_B14);
      }      
      adcnumber_right=(adcnumber_right_value[4]+adcnumber_right_value[5])/2;
      adcnumber_left=(adcnumber_left_value[4]+adcnumber_left_value[5])/2;
      
      //越界判断
      if(adcnumber_right>10&&adcnumber_left>10)
      {
        gpio_set(D12, 0);
        gpio_set(D13, 1);
        gpio_set(D14, 0);
        gpio_set(D15, 1);        
      }
      else
      {
        gpio_set(D12, 0);
        gpio_set(D13, 0);
        gpio_set(D14, 0);
        gpio_set(D15, 0);          
      }
      
      
      //PID数据处理
      PIDRegulation(&pid_value, adcnumber_left-adcnumber_right)  
      
      //舵机控制
      pwn_serve=800+pid_value.result;

3.代码整体

main.c文件

#include "headfile.h"

uint32 pwn_serve_init = 800;


main(void)
{
    DisableGlobalIRQ();
    board_init();
      //电机初始化
      //右轮设置
      gpio_init(D12, GPO, 0, GPIO_PIN_CONFIG);
      gpio_init(D13, GPO, 0, GPIO_PIN_CONFIG);
      //左轮设置
      gpio_init(D14, GPO, 0, GPIO_PIN_CONFIG);
      gpio_init(D15, GPO, 0, GPIO_PIN_CONFIG);
      pwm_init(PWM1_MODULE3_CHB_D1, 1000, 10000);
      pwm_init(PWM1_MODULE3_CHA_D0, 1000, 10000);
      
      //舵机初始化
      pwm_init(PWM4_MODULE2_CHA_C30, 50, 800); 
      
      //初始化ADC模块
      adc_init(ADC_1,ADC1_CH4_B15,ADC_8BIT);
      adc_init(ADC_1,ADC1_CH3_B14,ADC_8BIT);
      
      //中断初始化
      pit_init();
      pit_interrupt_ms(PIT_CH1, 10);
      
    EnableGlobalIRQ(0);
    
    while (1)
    {
      //pwm_duty(PWM4_MODULE2_CHA_C30, pwn_serve_init); 
    }
}

isr.c文件

#include "headfile.h"
#include "isr.h"

typedef struct

typedef struct
{
  int KP;//比例系数
  int KI;//积分系数
  int KD;//微分系数
  int lasterror_1;//前一拍偏差  
  int lasterror_2;//前两拍偏差
  int result;//输出值
}PID;



//初始化pid参数
PID pid_value={3,0,30,0,0,0};


//ADC采集
int adcnumber_right_value[10]={0}; 
int adcnumber_left_value[10]={0};


int pwn_serve=800;

//PID算法
void PIDRegulation(PID *vPID, int thiserror)
{
  vPID->result = vPID->KP * ( thiserror - vPID->lasterror_1 ) + vPID->KI * thiserror + vPID->KD * ( thiserror - 2 * vPID->lasterror_1 + vPID->lasterror_2 );
  vPID->lasterror_2 = vPID->lasterror_1;
  vPID->lasterror_1 = thiserror;
}


void CSI_IRQHandler(void)
{
    CSI_DriverIRQHandler();     //调用SDK自带的中断函数 这个函数最后会调用我们设置的回调函数
    __DSB();                    //数据同步隔离
}

void PIT_IRQHandler(void)
{
    if(PIT_FLAG_GET(PIT_CH0))
    {
      PIT_FLAG_CLEAR(PIT_CH0);
    }
    
    if(PIT_FLAG_GET(PIT_CH1))
    {  
    
	  int adcnumber_right=0;
	  int adcnumber_left=0;
      //AD采集
      for(int i=0;i<10;i++)
      {
        adcnumber_right_value[i]=adc_convert(ADC_1,ADC1_CH4_B15);
        adcnumber_left_value[i]=adc_convert(ADC_1,ADC1_CH3_B14);
      }      
      adcnumber_right=(adcnumber_right_value[4]+adcnumber_right_value[5])/2;
      adcnumber_left=(adcnumber_left_value[4]+adcnumber_left_value[5])/2;
      
      //越界判断
      if(adcnumber_right>10&&adcnumber_left>10)
      {
        gpio_set(D12, 0);
        gpio_set(D13, 1);
        gpio_set(D14, 0);
        gpio_set(D15, 1);        
      }
      else
      {
        gpio_set(D12, 0);
        gpio_set(D13, 0);
        gpio_set(D14, 0);
        gpio_set(D15, 0);          
      }
      
      
      //PID数据处理
      PIDRegulation(&pid_value, adcnumber_left-adcnumber_right);
      
      //舵机控制
      pwn_serve=800+pid_value.result;//800为舵机中值
      pwm_duty(PWM4_MODULE2_CHA_C30,pwn_serve); 
       
      PIT_FLAG_CLEAR(PIT_CH1);//清除中断标记位
    }
    
    if(PIT_FLAG_GET(PIT_CH2))
    {
        PIT_FLAG_CLEAR(PIT_CH2);
    }
    
    if(PIT_FLAG_GET(PIT_CH3))
    {
        PIT_FLAG_CLEAR(PIT_CH3);
    }

    __DSB();
}


void GPIO2_Combined_16_31_IRQHandler(void)
{
    if(GET_GPIO_FLAG(B15))
    {
        CLEAR_GPIO_FLAG(B15);//清除中断标志位
    }
}



void GPIO2_Combined_0_15_IRQHandler(void)
{
    if(GET_GPIO_FLAG(MT9V03X_VSYNC_PIN))
    {
        //不用清除标志位,标志位在mt9v03x_vsync函数内部会清除
        if(1 == flexio_camera_type)mt9v03x_vsync();
    }
    if(GET_GPIO_FLAG(SCC8660_VSYNC_PIN))
    {
        //不用清除标志位,标志位在scc8660_vsync函数内部会清除
        if(2 == flexio_camera_type)scc8660_vsync();
    }
}



总结

注意事项
(1)本文章的使用了tb6612电机驱动芯片对电机进行驱动。
(2)各个函数的操作都可以在相应的库里的.c文件和.h文件里查找。
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页