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

📄 smartcar.c

📁 智能遥控车代码
💻 C
字号:
//SmartCar.c : source file for the SmartCar project
//

#include "SmartCar.h"
#include "SmartCarTimer.h"
#include "Motor.h"
#include <delay.h>
#include <math.h>
//#include <eeprom.h>
#include "SmartCarExtINT.h"
#define uint unsigned int
#define uchar unsigned char
#define Run_Towards 0
#define Run_Backwards 1
#define LED_Front_Right	0x30
#define LED_Front_Mid	0x40
#define LED_Front_Left	0x60
#define LED_Back_Right	0x70
#define LED_Back_Mid	0x10
#define LED_Back_Left	0x90
#define LED_Ground_Front_Right	0x20
#define LED_Ground_Front_Left	0x50
#define LED_Ground_Back_Right	0x00
#define LED_Ground_Back_Left	0x80
#define LED_Off 0xF0

#define ADC_Ground_Front_Left	0
#define ADC_Ground_Back_Left	1
#define ADC_Ground_Back_Right	2
#define ADC_Front_Right	3
#define ADC_Ground_Front_Right	4
#define ADC_Front_Mid	5
#define ADC_Front_Left	7
#define Max_Speed 100
#define Time_Const_38K_Trans 0xBA
#define Timer0_Transmit 1
#define Timer0_Time 0
extern bool LED_Front_Mid_State;
extern bool Front_38K_Head, Back_38K_Head;
extern void delay_us(void);
extern bool Not_Get_NewCommand;
extern unsigned int Command_38K;
unsigned int My_Number=0;
//bool wait_conversation=true;
unsigned int Time=0;
//struct Wheel_State
//{
//	bool Side;				//“0”为左轮Left_Wheel
//	bool Run_Direct;		//“0”为正转Run_Towards
//	unsigned int Speed;		//0~Max_Speed
//}w1;
/////////////////////////////////////////////////////////////////////////////
//SmartCar

static void io_init(void)
{
	//{{WIZARD_MAP(General)
	//}}WIZARD_MAP(General)

	//{{WIZARD_MAP(I/O Ports)
	// PortB
	PORTB =0xDE;
	DDRB = 0xDE;
	// PortC
	PORTC = 0x0;
	DDRC = 0x0;
	// PortD
	PORTD = 0xff;
	DDRD = 0xff;
	//}}WIZARD_MAP(I/O Ports)

	//{{WIZARD_MAP(Watchdog)
	// Watchdog Enabled, Prescaler: OSC/16k
	wdt_enable(WDTO_15MS);
	//}}WIZARD_MAP(Watchdog)

	//{{WIZARD_MAP(Analog Comparator)
	// Analog Comparator Disabled
	ACSR = 0x80;
	//}}WIZARD_MAP(Analog Comparator)
}

void Timer0_State(unsigned int State)
{
	if (State== Timer0_Time)
	{
		OCR0A = 0x00;
		OCR0B = 0x00;
		TCNT0 = 0x00;
		TCCR0A = 0x00;
		TCCR0B = 0x05;
		TIMSK0=0x01;
		Time=0;
	}
	else if(State==Timer0_Transmit)
	{
		OCR0A = 0x67;
		OCR0B = 0x00;
		TCNT0 = 0x00;
		TCCR0A = 0x42;
		TCCR0B = 0x01;
	}
	else
	{
		TCCR0B = 0x00;
	}
}

bool Wait_Pioneer(void)//当收到任意38K信号返回"1"
{
		unsigned int Rotate_Times=0;//,temp_PCMSK0;
		PCMSK0 = 0x00;		//关引脚中断
		Timer0_State(Timer0_Time);//设置定时器0为计时状态

		while((Rotate_Times<3) && bit_is_set(PINB,0) && bit_is_set(PINB,5))
			{
				wdt_reset();//左转N毫秒
				PWM_OC1_set	(Run_Backwards,Max_Speed,Run_Towards,Max_Speed);delay(100,8000);PWM_OC1_set	(Run_Towards,0,Run_Towards,0);
				TIMSK0=0x01;	//开时间的中断0
				while((Time<60) && bit_is_set(PINB,0) && bit_is_set(PINB,5))//time<60==>2秒左右
				{	wdt_reset();	}//等待前一辆车自转
				TIMSK0=0x00;//关时间的中断0
				Time=0;		//系统时间清零
				Rotate_Times++;
			}
		Rotate_Times=0;
		while (bit_is_clear(PINB,5) && bit_is_set(PINB,0))//车尾接收到,则调整方向,直至车头接收
			{	PWM_OC1_set(Run_Backwards,40,Run_Towards,40);delay(3,8000);}//继续左转N毫秒
		if (bit_is_clear(PINB,0))
			{//车头接收到,继续调整方向,直至车头接收不到信号
				while (bit_is_clear(PINB,0))
					{	PWM_OC1_set(Run_Backwards,30,Run_Towards,30);delay(2,8000);//继续左转N毫秒
						Rotate_Times++;
					}
				PWM_OC1_set(Run_Towards,30,Run_Backwards,30);delay(2*Rotate_Times,8000);//右转N毫秒
				PWM_OC1_set(Run_Backwards,0,Run_Towards,0);//stop
			}
		PCMSK0=0x21;//开引脚中断
		return (bit_is_clear(PINB,0) || bit_is_clear(PINB,5));
}
void Transmit_Command_Part_0(unsigned int Which_Led)//输出一帧数据"0"
{//输出20T高电平//输出10T低电平
	PORTD=Which_Led;delay_us();delay_us();PORTD=LED_Off;delay_us();
}
void Transmit_Command_Part_1(unsigned int Which_Led)//输出一帧数据"1"
{//输出10T高电平//输出10T低电平
	PORTD=Which_Led;delay_us();	PORTD=LED_Off;delay_us();
}
bool Receive_Command(void)
{
	while(Not_Get_NewCommand)	{	wdt_reset();	}
	//while(Not_Get_NewCommand && (Time<4000)){wdt_reset();Time++;}
	Not_Get_NewCommand=true;
	if (Not_Get_NewCommand)	{	return true;	}//超时
	else					{	return false;	}
}

bool Transmit_Command(unsigned int Command_x4,unsigned int Which_Led,bool Answer)
{
	PCMSK0 = 0x00;//关所有引脚电平变化中断
	Timer0_State(Timer0_Transmit);
	switch (Command_x4)
	{	case 1:	Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);break;
		case 2:	Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);Transmit_Command_Part_0(Which_Led);break;
		case 3:	Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);Transmit_Command_Part_1(Which_Led);break;
		case 4:	Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_0(Which_Led);break;
		case 5:	Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);Transmit_Command_Part_0(Which_Led);Transmit_Command_Part_1(Which_Led);break;
		default:wdt_reset();
	}
	wdt_reset();	Timer0_State(99);
	PCMSK0 = 0x21;//开所有引脚电平变化中断
	TIMSK2 = 0x00;//关定时器2中断
	if (Answer)	{	Receive_Command();	if (Command_38K==Command_x4)	{	return 1;}
										else							{	return 0;}
				}
	else		{	return 1;
				}
}
//int eeprom_is_ready(void);
//void eeprom_write_byte (uint8_t *addr, uint8_t val);
int abs(int i);
unsigned int read_adc(unsigned char adc_input);
void adc_init(void);
void PWM_OC1_set(unsigned int Left_Run_Direct,unsigned int Left_Speed,unsigned int Right_Run_Direct,unsigned int Right_Speed);
int main(void)
{
	//{{WIZARD_MAP(Initialization)
	io_init();
	timers_init();
	adc_init();
	extint_init();
	//}}WIZARD_MAP(Initialization)
	// TODO: Add extra initialization here
	
	//{{WIZARD_MAP(Global interrupt)
	sei();
	//}}WIZARD_MAP(Global interrupt)
	//unsigned int temp;
	//eeprom_write_byte(0x01,0x05);
	//while (eeprom_is_ready()==0)
	//{}
	//temp=eeprom_read_byte (0x01);
	
	PWM_OC1_set(Run_Towards,0,Run_Towards,0);//test
	PORTD=LED_Off;
	//PCMSK0=0x00;
	while(1)
	{
		// TODO: Add your code here
		wdt_reset();
		if (Wait_Pioneer())//是否存在前一部车最长7秒左右
			{//存在!并且车头对着前一部车的车尾
				PWM_OC1_set(Run_Towards,0,Run_Towards,0);
				Timer0_State(Timer0_Transmit);
				PORTD=LED_Front_Mid;//开车头灯
				delay(2,8000);//test
				PORTD=LED_Off;
			}
		else
			{//不存在,则自编号1       //My_Number=0
				Timer0_State(Timer0_Transmit);//设置定时器0为 发射状态
				PWM_OC1_set(Run_Towards,Max_Speed,Run_Backwards,Max_Speed);//向右自转
				Time=0;		PCMSK0=0;
				while(Time<2500 && bit_is_set(PINB,0) && bit_is_set(PINB,5))//测试时等待8秒
					{	wdt_reset();//不能长时间发射,很容易烧管
						PORTD=LED_Back_Mid;	delay(1,8000);PORTD=LED_Off;delay(2,8000);
						Time++;
					}//当等待超过N秒或检测到信号时跳出循环
				PWM_OC1_set(Run_Towards,0,Run_Backwards,0);//停止向右自转
				if (Time==2500)
					{//超时
						//独自一车add code Here:
						
					}
				else
					{//发现第二部车
						//车头收到信号
						if(bit_is_clear(PINB,0))	{	PCMSK0 = 0x01;		}//开PINB.0引脚电平变化中断
						else						{	PCMSK0 = 0x20;		}//开PINB.5引脚电平变化中断
						TIMSK2 = 0x00;//关定时器2中断
						Timer0_State(Timer0_Time);
						Not_Get_NewCommand=true;//等待启动信号
						while((Not_Get_NewCommand || (Command_38K!=0x01)) && Time<1800){wdt_reset();}//等待启动信号
						if(Time==1800)
							{//超时
								//独自一车add code Here:
								
							}
						else//
							{//有启动信号到!!!//开跟踪灯
								Command_38K=0;
								Transmit_Command(1,LED_Front_Mid,false);//向B车回复,要求B车AD准备接收跟踪信号
								Timer0_State(99);//停止Timer0
								PORTD=LED_Front_Mid;
							}
						
					}//End_if (Time==250)
				Time=0;
			}//End_if (Wait_Pioneer())
			
	}//End_while(1)
}//End_int main(void)

⌨️ 快捷键说明

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