📄 main._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 + -