⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 遥控避障寻线开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
                                            break;
                                        case 0x0:  //音量-
                                            if (car_stat == 0x05)
                                            {
                                                if (pid.p)
                                                    pid.p--;
                                            }
                                            break;
                                        case 0x0D:  //<<
                                            GAIN++;
                                            break;
                                        case 0x0F:  //>>
                                            if (GAIN)
                                                GAIN--;
                                            break;
                                        case 0x0E:  //|<<
                                            pid.d++;
                                            break;
                                        case 0x19:  //>>|                                            if (pid.d)
                                                pid.d--;
                                            break;
                                        case 0x1E: //POWER
                                           // power_stat = ~power_stat;
                                            break;
                                        default:
                                            break;
                                        }
                                    }
                                }
                            } else {                   //重复信号,仅含有引导信号
                            }
                            pca_int_count = 0;
                            frame_dog = 0;
                        } else {
                            pca_int_count++;
                        }
                    } else {
                        pca_int_count = 0;
                        frame_dog = 0;
                    }
                } else {
                    j = (pca_int_count - 3) / 2;
                    i = j / 8;
                    j = j % 8;

                    if (period > MIN168MS && period < MAX168MS) {  //1.68ms
                     //   com_putchar(0x01);
                        data_buf[i] |= (0x01 << j);
                        pca_int_count++;
                    } else if (period > MIN056MS && period < MAX056MS) {  //0.56ms
                     //   com_putchar(0x00);
                        data_buf[i] &= ~(0x01 << j);
                        pca_int_count++;
                    } else {
                        pca_int_count = 0;
                        frame_dog = 0;
                    }
                }
            }
        }
    }

    if (CF) {    //PCA计数溢出中断,19.6608MHZ晶体大约6.7ms溢出
        CF = 0;
        pca_tick++;
        if (led_tick++ >= 10) {
            led_tick = 0;

            if (led_mod_table[led_mod][led_ptr++]) {
                LED1 = 0;
                LED2 = 0;
            } else {
                if (left_obj || right_obj || front_obj || back_obj) {
                    LED1 = 0;
                    LED2 = 0;
                } else {
                    LED1 = 1;
                    LED2 = 1;
                }
            }

            led_ptr %= 20;
        }

        if (pca_int_count) {
            frame_dog++;
            if (frame_dog >= 15) {  //100ms后重新开始分析新的红外线数据包
                pca_int_count = 0;
                frame_dog = 0;
            }
        }
    }
}

int read_black_line() {  //读黑线位置.
        unsigned char i;
        int grayscale_min;  //最黑的线
        char line_begin, line_end;  //黑线对应的传感器的开始和结束位置.
        int tmp;

        read_sensors(ad_datas);
/*
        line_begin = -1; line_end= -1;
        for (i = 0; i < 8; i++) {
//com_putchar(ad_datas[i]);
//com_putchar(ad_datas_check[i]);
            tmp = (ad_datas[i] * 100);
            tmp = tmp / ad_datas_check[i];
            ad_datas[i] = tmp;
            if (ad_datas[i] <= 40)  //灰度<=40%认为下面有部分黑线
            {
                if (line_begin == -1)
                    line_begin = i;
                else
                    line_end = i;
            }
//com_putchar(ad_datas[i]);
        }
        if (line_begin == -1)
            return -1;
        if (line_end == -1)
            return line_begin * 10;

        return 10*line_begin + (line_end - line_begin) * 10 * ad_datas[line_begin] / (ad_datas[line_begin] + ad_datas[line_end]);
*/

        line_begin = 0;
//        ad_datas[0] = ad_datas[0] * 100 / ad_datas_check[0];
        grayscale_min = 500;
        for (i = 1; i < 8; i++) {
//com_putchar(ad_datas[i]);
//com_putchar(ad_datas_check[i]);
            tmp = (ad_datas[i] * 100);
            tmp = tmp / ad_datas_check[i];
            ad_datas[i] = tmp;
            if (ad_datas[i] <= grayscale_min)
            {
                grayscale_min = ad_datas[i];
                line_begin = i;
            }
//com_putchar(ad_datas[i]);
        }

        if (grayscale_min < 50)  //灰度<50%认为是有效黑线
        {
            if (line_begin == 0)
                line_end = 1;
            else if (line_begin == 7)
            {
                line_begin = 6;
                line_end = 7;
            } else if (ad_datas[line_begin - 1] < ad_datas[line_begin + 1])
            {
                line_end = line_begin;
                line_begin = line_begin - 1;
            } else
                line_end = line_begin + 1;
            if (ad_datas[line_begin] == 0)
                ad_datas[line_begin] = 1;
            if (ad_datas[line_end] == 0)
                ad_datas[line_end] = 1;
            return 10*line_begin + (line_end - line_begin) * 10 * ad_datas[line_begin] / (ad_datas[line_begin] + ad_datas[line_end]);

        } else
            return -1;
}

void track_line(PID *pid) {  //未使用PID算法的版本,四驱车用PID算法效果差些,需要改进,三轮车用PID效果还可以.
    int line_pos;

    line_pos = read_black_line();
    if (line_pos == -1)
    {
        return;
    }
com_putchar(line_pos);

    if (line_pos > 45)
    {
        pwm_moto_left = 255;
        pwm_moto_right = 255;

        moto_left_forward = 0;
        moto_right_forward = 1;
    } else if (line_pos < 25) {
        pwm_moto_left = 255;
        pwm_moto_right = 255;

        moto_left_forward = 1;
        moto_right_forward = 0;
    } else
    {
        pwm_moto_left = GAIN;
        pwm_moto_right = GAIN;

        moto_left_forward = 1;
        moto_right_forward = 1;
    }
}

/*
void track_line(PID *pid) {  //使用PID算法的版本,三轮小车效果比较不错.
    int p; //P增益
    int i; //I增益
    int d; //D增益
    int gain; //控制量

    pid->position = read_black_line();
    if (pid->position == -1)
    {
//        pwm_moto_left = 0;
//        pwm_moto_right = 0;
//        pid_init(pid);
        return;
    }
com_putchar(pid->position);

    pid->position -= 30;

    pid->hisPosition += pid->position;                 //记录偏差之和

    pid->lastPosition[2] = pid->lastPosition[1]; //
    pid->lastPosition[1] = pid->lastPosition[0]; //
    pid->lastPosition[0] = pid->position;            //

    p = (pid->p) * (pid->position); //计算比例分量(P)=比例系数*本次位置差
    i = (pid->i) * (pid->hisPosition); //计算积分分量(I)=积分系数*偏差之和
    d = (pid->d) * ((pid->position) - (pid->lastPosition[2])); //计算微分分量(D)=微分系数*(本次位置差-前3次的位置差)
                                                               // 由于采样比较快,用本次位置-前3次位置才有足够大的控制
    gain = p + i + d; //P分量和D分量相加,得到控制量

//    if (gain > GAIN)
//        gain = GAIN;
//    if (gain < -GAIN)
//        gain = -GAIN;



    if (gain > 30)
    {
        pwm_moto_left = GAIN + gain;
        pwm_moto_right = GAIN + gain;

        moto_left_forward = 0;
        moto_right_forward = 1;
    } else if (gain < -30) {
        pwm_moto_left = GAIN - gain;
        pwm_moto_right = GAIN - gain;

        moto_left_forward = 1;
        moto_right_forward = 0;
    } else
    {
        pwm_moto_left = GAIN - gain;
        pwm_moto_right = GAIN -gain;

        moto_left_forward = 1;
        moto_right_forward = 1;
    }
}
*/
void main (void)
{
    unsigned int i;

    P2M0 = 0x3C;   //P2.2~P2.5  强推挽输出
    P3M0 = 0x30;   //P3.4,P3.5强输出.

    P1ASF = 0xff;   //P1.7~P1.0用做AD

    i = 0;
    MOTO_IN_A1 = 0;
    MOTO_IN_A2 = 0;
    MOTO_IN_B1 = 0;
    MOTO_IN_B2 = 0;

    
    EA = 0;

    power_stat = 0;

    time0_initialize();

//    com_initialize ();    /* initialize interrupt driven serial I/O */
//    com_baudrate (14400); /* setup for 14400 baud */
/*
    CMOD = 0x01;          // #00000001B,PCA空闲计数,PCA计数源=Fosc/12,PCA溢出中断(做一个定时器使用)
    CCON = 0x00;          //PCA中断标志清0,PCA停止计数
    CL = 0x0;
    CH = 0x0;

    CCAPM1 = 0x31;        //PCA1上升下降沿捕获
*/

    CMOD = 0x03;          // #00000011B,PCA空闲计数,PCA计数源=fosc/2,PCA溢出中断
    CCON = 0x00;          //PCA中断标志清0,PCA停止计数
    CL = 0x0;
    CH = 0x0;

    CCAPM0 = 0x31;        //PCA0上升下降沿捕获

/*
    CCAPM0 = 0x42;        //PCA0工作模式:8位pwm
    PCA_PWM0 = 0x00;
    CCAP0L = 0x40;        //25%占空比,可调节占空比来调节发射功率.低电平驱动.
    CCAP0H = 0x40;
*/


//    EPCA_LVD = 1;         //允许PCA和低压检测中断  
    ELVD = 1;

    car_stat = 0x00;
    pca_tick = 0;
    pca_int_count = 0;
    frame_dog = 0;


    EA = 1;                         /* Enable Interrupts */
    CR = 1;                         //启动PCA计数

    now = pca_tick;

    delay_ms(200);

    read_sensors_check();

    while (1)
    {
        if (power_stat) {
         //   auto_power_down();  //自动关机
        }
        switch (car_stat) {
        case 0:
/*
            MOTO_IN_A1 = 0;
            MOTO_IN_A2 = 0;
            MOTO_IN_B1 = 0;
            MOTO_IN_B2 = 0;
*/
            pwm_moto_left = 0;
            pwm_moto_right = 0;
            break;
        case 1:
            if (!front_obj) {
/*
                MOTO_IN_A1 = 0;
                MOTO_IN_A2 = 1;
                MOTO_IN_B1 = 0;
                MOTO_IN_B2 = 1;
*/
                moto_left_forward = 1;
                moto_right_forward = 1;
                pwm_moto_left = 255;
                pwm_moto_right = 255;
            } else {
/*
                MOTO_IN_A1 = 1;
                MOTO_IN_A2 = 0;
                MOTO_IN_B1 = 1;
                MOTO_IN_B2 = 0;

                delay(1000);
*/
                car_stat = 0;
            }
            break;
        case 2:
            if (!back_obj) {
                moto_left_forward = 0;
                moto_right_forward = 0;

                pwm_moto_left = 255;
                pwm_moto_right = 255;
/*
                MOTO_IN_A1 = 1;
                MOTO_IN_A2 = 0;
                MOTO_IN_B1 = 1;
                MOTO_IN_B2 = 0;
*/
            } else {
/*
                MOTO_IN_A1 = 0;
                MOTO_IN_A2 = 1;
                MOTO_IN_B1 = 0;
                MOTO_IN_B2 = 1;

                delay(1000);
*/
                car_stat = 0;
            }
            break;
        case 3:
            if (!left_obj) {
                moto_left_forward = 0;
                moto_right_forward = 1;

                pwm_moto_left = 255;
                pwm_moto_right = 255;
/*
                MOTO_IN_A1 = 1;
                MOTO_IN_A2 = 0;
                MOTO_IN_B1 = 0;
                MOTO_IN_B2 = 1;
*/
            } else {
/*
                MOTO_IN_A1 = 0;
                MOTO_IN_A2 = 0;
                MOTO_IN_B1 = 0;
                MOTO_IN_B2 = 0;
*/
            }
            break;
        case 4:
/*
            if (!right_obj)
            {
                MOTO_IN_A1 = 0;
                MOTO_IN_A2 = 1;
                MOTO_IN_B1 = 1;
                MOTO_IN_B2 = 0;
            } else {
                MOTO_IN_A1 = 0;
                MOTO_IN_A2 = 0;
                MOTO_IN_B1 = 0;
                MOTO_IN_B2 = 0;
            }
*/
                moto_left_forward = 1;
                moto_right_forward = 0;

                pwm_moto_left = 255;
                pwm_moto_right = 255;
            break;
        case 5:
            track_line(&pid);
            continue;
        case 0xff:
            if (!front_obj) {
                moto_left_forward = 1;
                moto_right_forward = 1;

                pwm_moto_left = 255;
                pwm_moto_right = 255;
                if (pca_tick - now > 300)
                {
                    pwm_moto_left = 0;
                    pwm_moto_right = 0;
                    delay_ms(1000);
                    now = pca_tick;
                }
            } else {
                i = pca_tick % 3;
                if (i == 0 && !left_obj) {
                    moto_left_forward = 0;
                    moto_right_forward = 1;

                    pwm_moto_left = 255;
                    pwm_moto_right = 255;
                    delay_ms(300);
                } else if (i == 1 && !right_obj) {
                    moto_left_forward = 1;
                    moto_right_forward = 0;

                    pwm_moto_left = 255;
                    pwm_moto_right = 255;
                    delay_ms(310);
                } else {
                    pwm_moto_left = 0;
                    pwm_moto_right = 0;
                    delay_ms(300);
                }
                now = pca_tick;
            }
            break;
        default:
            break;       
        }
        PCON |= 0x01;
    }
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -