?? ddc_b.c
字號:
#include <ht45rm03.h>
#include "htddc.h"
#pragma vector isr_comp @ 0x4
#pragma vector isr_int0 @ 0x8
#pragma vector isr_int1 @ 0xc
#pragma vector isr_pwm @ 0x10
#pragma vector isr_tmr0 @ 0x14
#pragma vector isr_tmr1 @ 0x18
//ISR for safequard
void isr_comp() // 比較器輸出
{ _cf=0;
if(!_cmpop)//確認是否有效的低電平
{
_pwmh=0;_pwml=0;//關閉PWM
_pc=0b00101010;
_misc=0b00100100; //_misc.4=pwmctrl==>PWM總開關
_pwmc=0x44; //死區開啟,延遲0.33us
pwm_enable_f=0;//xunhan_f=0;
runing_err_f=1;
delay_3s=60;
}
}
void isr_int0() // 外部INT0A,B,C
{
}
void isr_int1(){} // 外部INT1
void isr_pwm(){} // PWM
void isr_tmr0() // timer/event 0//電機霍爾檢測
{
read_xy:
xy_temp =_pa;xy_temp &=0x70;
for(xy_i=2;xy_i>0;xy_i--)
{
xy_temp1=_pa;xy_temp1 &=0x70;
if(xy_temp!=xy_temp1)goto read_xy;
}
xy_temp>>=4;xy_temp&=0x07;
_t0f=0; //33.33us once
ms++;sys_5ms++;time_f=1;
if(xy_temp!=xy_buf){xy_buf=xy_temp;xy_cnt=0;}
else xy_cnt++;
if(xy_cnt>=2)
{ xy_cnt=0;
if(xy_buf==0||xy_buf==7){xy_err++;xy_err_f=1;_pc=djout120[0];}
else
{if(xy_err_f)
{xy_err_f=0;last_xy=xy_buf;}
if(xy_err!=0)xy_err--;
if(xy_err>9)xy_err--;
if(pwm_enable_f)_pc=djout120[xy_buf];
}
}
}
void isr_tmr1() // timer/event 1//與PC的串行通訊1200波特率
{ _t1f=0;
if(tx_bit1_3==0)
{ tx_bit1_3=2;
if(tx_bit_cnt==9)TX=0;
else
{if(tx_bit_cnt>0)
{if(tx_buf&1)TX=1;else TX=0;
tx_buf>>=1;
}
}
if(tx_bit_cnt==0)TX=1;
else tx_bit_cnt--;
}
else tx_bit1_3--;
//receive
if(rx_sta_f)
{ if(rx_bit1_3==0)
{ rx_bit1_3=2;
rx_buf>>=1;
if(RX)rx_buf |= 0x80;
rx_bit_cnt--;
if(rx_bit_cnt==0)
{rx_sta_f=0;rx_bak_f=1;_mp1=rx_buf;tx_buf=_iar1;tx_bit_cnt=9;//
}
}
else rx_bit1_3--;
}
else { if(!RX && !rx_bak_f){rx_sta_f=1;rx_bit1_3=2;rx_bit_cnt=8;}
if(RX)rx_bak_f=1;else rx_bak_f=0;
}
}
//=========================================
void offset_cmp(void)
{ unsigned char temp,temp1,tempa,i;
_cmpc=0b10110000;_nop();_nop();//以CMP+為參考
temp=_cmpc & 0b01000000;//讀cmp out
for(i=15;i>0;i--)
{ _cmpc++;_nop();_nop();
temp1=_cmpc & 0b01000000;
if(temp!=temp1)break;
}
tempa=_cmpc & 0x0f;
_cmpc=0b10111111;_nop();_nop();
temp=_cmpc & 0b01000000;
for(i=15;i>0;i--)
{ _cmpc--;_nop();_nop();
temp1=_cmpc & 0b01000000;
if(temp!=temp1)break;
}
i=_cmpc & 0x0f;
tempa+=i;tempa>>=1;tempa &= 0x0f;
_cmpc=0b10000000;
_cmpc |= tempa;
}
//------------------------------------
void offset_opa(void)
{ unsigned char temp,temp1,tempa,i;
_opac=0b10100000;_nop();_nop();//以OPA-為參考
temp=_opac & 0b01000000;//讀opa out
for(i=15;i>0;i--)
{ _opac++;_nop();_nop();
temp1=_opac & 0b01000000;
if(temp!=temp1)break;
}
tempa=_opac & 0x0f;
_opac=0b10111111;_nop();_nop();
temp=_opac & 0b01000000;
for(i=15;i>0;i--)
{ _opac--;_nop();_nop();
temp1=_opac & 0b01000000;
if(temp!=temp1)break;
}
i =_opac & 0x0f;
tempa+=i;tempa>>=1;tempa &= 0x0f;
_opac=0b10000000;
_opac |= tempa;
}
//=========================================
void djmode_set(void)//檢測電機的類型60或120度的
{ unsigned char temph,templ,i;
temph = 0;templ = 0;
for(i=24;i>0;i--)
{ _pbc |= 0b10000000;
if(djmode_pin)temph++;
else templ++;
_delay(100);
}
if(temph>templ)djmode_f=1;
else djmode_f=0;
}
//=========================================
//測量A/D并平均8次
//=========================================
unsigned char ad_pro(unsigned char channel)
{ unsigned char i;
unsigned long temp;
channel &=0x3;
_adcr =0b00011000;
_adcr|=channel;
temp=0;
for(i=8;i>0;i--)
{ _start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
while(_eocb)_nop();
temp+=_adrh;
}
temp>>=3;
i=(unsigned char)temp;
return(i);
}
//===========================================
void nmos_chk(void)
{ unsigned char temp;
off_pwm_pro();
_pc=0;//打開所有下橋
_adcr =0b00011010;//電流AN2
_delay(10);
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
_delay(300);
_pc=0b00101010;//關閉all nmos
while(_eocb)_nop();
temp=_adrh;
if(temp>i_normal)nmos_err_f=1;
if(nmos_err_f)return;
_pc=0x3f;//打開所有上橋
_adcr =0b00011010;//電流AN2
_delay(10);
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
_delay(300);
_pc=0b00101010;//關閉all nmos
while(_eocb)_nop();
temp=_adrh;
if(temp>i_normal)nmos_err_f=1;
}
//==========================================
void first_i(void)
{ unsigned char temp;
temp=ad_pro(2);//電流測量在AN2
if(temp>8){opa_err_f=1;temp=0;}
i_normal=temp+25;
i_max=temp+50;
}
//==========================================
void break_chk(void)
{ unsigned char temph,templ,i;
temph = 0;templ = 0;
for(i=16;i>0;i--)
{ _pac |= 0b10000000;//pa7/int1 --break input
if(break_pin)temph++;
else templ++;
_delay(100);
}
if(temph>templ)break_f=0;
else break_f=1;
}
//==========================================
void time_nms(void)//200us once
{
if(sys_5ms>=150){sys_5ms=0;sys50ms++;}//150*0.03333ms=5ms
else return;
if(sys50ms>=10)sys50ms=0;
else return;
if(vol_del3s!=0)vol_del3s--;//50ms once
if(delay_3s!=0)delay_3s--;//50ms once
if(disp_once==0)
{ disp_once=96;//7s
if(nmos_err_f){flash_num=4;goto led_set_end;}
if(runing_err_f){flash_num=5;goto led_set_end;}
if(xy_err>6){flash_num=6;goto led_set_end;}
if(vol_low_f) {flash_num=8;goto led_set_end;}
if(break_f) {flash_num=2;goto led_set_end;}
if(opa_err_f) {flash_num=3;goto led_set_end;}
if(pwm_enable_f)flash_num=0;//工作不亮
else flash_num=200;//不工作正常一直閃
led_set_end:_nop();
}
else disp_once--;
if(disp_ms==0)
{ if(flash_num!=0)
{disp_ms=8;flash_num--;}
}
else disp_ms--;
if(disp_ms<4)off_led;else on_led;
}
//=========================================
// ;取樣電阻7.5K+7.5K+1.2K
// ;40.V電壓轉換值:151
// ;41.V電壓轉換值:155
// ;42.V電壓轉換值:159
// ;43.V電壓轉換值:163
// ;44.V電壓轉換值:167
// ;45.V電壓轉換值:171
void vol_chk_pro(void)//電流因素未考慮
{
if(vol_buf>154)
{ if(vol_before_f){vol_before_f=0;vol_del3s=60;}//3s=60*50ms
if(vol_del3s==0)vol_low_f=0;
}
if(vol_buf<142)
{ if(!vol_before_f){vol_before_f=1;vol_del3s=60;}
if(vol_del3s==0)vol_low_f=1;
}
}
//=========================================================
//轉速把電壓范圍處理
//自行車:限速模式下應為1.2V--4.2V,
//轉把霍爾正常輸出低電平為0.8-->1.0V
//=========================================================
void spd_chk_pro(void)
{ unsigned char temp,tt;
//if(xunhan_f)return;
temp=spd_buf;
if(spd_buf<59)spd_first_f=0;//ad59==>1.15v
if(temp>=65)temp-=65;//ad65==>1.27v
else temp=0;
if(spd_first_f)temp=0;//spd_first_f為上電有轉把信號
if(temp>99)temp=100;
tt=temp>>1; //tt=temp/2
temp<<=1;
temp+=tt; //temp*2.5
spd_cnt++;
spd_add+=temp;
if(spd_cnt<8)return;
spd_add>>=3;//8次SPD平均
spd_bufa=(unsigned char)spd_add;
spd_cnt=0;
spd_add=0;
if(spd_bufa<5)
{ nmos_chk_f=1;flag_set_f=0;nmos_err_f=0;
runing_err_f=0;pwm_enable_f=0;
run_3s=0;return;
}
if(nmos_chk_f)//啟動電機之前要檢MOS管正常與否
{nmos_chk();//檢測NMOS電橋(DQ)有無擊穿故障
huanxian_cnt=0;
}
nmos_chk_f=0;
if(delay_3s!=0){pwm_enable_f=0;run_3s=0;return;}
if(runing_err_f){pwm_enable_f=0;run_3s=0;return;}// nmos_err_f||break_f||||vol_low_f
if(xy_err>6){pwm_enable_f=0;run_3s=0;return;}
pwm_enable_f=1;
if(_pwmh<spd_bufa)_pwmh++;
if(_pwmh>spd_bufa)_pwmh--;
if(_pwmh<5)_pwmh=6;
if(_pwmh<245){_pwmc =0b01000101;_misc=0b00110100;}
else {_pwmc =0b01000100;_misc=0b00100100;}//PWM>95%==>100%
//if(!flag_set_f)//設flag_set_f目的是剛開始讓duzuan_lev2_f=0;
// {flag_set_f=1;pwm_enable_f=1;duzuan_lev2_f=0;}
}
//=========================================
void break_pro(void)
{
if(break_pin){break_f=0;break_cnt=0;}
else break_cnt++;
if(break_cnt>30)break_f=1;
}
//=========================================
void io_set(void)
{ _pac=0b11111111;//pa7/int1==>手剎,pa4,5,6電機霍爾 配置上拉
_pbc=0b01111111;//pb7,6->TX RX;;;pb5,4->SDA,SCL 配置上拉
//pb2/AN2電流AD;;pb1/AN1電池電壓AD;;pb0/AN0手柄調速AD
_pdc=0;
_pcc=0x00;
//_couten=1;//PA3=GPIO COUT不在這輸出
}
//==============================================================
void pwm_out_pro(void)
{
}
//=======================================================
void off_pwm_pro(void)
{
_pwmh=0;_pwml=0;//關閉PWM
_pc=0b00101010;
_misc=0b00100100;
_pwmc=0x44;//有0.33us死區時間
}
//========================================
void init(void)
{unsigned char i;
if(_to)return;
_intc0=0;_intc1=0;
off_pwm_pro();
off_led;//pd0==>led
TX =1;
_pc=0b00101010;
io_set();
_pc=0b00101010;
off_led;//pd0==>led
TX =1;
_wdts=7;
for(i=250;i>0;i--)
{
_clrwdt1();
_clrwdt2();
_delay(6000);
} //delay 500ms
sta_flag.byte=0;sta_flag_a.byte=0;
disp_ms=0;disp_once=0;flash_num=0;
spd_cnt=0;spd_bufa=0;delay_3s=0;
offset_cmp();
offset_opa();
}
//***************************************************************
void main(void)
{ _acsr=2;//AD clock Fsys/32
init();
spd_add=0;
djmode_set();
first_i();
vol_buf = ad_pro(1);//電壓測量在AN1
break_chk(); //檢測剎車有否
spd_buf = ad_pro(0);// 轉把測量在AN0
//if(spd_buf>66)spd_first_f=1;//66==>1.29v
//#asm
//set [0ffh].2
//#endasm
nmos_chk();//檢測NMOS電橋(DQ)有無擊穿故障
_tmr0=156;//100=256-156
_emi=1;_et0i=1;
_tmr1=152;//256-152=104
_tmr1c=0b10010101;//定時器12MHZ 278us//Fsys/16==>add 1 === 4/3us
_et1i=1;
nms=0;
while(1)
{ _clrwdt1();
io_set();
if(pwm_enable_f)_eci=1;//允許比較器
else off_pwm_pro();
_tmr0c=0b10010010;//定時器12MHZ 25us//Fsys/4
if(time_f)
{time_f=0;time_nms();}
if(ms>7)//25us*8=0.2ms
{ms=0;_acsr=2;//AD clock Fsys/32
if(pwm_enable_f)huanxian_cnt++;
switch(nms)
{
case 0:{_adcr =0b00011010;//AN2測電流
_delay(10);
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
break;
}
case 1:{
if(_adcr ==0b00011010)i_buf=_adrh;
_adcr =0b00011000;//AN0測手柄調速
break_pro();
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
break;
}
case 2:{if(_adcr ==0b00011000)spd_buf = _adrh;
_adcr =0b00011010;//AN2測電流
spd_chk_pro();
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
break;
}
case 3:{if(_adcr ==0b00011010)i_buf=_adrh;
_adcr =0b00011001;//AN1測電池電壓
_delay(10);
_start=0;_nop();
_start=1;//reset AD
_start=0;//start AD
break;
}
case 4:{if(_adcr ==0b00011001)vol_buf = _adrh;
vol_chk_pro();
nms=0xff;
break;
}
default:nms=0xff;
}
nms++;
}
_clrwdt2();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -