/*ROM 3892 BYTES*/
/*功能*/
/*60度/120度直流无刷电机自适应*/
/*软启动*/
/*转把调速*/
/*禁止巡航/手动按键巡航/自动巡航*/
/*过流保护*/
/*限流*/
/*堵转保护(堵转进入静音)*/
/*防飞车保护(上电转把必须归零及防止转把电压出现异常)*/
/*1+1助力*/
/*欠压回差保护*/
/*EABS电子柔性刹车(柔性静音)*/
/*换相补偿*/
/*ISP在线编程、维护和升级软件*/
/*使用最新AT电机专用驱动MCU*/
/*注:堵转退出不可靠的现象已在该程序解决,使用if(drive_duty_var==0)语句*/
/*注:该程序没有按键巡航的功能(已屏蔽)*/
/*注:该程序空载时高速纯使用机械刹车没事*/
/*注:根据余姚路易要求,堵转电流为12A±1A,限流18A±1A*/
/*注:换相时关断MOS管加入了冗余语句close_drive_function()两条,新龙测试时出现的启动复位现象、异常过流现象已基本解决*/
/******************************/
#include "iom48v.h"
//#include "avr/interrupt.h"
//#include "avr/pgmspace.h"
/******************************/
#define QIANYA_VALUE 120 //欠压值预定义(QIANYA_VALUE/255*5)QIANYA_VALUE=118时,欠压值为41.5V±0.5V;QIANYA_VALUE=128时,欠压值为44±0.5V
#define XIANLIU_CURRENT_VALUE 110 //限流值预定义(XIANLIU_VALUE/10A)0B
case 0b00000001:TCCR1A=0b00100001;//开CH
PORTB&=0b11110111;//开BL
break; //⑤电流流向:C->B
case 0b00000010:;
case 0b00000111:TCCR0A=0b00100001;//开BH
PORTD&=0b11110111;//开AL
break; //③电流流向:B->A
case 0b00000011:TCCR1A=0b00100001;//开CH
PORTD&=0b11110111;//开AL
break; //④电流流向:C->A
case 0b00000100:TCCR0A=0b10000001;//开AH
PORTB&=0b11111101;//开CL
break; //①电流流向:A->C
case 0b00000110:TCCR0A=0b00100001;//开BH
PORTB&=0b11111101;//开CL
break; //②电流流向:B->C
default:break;
}
}
/********************************/
/*开三桥函数*/
/********************************/
void change_phase_function1(void)
{
close_drive_function();
close_drive_function();
close_drive_function();
close_drive_function();
close_drive_function();
switch(PIND&0b00000111)
{
case 0b00000000:;
case 0b00000101:TCCR0A=0b10000001;
TCCR1A=0b00100001;//开AH CH
PORTB&=0b11110111;//开BL
break; //⑥电流流向:A->B
case 0b00000001:TCCR1A=0b00100001;//开CH
PORTD&=0b11110111;//开AL
PORTB&=0b11110111;//开BL
break; //⑤电流流向:C->B
case 0b00000010:;
case 0b00000111:TCCR0A=0b00100001;//开BH
PORTB&=0b11111101;//开CL
PORTD&=0b11110111;//开AL
break; //③电流流向:B->A
case 0b00000011:TCCR0A=0b00100001;
TCCR1A=0b00100001;//开BH CH
PORTD&=0b11110111;//开AL
break; //④电流流向:C->A
case 0b00000100:TCCR0A=0b10000001;//开AH
PORTB&=0b11110101;//开BL CL
//PORTB&=0b11111101;//开CL
break; //①电流流向:A->C
case 0b00000110:TCCR0A=0b10100001;//开AH BH
PORTB&=0b11111101;//开CL
break; //②电流流向:B->C
default:break;
}
}
/********************************/
int main(void)
{
//初始化
DDRB=0b00001110;
DDRC=0b00010000;
DDRD=0b01101000;
PORTB=0b11111011;
PORTC=0b01101000;
PORTD=0b10011111; //各端口初始化
/*防飞车保护功能的实现*/
feiche_protect:
ADMUX=0b00100001; //从ADC1通道转换
ADCSRA=0b10000111; //首先128分频,ADC中断禁止
ADCSRB=0b00000000; //单步触发转换模式,1/8MHZ*128*25(最多时钟数)=400us
ADCSRA|=0b01000000; //启动第一次转换开始
while((ADCSRA&0b00010000)==0);
ADCSRA|=0b00010000;//向标志写1来将ADC标志清除
if(ADCH>63)
goto feiche_protect;
//TIMSK0=0b00000000;
TCCR0A=0b00000001;
TCCR0B=0b00000001;
//OCR0A=0;
//OCR0B=0; //定时器0用来做相位修正的PWM输出,初始化为占空比输出0,不引发任何中断
//TIMSK1=0b00000000;
TCCR1A=0b00000001;
TCCR1B=0b00000001;
//OCR1AL=0;
//OCR1BL=0; //定时器1用来做8位相位修正的PWM输出,初始化为占空比0,不引发任何中断
TIMSK2=0b00000001;
TCCR2A=0b00000001;
TCCR2B=0b00000001;
//OCR2A=0;
//OCR2B=0; //定时器2用来做相位修正的PWM输出,初始化占空比为0,并引发定时中断,不分频
ADMUX=0b00100000; //首先从ADC0通道开始转换
ADCSRA=0b10001010; //4分频,开ADC中断使能
ADCSRB=0b00000000; //单步触发转换模式,1/8MHZ*4*25(最多时钟数)=12.5us
ADCSRA|=0b01000000; //启动第一次转换开始
PCICR=0b00000100;
PCMSK2=0b0000111; //使能PCINT16,PCINT17和PCINT18的引脚电平变化中断,以捕获霍尔信号
SREG|=0b10000000; //开总中断
//主循环开始
while(1)
{;}
}
/*******************************************/
/*霍尔信号电平变化中断*/
/*******************************************/
SIGNAL(SIG_PIN_CHANGE2)
{
PORTC^=0b00010000;//霍尔信号变化,则工作指示灯不断闪
}
/******************************************/
/*ADC转换中断*/
/******************************************/
SIGNAL(SIG_ADC)
{
unsigned char m;
switch(adc_int_event_counter)
{
case 0:dianchi_ADC_buffer=ADCH;
adc_int_event_counter=1;
ADMUX=0b00100001;
break;
case 1:if(zhuanba_ADC_buffer>=ADCH)
m=zhuanba_ADC_buffer-ADCH;
else
m=ADCH-zhuanba_ADC_buffer;
if(m>=5) //转把回差电压(0.1V)
{
zhuanba_ADC_buffer=ADCH; //只有转把回差电压大于0.1V,才更新转把
xunhang_counter=0;
}
adc_int_event_counter=2;
ADMUX=0b00100010;
break;
case 2:xianliu_ADC_buffer=ADCH;
adc_int_event_counter=0;
ADMUX=0b00100000;
break;
default:break;
}
ADCSRA|=0b01000000; //启动一次转换开始
}
/**************************************************/
/*定时器2定时中断,约每64uS定时中断一次*/
/**************************************************/
SIGNAL(SIG_OVERFLOW2)
{
/*过流保护的实现*/
if((flag&0b10000000)==0) //如果还没有过流
{
if((PIND&0b10000000)==0)
{
if(++guoliu_sample_counter>=2)
flag|=0b10000000; //过流标志置1
else
guoliu_sample_counter=0;
}
}
else //如果已经过流
{
if(zhuanba_ADC_buffer<64)//如果转把归零,则解除过流保护
flag&=0b01111111; //过流标志清0
}
/*限流的实现*/
if(xianliu_ADC_buffer>xianliu_var)
flag|=0b00001000;
else
flag&=0b11110111; //超过限流比较值,则超限流标志置1,否则清0
/*调速及EABS刹车的实现*/
switch(tiaosu_event_counter)
{
case 0:if((flag&0b01000000)==0) // 如果不是刹车
{
if((flag&0b00000010)==0) //如果不是巡航
drive_duty_buffer=pgm_read_byte(zhuanba_tab+zhuanba_ADC_buffer);
if(((flag&0b00000100)!=0)||((flag&0b00010000)!=0))//如果是电池欠压或者堵转
drive_duty_buffer=0;
if((flag&0b10000000)!=0)
{
drive_duty_var=0; //如果是过流,则立即关闭PWM(无缓冲)
drive_duty_buffer=0;
}
if((flag&0b00001000)==0) //如果不是超限流
{
if(++drive_duty_delay_counter>=10)
{
drive_duty_delay_counter=0;
if(drive_duty_vardrive_duty_buffer)
drive_duty_var--; //当前驱动占空比(drive_duty_var)逐级逼近转把设定的占空比(drive_duty_buffer)
}
}
else if(drive_duty_var>0) //如果是超限流,则细减
drive_duty_var--;
OCR0A=drive_duty_var;
OCR0B=drive_duty_var;
OCR1B=drive_duty_var; //更新PWM
if(drive_duty_var==0)
close_drive_function(); //如果当前驱动占空比等于0,则关闭所