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

📄 df.txt

📁 用和泰单片机的电动车程序
💻 TXT
字号:
#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++;
	       }
	  

⌨️ 快捷键说明

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