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

📄 main._c

📁 前两年在一家模型公司开发的
💻 _C
字号:
/********************************************************************************/
//		
// 		builder : 2007-04-10
// 		Target  : ATMEAG 48V
// 		Crystal : 内部 8.00 MHz
//
//		
		
/********************************************************************************/

#include 	<iom48v.h>
#include 	<macros.h>

#include	"eeprom.h"
#include	"time2.h"
#include	"adc.h"


#define		uchar		unsigned char
#define		uint		unsigned int


#define		SET_LED		PORTD |=  (1<<PB4)
#define		CLR_LED		PORTD &= ~(1<<PB4)

uchar	e2rom[7];

uint	PE1,PE2;

uchar	mode;
uchar	rxd_flag;	// 油门接收OK标志

uchar	PWM;
uint	Timer;
uint	high,middle,low;
uchar	REV;

union	
{	uint	temp;
	uchar  	data[2];		
}time;


/*---------------------------------------------------------------
   			初始化
----------------------------------------------------------------*/
void timer0_init(void)
{
 	TCCR0B = 0x00; //stop
 	TCNT0  = 0x01; //set count
 	TCCR0A = 0x23; 
 	OCR0B  = 0xA5;
 	TCCR0B = 0x01; //start timer
}



void timer1_init(void) 		// 20MS 中断
{
 	TCCR1B = 0x00;  // stop
 	TCNT1H = 0xB1;  // setup
 	TCNT1L = 0xE0;
 	OCR1AH = 0x4E;
 	OCR1AL = 0x20;
 	OCR1BH = 0x4E;
 	OCR1BL = 0x20;
 	ICR1H  = 0x4E;
 	ICR1L  = 0x20;
 	TCCR1A = 0x00;
}


void init_devices(void)
{
	asm("cli");
		
 	DDRB  = 0x7F;
 	PORTB = 0xC0;
	
	DDRC  = 0x00;
 	PORTC = 0x00; // m103 output only
 	
 	DDRD  = 0xFB;
 	PORTD = 0x40;
 	
 	MCUCR  = 0x00;
 	EICRA  = 0x03; 	// INT0 上升沿触发
 	EIMSK  = 0x01;	// 使能 INT0 中断
 	
 	timer0_init();
 	timer1_init();
 	timer2_init();
 	init_eeprom();
 	adc_int();
 	
 	asm("sei");
}

/*---------------------------------------------------------------
   			延时
----------------------------------------------------------------*/

void delay(uint t)
{
	uint i,j,k;
	
	for(i=0;i<t;i++)
	{
		for(j=0;j<200;j++)
		{
			for(k=0;k<50;k++);;
		}
	}
}


void LED_set(void)
{
	SET_LED	;
	delay(7);
	CLR_LED	;
	delay(5);
}

/*---------------------------------------------------------------
   			油门处理
----------------------------------------------------------------*/

void Gun_set(void)
{
	if(rxd_flag)	// 接收已完成
	{
		rxd_flag = 0;
		
		if(Timer>high) Timer = high;	// 确保接收到的数据在正常范围内
		if(Timer<low)  Timer = low;
		
		if(Timer>(middle+50))		// 前进 1550us
		{
			PWM = ((Timer-middle)*10)/PE1;	// 计算占空比
			if(PWM>210)PWM = 255;			
			
			Pwm_set(PWM,1);		// 设置PWM占空比
			mode = 1;
			SET_LED;
		}
		else if(Timer<(middle-50)) 	
		{
			if(!mode && REV)	// 后退
			{
				PWM = ((middle-Timer)*10)/PE2;
				if(PWM>210)PWM = 255;
				Pwm_set(PWM,2);
				SET_LED;
				delay(5);
			}
			else 
			{
				Pwm_set(255,3);	// 刹车
				while((Timer+50)<=middle)
				{
					LED_set();
				}
				mode = 0;
			}
		}
		else 
		{
			Pwm_set(0,0);
			CLR_LED;
		}
	}
}




uchar key(void)
{
	uchar i,k=0;
	
	for(i=0;i<5;i++)
	{
		if(PINB & 0x80) k = 0;
		else k ++;
		delay(3);
	}

	return k;
}

/*---------------------------------------------------------------
   			
----------------------------------------------------------------*/

uint compute(void)
{
	uchar 	i;
	uint 	temp = 0;
	
	for(i=0;i<8;i++)
	{	
		while(!rxd_flag);
		temp += Timer;
		rxd_flag  = 0;
		Timer= 0;
	}
	temp = (temp>>3);
	
	return temp;
}


void Buz()
{
	Pwm_set(20,1);
	
	delay(10);
	
	Pwm_set(0,0);
	
	delay(10);
}

void Rev_Setup()
{
	e2rom[6] = EEPROM_read(6);
	
	if(key()>3)	
	{
		while(!(PINB&0x80)); // 等待按键松开
		
		if(e2rom[6]) e2rom[6]=0;
		else e2rom[6] =1;
	}
	EEPROM_write(6,e2rom[6]);
}



/*---------------------------------------------------------------
   			中点设置
----------------------------------------------------------------*/
void Setup()
{
 	 uchar i;
	 

	if(key()>3)		// 设置
	{
loop:	Buz();	
		middle = compute();		// 中位设置
		
		delay(50);
		while(key()<3)
		{
			LED_set();
			delay(35);
		}
		while(!(PINB&0x80));
		high = compute();		// 高位设置
		
		Buz();
		delay(50);
		
		while(key()<3)
		{
			LED_set();
			LED_set();
			delay(35);
		}
		while(!(PINB&0x80));
		low = compute();		// W低位设置
		Buz();
		delay(50);

		// 设置数据正确存盘
		if((low>800&&low<1300)&&(middle>1350&&middle<1650)&&(high>1700&&high<2200))
		{							
			PE1 = ((high-middle)*10)/256+2;
			PE2 = ((middle-low )*10)/256+2;
			
			e2rom[0] = low/256;
			e2rom[1] = low%256;
		
			e2rom[2] = high/256;
			e2rom[3] = high%256;
		
			e2rom[4] = middle/256;
			e2rom[5] = middle%256;
		
			for(i=0;i<6;i++)	// 写EEPOM
			{
				EEPROM_write(i,e2rom[i]);
				delay(5);
				while(compute()<1350||compute()>1650);
			}
			Buz();
			LED_set();
			delay(10);
			LED_set();
		}
		else 	// 设置不对重来
		{
			while(key()<3)
			{
				LED_set();
			}
			delay(100);
			goto loop;
			
		}
	}	
}
		

void Read_E2rom(void)
{	
	uchar i;
	
	for(i=0;i<7;i++)	// 读EEPOM
	{
		e2rom[i] = EEPROM_read(i);
		delay(5);
	}
	
	low 	= e2rom[0]*256+e2rom[1];	// 油门低位
	high 	= e2rom[2]*256+e2rom[3];	// 高位
	middle 	= e2rom[4]*256+e2rom[5];	// 中位
	REV		= e2rom[6];		// 倒车标致
	
	if((low>800&&low<1300)&&(middle>1350&&middle<1650)&&(high>1700&&high<2200))
	{	// 读起的数据正确
		PE1 = ((high-middle)*10)/256+2;
		PE2 = ((middle-low )*10)/256+2;
	}
	else // 读起的数据不正确使用默认值
	{
		PE1 = 23;
		PE2 = 23;
		middle = 1500;
		low	   = 1100;
		high   = 1900;
		REV	   = 1;
	}
}



/*---------------------------------------------------------------
   			INT0 中断油门接收
----------------------------------------------------------------*/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
	if(EICRA==0x03)		// 上升沿开始记时
	{
		TCNT1H = 0x00; 
 		TCNT1L = 0x00; 
 		TCCR1B = 0x02;  //start Timer1
		EICRA  = 0x02;
	}
	else if(EICRA==0x02)	// 下降沿读计时数据
	{
		time.data[0] = TCNT1L;
		time.data[1] = TCNT1H;
		Timer  	= time.temp;
		TCNT1H 	= 0x00; 
 		TCNT1L	= 0x00; 
		EICRA  	= 0x03;
		rxd_flag =1;	// 置接收 flag
	}
}


/*---------------------------------------------------------------
   			main
----------------------------------------------------------------*/

int main(void)
{
	delay(10);
	
	init_devices();		// 初始化
	
	Rev_Setup();
	
	Read_E2rom();		// 读EEPROM
	
	while(!rxd_flag);	// 等待油门信号
	Buz();
	
	LED_set();
	delay(10);
	LED_set();
	
	rxd_flag = 0 ;
	
	while(1)
	{	
		Gun_set();		
		Setup();	
	}
}

/*--------------------   the end ------------------------------------*/

⌨️ 快捷键说明

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