找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 755|回复: 0
收起左侧

基于逐飞科技STC32G单片机开源库写的电磁巡迹差速方案 源程序

[复制链接]
ID:1032245 发表于 2023-4-30 11:15 | 显示全部楼层 |阅读模式
给你们看看我家哥哥战车:
1.png 1.png
/******************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2020,逐飞科技
* All rights reserved.
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
* @author  逐飞科技
********************************************************************************/

#include "headfile.h"
/*
* 系统频率,可查看board.h中的 FOSC 宏定义修改。
* board.h文件中FOSC的值设置为0,则程序自动设置系统频率为33.1776MHZ
* 在board_init中,已经将P54引脚设置为复位
* 如果需要使用P54引脚,可以在board.c文件中的board_init()函数中删除SET_P54_RESRT即可
*/

#include "LED.H"
uint16 adc_data[3];
#define a 14.5
#define tingche P45//停车触发
int16 x,y;
uint16 av0,av1,av2,av3;
uint16 max1,min1;
uint16 k;//数字代表小车运行模式
uint16 count;

void main()
{
        WTST=0;
        board_init();                        // 初始化寄存器,勿删除此句代码。
        WTST=0;
        DisableGlobalIRQ();
        sys_clk=3500000;
        
        //不断电下载
        EAXFR = 1;                                 //使能访问 XFR
        CKCON = 0x00;                 //设置外部数据总线速度为最快
        WTST = 0x00;                         //设置程序代码等待参数,                                         
        P3M0 = 0x00;      //赋值为 0可将 CPU执行程序的速度设置为最快
        P3M1 = 0x00;      //将P3口设置为准双向口
        P32 = 1;


        
        adc_init(ADC_P00, ADC_SYSclk_DIV_2);        //adc电压采集
        adc_init(ADC_P01, ADC_SYSclk_DIV_2);        
        adc_init(ADC_P02, ADC_SYSclk_DIV_2);        
        adc_init(ADC_P03, ADC_SYSclk_DIV_2);

        oled_init();
        
        pwm_init(PWMA_CH1P_P10, 10000, 0);  //初始化PWMA  使用引脚P6.0  输出PWM频率10000HZ   占空比为百分之 pwm_duty / PWM_DUTY_MAX * 100
  pwm_init(PWMA_CH2N_P13, 10000, 0);
        pwm_init(PWMA_CH3P_P14, 10000, 0);
        pwm_init(PWMA_CH4N_P17, 10000, 0);
        EnableGlobalIRQ();
  tingche=1;
        k=3;//开始正常循迹
        count=0;
        
        while(1)        
                {
                        if(!P32) IAP_CONTR = 0x60;//当检测到P3.2的电平为低时,软件复位到系统区
                        
                        adc_data[0] = adc_once(ADC_P00, ADC_12BIT);        
                        adc_data[1] = adc_once(ADC_P01, ADC_12BIT);        
                        adc_data[2] = adc_once(ADC_P02, ADC_12BIT);               
                        adc_data[3] = adc_once(ADC_P03, ADC_12BIT);
                        
                        av0=adc_data[0];
                        av1=adc_data[1];
                        av2=adc_data[2];
                        av3=adc_data[3];

                        
//oled显示屏显示
                        oled_p6x8str(0,1,"ADCcollect");
                        oled_int16(0,2,av0);
                        oled_int16(84,2,av3);
                        oled_int16(20,3,av1);
                        oled_int16(56,3,av2);

                        oled_p6x8str(2,5,"k");
                        oled_int16(38,5,k);
                        oled_p6x8str(2,6,"count");
                        oled_int16(38,6,count);
                        delay_ms(1);
                        
                        //小车模式判断 temp        
      if(av1>1900||av2>1900)//入环
                        {
                                k=1;
                        }
                        else if(tingche==0)
                        {
                                k=0;//干簧管停车触发
                        }
                        else if(av0<170||av3<170)
                        {
                                k=4;//极限拉扯
                        }
                        else
                        {
                                k=3;//正常巡迹
                        }               
                                
                                //*****小车运行模式
                                                switch(k)
                                                {
                                                        case 0://停车触发
                                                                pwm_duty(PWMA_CH1P_P10, 0);     //right
                                                                pwm_duty(PWMA_CH2N_P13, 0);
                                                                pwm_duty(PWMA_CH3P_P14, 0);     //left
                                                                pwm_duty(PWMA_CH4N_P17, 0);
                                                          while(1)
                                                                {
                                                                        LED();
                                                                }
                                                                break;

                                                        case 1://入环岛转向//检测特征值然后微调直线行驶距离和入环差值和持续时间,从而达到准确入环
                                                                if(count==1)
                                                                {
                                                                        pwm_duty(PWMA_CH1P_P10, 9999);     //right
                                                                  pwm_duty(PWMA_CH2N_P13, 0);
                                                                  pwm_duty(PWMA_CH3P_P14, 9999);     //left
                                                                  pwm_duty(PWMA_CH4N_P17, 0);        
                                                                        delay_ms(100);
                                                                        pwm_duty(PWMA_CH1P_P10, 4600);     //right
                                                                  pwm_duty(PWMA_CH2N_P13, 0);
                                                                        pwm_duty(PWMA_CH3P_P14, 9700);     //left
                                                                        pwm_duty(PWMA_CH4N_P17, 0);
                                                                        delay_ms(500);
                                                                        count++;
                                                                }
                                                                break;
                                                        
//                                                        case 2://出环岛转向
//                                                                delay_ms(1000);
//                                                                pwm_duty(PWMA_CH1P_P10, 9000);     //right
//                                                                pwm_duty(PWMA_CH2N_P13, 0);
//                                                                pwm_duty(PWMA_CH3P_P14, 9860);     //left
//                                                                pwm_duty(PWMA_CH4N_P17, 0);
//                                                                delay_ms(1000);
//                                                                k=3;
//                                                                delay_ms(1);
//                                                                break;
                                                
                                                        case 3://正常循迹
                                                          if(av0>av3)
                                                                        {
                                                                         x=9800-a*(av0-av3);
                                                                         y=9800+a*(av0-av3);
                                                                        }
                                                                if(av0<av3)
                                                                {
                                                                                x=10000+a*(av3-av0);
                                                                                y=10000-a*(av3-av0);
                                                                }
                                                                  if(x>10000)
                                                                        x=10000;
                                                                  if(y>10000)
                                                                        y=10000;
                                                                        if(x<0)
                                                                        {
                                                                                x=0;
                                                                        }
                                                                        if(y<0)
                                                                        {
                                                                                y=0;
                                                                        }
                                                                pwm_duty(PWMA_CH1P_P10, y);     //right
                                                                pwm_duty(PWMA_CH2N_P13, 0);
                                                                pwm_duty(PWMA_CH3P_P14, x);     //left
                                                                pwm_duty(PWMA_CH4N_P17, 0);        
                                                                break;
                                                                        
                                                        case 4://极限拉扯,如果遇到小车抽风没转过来,还可以靠出轨迹后的微弱电磁差进行修正
                                                                        if(av0>av3)
                                                                                {
                                                                                  y=10000;
                                                                                        //delay_ms(5);
                                                                                  x=4600;
                                                                                }
                                                                        if(av0<av3)
                                                                                {
                                                                                  y=4600;
                                                                                        //delay_ms(5);
                                                                                  x=9999;
                                                                                }
                                                                        
                                                                pwm_duty(PWMA_CH1P_P10, y);     //right
                                                                pwm_duty(PWMA_CH2N_P13, 0);
                                                                pwm_duty(PWMA_CH3P_P14, x);     //left
                                                                pwm_duty(PWMA_CH4N_P17, 0);        
                                                                break;
                                                         
                                                  case 5:
                                                                pwm_duty(PWMA_CH1P_P10, 9999);     //right
                                                                pwm_duty(PWMA_CH2N_P13, 0);
                                                                pwm_duty(PWMA_CH3P_P14, 9999);     //left
                                                                pwm_duty(PWMA_CH4N_P17, 0);        
                 break;               
                                                 }        //switch选择结束                                                

                                                                oled_p6x8str(0,4,"X");
                                                                oled_int16(10,4,x);
                                                                oled_p6x8str(50,4,"Y");
                                                                oled_int16(56,4,y);                                                        
                                                                //delay_ms(1);        

                }
                        
}

给你们看看我家哥哥战车:
游客,本帖隐藏的内容需要积分高于 1 才可浏览,您当前积分为 0


Keil代码下载: Keil代码.7z (131.51 KB, 下载次数: 13)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表