说明文件:
设计名称:循迹小车

时间:2006-12-9

关键词:Atemega32 L298 减速电机 光电对管 7812 7805

作者:古欣 朱岩 王智涌 原瑞花 喻巧群

/*********************************************************/

硬件资源分配1.0:12-9

PA0-PA5 光电对管检测
 
PB1,PB2,PB3 电机右 PB3为PWM
PB4,PB5,PD7 电机左 PD7为PWM

PD2 int0 码牌 行程检测

/********************************************************/
电机转向:
PB1 = 1
PB2 = 0 右电机前转

PB4 = 0
PB5 = 1 左电机前转
/********************************************************/

flag; //小车状态
//0未偏 1左偏 2右偏 3前出线 4后出线 5脱轨

主程序:


电机驱动程序:

/****************************************************************
** 文件名:motor.c   电机驱动函数
****************************************************************/
#include "config.h"

/************************左电机动作*****************************/
//左电机前进
void motor_left_forward(uint8 speed)
{
 motol_uen1;
 motol_en2;
 if(speed!=0) //加入调速指令
  {
   OCR0=speed;
  }
 T0_EN;
}
//左电机后退
void motor_left_backward(uint8 speed)
{
 motol_en1;
 motol_uen2;
 if(speed!=0) //加入调速指令
  {
   OCR0=speed;
  }
 T0_EN;
}
//左电机速度设定
void motor_left_speed_set(uint8 speed)
{
 if(speed!=0)
  {
   OCR0=speed;
  } 
}
//左电机滑行
void motor_left_stop(void)
{
 motol_uen1;
 motol_uen2;
 T0_UEN;
}
//左电机急停
void motor_left_quick_stop(void)
{
 motol_en1;
 motol_en2;
 T0_UEN;
}

/*************************右电机动作*****************************/
//右电机前进
void motor_right_forward(uint8 speed)
{
 motor_en1;
 motor_uen2;
  if(speed!=0) //加入调速指令
  {
   OCR2=speed;
   while(ASSR&(1<<TCR2UB)==1) ; //异步操作需要等待 OCR2写入完毕
  }
 T2_EN;
}
//右电机后退
void motor_right_backward(uint8 speed)
{
 motor_uen1;
 motor_en2;
 if(speed!=0) //加入调速指令
  {
   OCR2=speed;
   while(ASSR&(1<<TCR2UB)==1) ; //异步操作需要等待 OCR2写入完毕
  }
 T2_EN;
}
//右电机速度设定
void motor_right_speed_set(uint8 speed)
{
 if(speed!=0)
  {
   OCR0=speed;
   while(ASSR&(1<<TCR2UB)==1) ; //异步操作需要等待 OCR2写入完毕
  } 
}
//右电机滑行
void motor_right_stop(void)
{
 motor_uen1;
 motor_uen2;
 T2_UEN;
}

//右电机急停
void motor_right_quick_stop(void)
{
 motor_en1;
 motor_en2;
 T2_UEN;
}

延时程序:

/****************************************************************
** 文件名:unit.h   定时函数头文件
****************************************************************/
#ifndef _UNIT_H__
#define _UNIT_H__ 1  
//100us
extern void Delay100us(uint8 n);
//1s
extern void Delay1s(uint16 n);
//1ms
extern void Delay1ms(uint16 n);

#endif
/****************************************************************
** 文件名:unit.c   定时函数
****************************************************************/

#include "config.h"
/***************************************************************************
延时公式

*/
void Delay100us(uint8 n)
{
	uint8 i;          //4clock                   
	for(i=147;n!=0;n--)	
	while(--i);      //5 * i clock
}
void Delay1ms(uint16 n)
{        
	for (;n!=0;n--){
		Delay100us(10);
	}
}
void Delay1s(uint16 n)
{
	n=n*40;                
	for (;n!=0;n--){
		Delay100us(250);
	}
}

工程定义头文件:


/****************************************************************
** 文件名:config.h   工程头文件定义
****************************************************************/
#ifndef __config_H__
#define __config_H__ 1

/*********************************************/
#define M8    1
#define M16   2
#define M32   3
#define M64   4
#define M128  5
/*********************************************/
#define CPU_TYPE  M32

//定义MCU时钟频率
//#define F_CPU 14745600
#define F_CPU 7372800
//**************************************************
//包含系统头文件,请根据实际需要进行裁减
//**************************************************
//#pragma REGPARMS
#if CPU_TYPE == M128
#include <iom128v.h>
#endif
#if CPU_TYPE == M64
#include <iom64v.h>
#endif
#if CPU_TYPE == M32
#include <iom32v.h>
#endif
#if CPU_TYPE == M16
#include <iom16v.h>
#endif
#if CPU_TYPE == M8
#include <iom8v.h>
#endif
//#include <intrins.h>
//#include <absacc.h>
#include <string.h>
//#include <FLOAT.H>
//#include <math.h>
//#include <stdlib.h>
#include <macros.h>
//#include <eeprom.h>
//#define const code

//**************************************************
//系统数据类型定义
//**************************************************
#ifndef TRUE
#define TRUE  1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define MIN(a,b)			((a<b)?(a):(b))
#define MAX(a,b)			((a>b)?(a):(b))
#define ABS(x)				((x>0)?(x):(-x))
typedef unsigned char  uint8;  /* 定义可移植的无符号8位整数关键字*/
typedef signed   char  int8;   /* 定义可移植的有符号8位整数关键字*/
typedef unsigned int   uint16; /* 定义可移植的无符号16位整数关键字*/
typedef signed   int   int16;  /* 定义可移植的有符号16位整数关键字*/
typedef unsigned long  uint32; /* 定义可移植的无符号32位整数关键字*/
typedef signed   long  int32;  /* 定义可移植的有符号32位整数关键字*/

//**************************************************
//包含工程头文件,请根据需要进行裁减
//**************************************************
#include "unit.h"
//#include "lcddrive.h"
#include "main.h"
#include "motor.h"
//#include "queue.h"
//#include "TWI.h"
//#include "sio.h" 
//**************************************************
//一下为工程变量、端口定义
//**************************************************

/********************************/
/*     "以下为工程配置"         */
/********************************/

#define T0 used
//#define T1 used
#define T2 used
//#define Int0 used
//#define Int1 used

//计数器0比较计数中断允许
#if T0==used
 #define T0_EN TIMSK |= (1<<OCIE0)|(1<<TOIE0)
 #define T0_UEN TIMSK &=~ (1<<OCIE0)|(1<<TOIE0)
 #define T0_start TCCR0 |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|0x04;
 //0x04 0100B 代表256预分频
 #define T0_stop TCCR0 = 0x00
#endif

//计数器1定时中断允许 //OVERflow
#if T1==used
 #define T1_EN TIMSK |= (1<<TOIE1)|(1<<TOIE1)
 #define T1_UEN TIMSK &=~ (1<<TOIE1)|(1<<TOIE1)
 #define T1_start TCCR1B = 0x02
 #define T1_stop TCCR1B = 0x00
#endif

//定时器2允许,PWM输出
#if T2==used
 #define T2_EN TIMSK |= (1<<OCIE2)|(1<<TOIE2)
 #define T2_UEN TIMSK &=~ (1<<OCIE2)|(1<<TOIE2)
 #define T2_start TCCR2 = (1<<WGM20)|(1<<WGM21)|(1<<COM21)|0x06
 #define T2_stop TCCR2 = 0x00
 //start timer 快速pwm模式,匹配清零,溢出置位 256分频
 //高比低为:(OCR2-0X55)/(0XFF-OCR2)    OX55++++++(0X77)__________OXFF
 //即OCR2越大,输出越大
#endif


//外部中断T0
#if Int0==used
 #define INT0_EN GICR |= (1<<INT0)
 #define INT0_UEN GICR &=~ (1<<INT0)
#endif


//外部中断T1
#if Int1==used
 #define INT1_EN GICR |= (1<<INT1)
 #define INT1_UEN GICR &=~ (1<<INT1)
#endif


#endif


/**********************end******************************/
/** moto test  电机运转情况测试程序*******************************
void main(void)
{
 init_devices();
 
   straight();
    Delay1s(5);
   turn_left();
    Delay1s(5);
   turn_right();
    Delay1s(5);
   straight_back();
    Delay1s(5);
   stop();
 
 while(1)
 ;
}
*************************************************************************/

中断处理;(这里都是定时器比较匹配和溢出中断)

/**********************************************************************
** 文件名:interupts.c   中断处理函数
***********************************************************************/
#include "config.h"

#pragma interrupt_handler timer0_ovf_isr:12
void timer0_ovf_isr(void)
{
 TCNT0 = 0x01; //reload counter value
}

#pragma interrupt_handler timer0_comp_isr:11
void timer0_comp_isr(void)
{
   //compare occured TCNT0=OCR0
}

#pragma interrupt_handler timer2_ovf_isr:6
void timer2_ovf_isr(void)
{
 TCNT2 = 0x01; //reload counter value
}

/**********************************************************************/
// T2 控制PWM输出
// timer2_comp_isr不需要用,但是必须允许中断,在中断时有信号输出变化
/*********************************************************************/

#pragma interrupt_handler timer2_comp_isr:5
void timer2_comp_isr(void)
{
   //compare occured TCNT2=OCR2
}