搜索
bottom↓
回复: 31

求智能循迹小车程序!!【恢复】

[复制链接]

出0入0汤圆

发表于 2009-2-3 17:48:13 | 显示全部楼层 |阅读模式
本人刚开始接触avr,现在想做一个智能循迹小车,在论坛上找了许多原程序,但是注释不是很多,有的不是很明白。所以希望那个大侠能发个注释比较完整的程序供小弟学习。先谢谢了~

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2009-7-28 18:23:29 | 显示全部楼层
下面的这个程序片段,是循迹的功能。
硬件小车 用的犀拓开发网的智能小车,小车采用L293电机驱动芯片,传感器用的红外对管 返回的是高低电平信号
传感器一共用了3个,采用夹着线走的方式

控制器用的Mega16控制器  传感器接PA口,当小车沿着线走, 那么小车不做动作
当小车偏离线时,做相应的调整


//======================================================================
//        函    数:        void car_follow(void)
//        实现功能:        循迹
//        入口参数:        无
//        返回  值:        无
//======================================================================
void car_follow(void)
{
        unsigned int temp;

        temp = PINA&0x07;

        switch(temp)
        {
                case 0x00:                                                // 全部压线,原地右转
                        car_right();
                        while((PINA&0x07) != 0x05);                 // 当中间的传感器没寻到线时,一直保持原地右转
                        car_ahead();                                // 当中间的传感器寻到线时,小车向前直走
                        break;
                case 0x01:                                                // 右中压线,右转
                        car_right();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x02:                                                // 左右压线,直走
//                        car_ahead();
                        break;
                case 0x03:                                                // 右压线,  右转
                        car_right();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x04:                                                // 左中压线,左转
                        car_left();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x05:                                                // 中间压线,直行
//                        car_ahead();
                        break;
                case 0x06:                                                // 左压线,  左转
                        car_left();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x07:                                                // 全不压线,直行
//                        car_ahead();
                        break;
        }
}


以上程序片段用的函数,完整程序见下面

////////////////////////////////////主文件
//======================================================================
//        The information contained herein is the exclusive property of
//        Beijing Bynatec Co., Ltd. And shall not be distributed, reproduced,
//        or disclosed in whole in part without prior written permission.
//        (C) COPYRIGHT 2009 Beijing Bynatec Co., Ltd.
//        ALL RIGHTS RESERVED
//        The entire notice above must be reproduced on all authorized copies.
//======================================================================

//============================================================
//        犀拓开发网 http://www.mcutop.com
//
//        工程名称:        car_follow.aps
//        功能描述:        智能小车循迹
//        IDE环境:        AVR Studio v4.14 WinAVR-20081205
//        操作系统:        windows xp sp3
//        涉及的库:        libc.a
//        组成文件:        main.c
//        硬件连接:        左---中---右
//                                PA0--PA1--PA2
//                                压线:PAn = 0
//                                离线:PAn = 1
//                                key4  == PA3                        按键启动小车
//
//                                晶振7.3728MHz
//        维护记录:        2009年3月2日        v1.0
//======================================================================

//======================================================================
//        文件名称:        main.c
//        功能描述:        智能小车循迹
//        维护记录:        2009年3月2日        v1.0
//======================================================================

#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"
#include "car.h"
#include "key.h"

//======================================================================
//        函    数:        void sensor_init(void)
//        实现功能:        循迹传感器初始化
//        入口参数:        无
//        返回  值:        无
//======================================================================
void sensor_init(void)
{
        DDRA &= ~0x07;                                                // PA0~PA2 设置为输入
}

//======================================================================
//        函    数:        void car_follow(void)
//        实现功能:        循迹
//        入口参数:        无
//        返回  值:        无
//======================================================================
void car_follow(void)
{
        unsigned int temp;

        temp = PINA&0x07;

        switch(temp)
        {
                case 0x00:                                                // 全部压线,原转
                        car_right();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x01:                                                // 右中压线,右转
                        car_right();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x02:                                                // 左右压线,直走
//                        car_ahead();
                        break;
                case 0x03:                                                // 右压线,  右转
                        car_right();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x04:                                                // 左中压线,左转
                        car_left();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x05:                                                // 中间压线,直行
//                        car_ahead();
                        break;
                case 0x06:                                                // 左压线,  左转
                        car_left();
                        while((PINA&0x07) != 0x05);
                        car_ahead();
                        break;
                case 0x07:                                                // 全不压线,直行
//                        car_ahead();
                        break;
        }
}

//======================================================================
//        函    数:        int main(void)
//        实现功能:        主函数 循迹
//        入口参数:        无
//        返回  值:       
//======================================================================
int main(void)
{
        uint8_t key;

        Key_Init();
        car_init();
        sensor_init();

        while(1)                                                // 等待按键启动 KEY4
        {
                key = Key_Get();
                if(key == KEY_4)
                        break;
        }

        car_ahead();                                        // 小车启动
        while(1)
        {
                car_follow();
        }
}


// 定时器0
//ISR(SIG_OVERFLOW0)
ISR(TIMER0_OVF_vect)
{
        Key_Scan();
}

//////////////////////////按键处理文件

//============================================================
// 文件名称:Key.c
// 实现功能:1*4按键扫描程序,适用于低电平有效的按键电路
//                         使用定时器0中断(112.5Hz)
// 日期:    2008/7/28
//============================================================

//================================================
//        按键去抖动时间设定,单位为1/112.5秒
//================================================
#define Key_Debounce        1                        // (4/112.5)秒=28.125ms
//================================================
//        持续按键时间间隔设定,单位1/128秒
//================================================
#define Key_TimeOut                16                        // (64/112.5)秒=0.5688s

//================================================
//        按键使用端口设定
//================================================
#define Key_ALL                        0x08
#define P_Key_Data                PINA
#define        P_Key_Dir                DDRA
#define        P_Key_Port                PORTA
/*
#define P_Key_Data                PINB
#define        P_Key_Dir                DDRB
#define        P_Key_Port                PORTB

#define P_Key_Data                PINC
#define P_Key_Dir                DDRC
#define P_Key_Port                PORTC

#define P_Key_Data                PIND
#define P_Key_Dir                DDRD
#define P_Key_Port                PORTD*/

#include "key.h"
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t KeyCode;                // 存储获得的键值
volatile uint8_t ScanCnt;                // 该变量用来表示按键持续时间
volatile uint8_t KeyUp;                        // 按键是否处于抬起状态

//======================================================================
//        函    数:        void Key_Init(void)
//        实现功能:        初始化按键扫描程序,该函数将开启定时器0溢出中断
//        入口参数:        无
//        返回  值:        无
//======================================================================
void Key_Init(void)
{
        P_Key_Dir &= ~(/*_BV(0) | _BV(1) | _BV(2) | */_BV(3));
        P_Key_Port |= /*_BV(0) | _BV(1) | _BV(2) | */_BV(3);                // 设置按键为上拉电阻
       
        ScanCnt = 0;                        // 初始化变量
        KeyCode = 0;
        KeyUp = 1;

        TCNT0 = 0;
        TCCR0 = _BV(CS02) | _BV(CS00);                // 预分频256
        TIMSK |= _BV(TOIE0);
        sei();                                                                // 使能中断
}

//======================================================================
//        函    数:        void Key_Scan(void)
//        实现功能:        按键扫描,该函数被定时器0中断服务函数程序调用
//        入口参数:        无
//        返回  值:        无
//======================================================================
void Key_Scan(void)
{
        uint8_t key_t;

//        PORTB^=_BV(1);                                // 调试时用来指示
        key_t = ~P_Key_Data;                // 获取IO端口状态
        key_t &= Key_ALL;                        // 判断当前是否有键按下
        if(key_t != 0)
        {
                KeyUp = 0;                                // 按键没抬起
                if(key_t == KeyCode)
                {
                        ScanCnt++;
                }
                else
                {
                        ScanCnt = 0;
                        KeyCode = key_t;
                }
        }
        else
        {
                KeyUp = 1;                                // 按键抬起
        }


}

//======================================================================
//        函    数:        uint8_t Key_Get(void)
//        实现功能:        获取键值
//        入口参数:        无
//        返回  值:        获得的键值
//======================================================================
uint8_t Key_Get(void)
{
        uint8_t key_G;

        cli();                // 关中断
        if((ScanCnt >= Key_Debounce) && (KeyUp == 1))
        {
                key_G = KeyCode;
                KeyCode = 0;
                ScanCnt = 0;

                sei();        // 开中断
                return key_G;
        }
        if((ScanCnt >= Key_TimeOut) && (KeyUp==0))
        {
                key_G = KeyCode;
                KeyCode = 0;
                ScanCnt = 0;
                KeyUp = 1;

                sei();        // 开中断
                return key_G;
        }

        sei();
        return 0;        // 没有按键

}


//////////////////////////////////////小车驱动文件
//============================================================
// 犀拓开发网 http://www.mcutop.com
//
// 文件名称:car.c
// 实现功能:小车驱动
// 日期:         2009年3月2日
//============================================================

#include "avr/io.h"
#include "util/delay.h"

void car_init(void)
{
        DDRD |= _BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5);
}

void car_stop(void)                                        // 刹车
{
        PORTD |= _BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5);
}

void car_ahead(void)                                // 前进
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD2) | _BV(PD4);
}

void car_backward(void)                                // 后退
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD3) | _BV(PD5);
}

void car_left_Circle(void)                        // 原地左转
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD3) | _BV(PD4);
}

void car_right_Circle(void)                        // 原地右转
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD2) | _BV(PD5);
}

void car_left_stop(void)                        // 左转,左轮不动
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD2) | _BV(PD3) | _BV(PD4);
}

void car_right_stop(void)                        // 右转,右轮不动
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD2) | _BV(PD4) | _BV(PD5);
}

void car_left(void)                                        // 左转
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD4);
}

void car_right(void)                                // 右转
{
        PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
        _delay_ms(10);
        PORTD |= _BV(PD2);
}
智能小车循迹完整程序ourdev_465283.rar(文件大小:22K) (原文件名:car_follow.rar)

出0入0汤圆

发表于 2009-7-31 10:33:21 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2009-8-6 15:56:24 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2009-8-8 19:15:59 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2009-8-10 15:05:20 | 显示全部楼层
xiexiefenxiang

出0入0汤圆

发表于 2009-8-27 16:39:01 | 显示全部楼层
谢谢分享,很有用!

出0入0汤圆

发表于 2009-8-31 15:19:26 | 显示全部楼层
谢谢分享,我以前做过舵机的,和直流电机控制转弯的,今天来学学控制转速比来转向

出0入0汤圆

发表于 2009-12-3 19:35:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-23 20:26:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-24 12:05:42 | 显示全部楼层
好资料   留个记号   下次来玩玩这个速度控制的!

出0入0汤圆

发表于 2010-4-10 17:20:40 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2010-4-10 20:22:28 | 显示全部楼层
void car_stop(void) // 刹车
{
PORTD |= _BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5);
}

void car_ahead(void) // 前进
{
PORTD &= ~(_BV(PD2) | _BV(PD3) | _BV(PD4) | _BV(PD5));
_delay_ms(10);
PORTD |= _BV(PD2) | _BV(PD4);
}
请问PD2.3.4.5引脚接得是什么,怎么全为1时就刹车。2.4为1时就前进!

出0入0汤圆

发表于 2010-5-11 13:09:37 | 显示全部楼层
学习学习!!!

出0入0汤圆

发表于 2010-5-12 11:49:18 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2010-5-12 21:26:37 | 显示全部楼层
马克!

出0入0汤圆

发表于 2010-5-25 11:49:48 | 显示全部楼层
看别人的程序还不如自己写

出0入0汤圆

发表于 2010-5-26 15:40:44 | 显示全部楼层
THANKS!

出0入0汤圆

发表于 2010-7-16 13:33:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-13 16:58:09 | 显示全部楼层
谢谢分享。

出0入0汤圆

发表于 2011-3-21 22:15:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-22 19:30:19 | 显示全部楼层
太棒了啊!!!

出0入0汤圆

发表于 2011-3-24 17:45:50 | 显示全部楼层
MARK!!

出0入0汤圆

发表于 2011-3-30 13:59:00 | 显示全部楼层
回复【1楼】odysseuslx 刘学
-----------------------------------------------------------------------
odysseuslx 刘学
我现在也正在做用l293d驱动直流电机,但是很不稳定,我发前进指令时,小车的两个车轮先转一会,然后又一个就不转了,另一个接着转,给单片机掉电,然后还是这个情况,有时候两个一起转,但一会也停,不稳定!我的电源是两节3.7v电池并联供电的。感觉电机的电感对单片机冲击挺大的!你能把你的电路图给我看看吗?感激不尽!

出0入0汤圆

发表于 2011-5-10 11:05:34 | 显示全部楼层

出0入0汤圆

发表于 2011-9-23 18:23:12 | 显示全部楼层
hao

出0入0汤圆

发表于 2011-9-28 16:10:20 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-8-19 20:27:21 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-8-22 23:21:42 | 显示全部楼层
mark.......

出0入0汤圆

发表于 2015-7-18 20:24:08 | 显示全部楼层
mark,简直棒!

出0入0汤圆

发表于 2015-7-18 21:14:31 来自手机 | 显示全部楼层
谢谢分享
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-28 18:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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