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

📄 motor.c

📁 AVR Mega128 电机保护程序源码 含过流、欠压、不平衡保护
💻 C
📖 第 1 页 / 共 2 页
字号:
//ICC-AVR application builder : 2004-11-11
// Target : M128
// Crystal: 14.7456Mhz

  #include <iom128v.h>
  #include <macros.h>
  void port_init(void);		  			  	//端口初始化子程序
  void watchdog_init(void);					//WDT初始化子程序
  void timer2_init(void);					//T2初始化子程序
  void adc_init(void);						//AD初始化子程序
  void delay(unsigned int t);  				//延迟(us)子程序
  void INT2SEC(int h);	  					//整数->LED字段转换子程序
  void adc_isr(void);						//AD中断子程序
  void timer2_comp_isr(void);				//T2比较匹配中断子程序
  void dft(unsigned char ADNum);			//DFT子程序
  unsigned int sqrt_32(unsigned long a);	//32位整数开平方子程序
  int fmuls16x16_16(int a,int b);	 		//16位小数乘法子程序
  void _10ms_process(void);	  				//10ms定时处理子程序
  void main(void);							//主程序

  #define DEBUG
//  #define DEBUG_P

  #define bRL1  (1<<0)		 
  #define bRL2  (1<<1)
  #define bLEDB (1<<3)
  #define bLEDA (1<<4)
  #define bS1   (1<<2)
  #define bS2   (1<<5)
  #define cRL3	(1<<5)
  
  #define ADBufLen	  32     				//AD循环缓冲区长度(字)
  #define EERate	  0x100 	 			//EE定值地址
  #define EECal	      0x200 	 			//EE校准值地址
  #define CapDlyTime  6000					//电容延迟接入时间60.00s
  
  //标志字符COMF位定义
  unsigned char COMF,COMFP;
  #define comf_cal	    (1 << 7)
  #define comf_err		(1 << 6)
  #define comf_err_cal	(1 << 5)
  #define comf_err_ee	(1 << 4)
  #define comf_pw_on	(1 << 3)
  #define comf_eewrt	(1 << 2)
  #define comf_s2down	(1 << 1)
  #define comf_s1down	(1 << 0)
  //保护标志字符PRS位定义
  unsigned char PRS,PRSH;
  #define prs_ub		(1 << 6)	//不平衡
  #define prs_lv3		(1 << 5)	//C相欠电压
  #define prs_lv2		(1 << 4)	//B相欠电压
  #define prs_lv1		(1 << 3)	//A相欠电压
  #define prs_oc3		(1 << 2)	//C相过电流
  #define prs_oc2		(1 << 1)	//B相过电流
  #define prs_oc1		(1 << 0)	//A相过电流
  unsigned char WDF;
  #define wdf_ad		(1 << 7)
  #define wdf_t2		(1 << 6)
  #define wdf_main		(1 << 5)

  int ADBuf[8][ADBufLen];       //ADC缓冲区(i1,i2,i3,i1b,i2b,i3b,6:u,7:i0)
  int DFTBuf[ADBufLen];		 	//DFT计算缓冲区
  unsigned char ADBufCnt;    	//AD缓冲区计数(0~ADBufLen-1)
  unsigned char ADBufCntHold;	//AD缓冲区计数(DFT计算时保持)
  unsigned char ADMuxCnt;    	//AD通道转换计数(0~7)
  int ab[8][2];	  	   	     	//DFT计算值(i1,i2,i3,i1b,i2b,i3b,6:u,7:i0)
  unsigned int IU[8]; 	        //有效值计算值(I1,I2,I3,I1b,I2b,I3b,U,I0)
  unsigned int I1,I2,I3,I,U,P,Q,CF,I0;	//测量数据
  unsigned int Iave,Uave,Pave,Qave,CFave,I0ave;
  unsigned long Iacc,Uacc,Pacc,Qacc,CFacc,I0acc;
  unsigned int AveCnt;

  unsigned char _1667usCnt;
  unsigned char _10msCnt;
  unsigned char LEDScanCnt;
  unsigned char DspCnt;
  unsigned char DspBlinkCnt;
  unsigned int PowOnCnt,PowOffCnt;
  unsigned int PowOnDlyCnt;
  unsigned int CapDlyCnt;
  unsigned int TripDlyCnt;
  unsigned char S1DownCnt,S1UpCnt,S2DownCnt,S2UpCnt;
  unsigned char S1ClikCnt,S1ClikDly,S2ClikCnt,S2ClikDly;
  unsigned char LED[4];
  unsigned int CalValue[7];
  unsigned int RateCrt;  	   	   	 //额定电流
  //保护单元
  struct PRT_UNIT{
    unsigned char  OverLmt;		     //确认越限
    unsigned char  OverLmtInst;		 //瞬时越限
    unsigned long  ActDT;		 	 //动作延迟计数器
    unsigned long  RstDT;			 //复位延迟计数器
  };
  struct PRT_UNIT UnitOC[3];		 //过流保护单元
  struct PRT_UNIT UnitLV[3]; 	 	 //欠压保护单元
  struct PRT_UNIT UnitUB;		 	 //不平衡保护单元		 
  //保护参数
  struct PRT_CNST{
    unsigned int  ActLvl;            //动作整定值
    unsigned int  RstLvl;			 //动作返回值
    unsigned int  RstTim;			 //复位延迟时间
    unsigned int  ActTim;			 //动作延迟时间
  };
  struct PRT_CNST CnstOC;		 	 //过流参数  
  struct PRT_CNST CnstLV;		 	 //欠压参数
  struct PRT_CNST CnstUB;		 	 //不平衡参数
  unsigned int  P_CNST_sumchk; 	 	 //保护参数检查和
  unsigned char PRV;			 	 //保护定值

  //AD通道选择表
  const unsigned char ADMux[8]={0x04,0x07,0x03,0x01,0x06,0x02,0x00,0x01};	 
  //数码管字符表
  const unsigned char LEDChar[17]=			   //afbedhcg
  {0b00000101,0b11011101,0b01000110,0b01010100,0b10011100,	//01234	
   0b00110100,0b00100100,0b01011101,0b00000100,0b00010100,	//56789
   0b00001100,0b10100100,0b00100111,0b11000100,0b00100110,  //AbcdE
   0b00101110,0b11111011};									//F.
//=====================================================================
//  保护整定值						
//=====================================================================
  #define CALU   	      2200
  #define CALUMin  	      2000
  #define CALUMax  	      2400
  #define CALi   	      600
  #define CALiMin  	      500
  #define CALiMax  	      700
  #define CALI   	      1200
  #define CALIMin  	      1050
  #define CALIMax  	      1350

  #define adc_rate 		  1*1414/8/511*1200/1000//电流转换因子(满量程100.0A)
  //过电流定值
  #define overcrt_rv	  1200/100	 			//过电流整定值(Ip=1.2Ir)
  #define overcrt_rtn	  1200/100*90/100		//过电流返回值          
  #define overcrt_rst_t	  10					//复位延迟时间(0.1s)         
  #define overcrt_dly_t	  22500					//动作延迟时间(225s)
  //不平衡电流定值
  #define unblnc_rv		  600/100				//不平衡整定值(Un=0.6Ir)
  #define unblnc_rtn	  600/100*90/100	    //不平衡返回值 
  #define unblnc_rst_t	  10					//复位延迟时间(0.1s)
  #define unblnc_dly_t	  3566					//动作延迟时间(35.66s)
  //额定电流:15A,20A,30A,45A,60A,80A
  const unsigned int crt_rv[6]={15,20,30,45,60,80};

#ifdef DEBUG
  const int debug_data0[16]={
  0,196,361,472,511,472,361,196,0,-196,-361,-472,-511,-472,-361,-196};
  const int debug_data1[16]={
  443,311,132,-67,-256,-405,-494,-507,-443,-311,-132,67,256,405,494,507};
  const int debug_data2[16]={
  -443,-507,-494,-405,-256,-67,132,311,443,507,494,405,256,67,-132,-311};
  const int debug_data3[16]={
  0,196,361,472,511,472,361,196,0,-196,-361,-472,-511,-472,-361,-196};
  const int debug_data4[16]={
  443,311,132,-67,-256,-405,-494,-507,-443,-311,-132,67,256,405,494,507};
  const int debug_data5[16]={
  -443,-507,-494,-405,-256,-67,132,311,443,507,494,405,256,67,-132,-311};
#endif 

//============================================================================
//    IO端口初始化
//============================================================================
void port_init(void)
{
   DDRB  = bRL2|bRL1|bLEDA|bLEDB;
   PORTB  = bS1|bS2;
   PORTD = 0xFF;
   DDRD  = 0xFF;
   DDRC = cRL3;
   PORTC = cRL3;
}
//============================================================================
//    看门狗初始化
//============================================================================
//Watchdog initialisation
// prescale: 512K cycles
void watchdog_init(void)
{
   WDR();
   WDTCR=0x18;
   WDTCR=0x0d; 		   //0.5s
}
//============================================================================
//    TIMER0初始化
//============================================================================
//TIMER0 initialisation - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value:  0.998mSec (0.2%)
void timer0_init(void)
{
   TCCR0 = 0x00; //stop
   TCNT0 = 0x1A; //set count
   TCCR0 = 0x03; //start timer
}
//============================================================================
//    TIMER2初始化
//============================================================================
//TIMER2 initialisation - prescale:256
// WGM: Normal
// desired value: 599.99Hz
// actual value: 600.000Hz (0.0%)
void timer2_init(void)
{
   TCCR2 = 0x00; //stop
   ASSR  = 0x00; //set async mode
   TCNT2 = 0xA0; //setup
   OCR2  = 0x5f;
   TCCR2 = 0x0E; //start
}
//============================================================================
//    ADC初始化
//============================================================================
//ADC initialisation
// Conversion time: 56uS
void adc_init(void)
{
   ADCSRA = 0x00;     //关闭ADC
   ADMUX = 0xC0;     //选通0通道,内部REF=2.56V
   ACSR  = 0x80;	 //关闭模拟比较器
   SFIOR = 0x10;	 //ADC高速模式
   ADCSRA = 0x84;	 //0x86:56us
}
//============================================================================
//    延时子程序(微秒)
//============================================================================
void delay(unsigned int t)  
 {  asm("push r24");
  	asm("in r24,0x3f");
  	asm("push r24");
  	asm("push r25");
  	asm("clr r24");
  	asm("clr r25");
  	asm("_loopu::nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");  
  	asm("nop");
  	asm("nop");
  	asm("subi r24,-1");
  	asm("sbci r25,-1"); 
  	asm("cp  r24,%t");
  	asm("cpc r25,r17"); 
  	asm("brlo _loopu");
  	asm("pop r25");
  	asm("pop r24");
  	asm("out 0x3f,r24");
  	asm("pop r24");
 }
//============================================================================
//    INT-SEC转换子程序(100us/14.74MHz)
//============================================================================
void INT2SEC(int h)
{unsigned char i4,i3;	 
   if(h>9999){
      LED[3]=9;
      LED[2]=9;
      LED[1]=9;
      LED[0]=9;
      return;
   }
   i4=h/1000;
   if(i4==0) LED[3]=0xFF; else LED[3]=LEDChar[i4]; 
   h=h%1000;
   i3=h/100;
   if((i3==0)&&(i4==0)) LED[2]=0xFF; else LED[2]=LEDChar[i3];
   h=h%100;
   LED[1]=LEDChar[h/10];
   LED[1]&=~0x04; 
   h=h%10;
   LED[0]=LEDChar[h];
}

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
//    ADC中断子程序
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{int a;
   a=ADCL;
   a+=(((int)ADCH&0x03)<<8);
   ADBuf[ADMuxCnt-1][ADBufCnt]=a-511;
   ADCSRA|=(1<<ADSC);	      //开始AD转换
   delay(4);	
   if(ADMuxCnt<8){
      ADMuxCnt++;		      //选通下个通道
	  ADMUX&=0xF0;
      ADMUX|=ADMux[ADMuxCnt];
   }	
   else	
      ADCSRA&=~(1<<ADIE);    //关闭ADC中断
   WDF|=wdf_ad;			  	  //置看门狗标志
}
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
//    T0中断子程序(1ms)
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
   TCNT0 = 0x1A; //reload counter value
}
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
//    T2比较匹配中断子程序(1.6667ms)
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
#pragma interrupt_handler timer2_comp_isr:4
void timer2_comp_isr(void)
{
  //启动AD转换
  ADBufCnt++;		 		  	  	 //AD缓冲计数器处理
  ADMuxCnt=0;
  ADMUX&=0xF0;
  ADMUX|=ADMux[ADMuxCnt];
  if(ADBufCnt>=ADBufLen) ADBufCnt=0;
  ADCSRA|=1<<ADIE;
  ADCSRA|=1<<ADSC;	  		 		 //开始AD转换
  delay(4);
  ADMuxCnt++;	 				  	 //选通ch1,等待转换完成
  ADMUX&=0xF0;
  ADMUX|=ADMux[ADMuxCnt];
   //LED扫描
  LEDScanCnt++; 
  if(LEDScanCnt>3)
     LEDScanCnt=0;
  switch(LEDScanCnt){
      case 0:
	     PORTD=0xff;
	     PORTB&=~(bLEDB|bLEDA);
		 PORTD=LED[3];
	     break;
	  case 1:
	     PORTD=0xff;
	     PORTB&=~(bLEDB|bLEDA);
		 PORTB|=bLEDA;
		 PORTD=LED[2];
	     break;
	  case 2:
	     PORTD=0xff;
	     PORTB&=~(bLEDB|bLEDA);
		 PORTB|=bLEDB;
		 PORTD=LED[1];
	     break;
	  case 3:
	     PORTD=0xff;
	     PORTB&=~(bLEDB|bLEDA);
		 PORTD=LED[0];
	     PORTB|=(bLEDB|bLEDA);
	     break;
	  default:;   
  }
  if(_1667usCnt++>=5){
     _1667usCnt=0;
     _10ms_process();
  }
}

//============================================================================
//    DFT子程序
//============================================================================
const int SinTable[16]={//汉明窗
  0x0000,0x05A2,0x136F,0x2B0A,0x451E,0x54AC,0x4E50,0x2F44,
  0x0000,0xD0BC,0xB1B0,0xAB54,0xBAE2,0xD4F6,0xEC91,0xFA5E};
const int CosTable[16]={//汉明窗
  0x0A3D,0x0D99,0x136F,0x11D4,0x0000,0xDCEE,0xB1B0,0x8DE3,
  0x8000,0x8DE3,0xB1B0,0xDCEE,0x0000,0x11D4,0x136F,0x0D99};
void dft(unsigned char ADNum)
{ unsigned char i,j;
  int a=0,b=0;
  if((ADNum>=0)&&(ADNum<8)){
    for(i=0;i<16;i++){
  	  j=i+ADBufCntHold+4;
	    if(j>=ADBufLen) j-=ADBufLen; 
	       a+=fmuls16x16_16(ADBuf[ADNum][j],SinTable[i]);
		   b+=fmuls16x16_16(ADBuf[ADNum][j],CosTable[i]);
  	}
	if(COMF&comf_cal){
       ab[ADNum][0]=a; 
	   ab[ADNum][1]=b;
	}
	else{
       ab[ADNum][0]=fmulsu16x16_16(a,CalValue[ADNum]); 
	   ab[ADNum][1]=fmulsu16x16_16(b,CalValue[ADNum]);
	}   
  }
} 
//============================================================================
//    32位平方根子程序
//============================================================================
unsigned int sqrt_32(unsigned long a)
{
   asm("clr r0");
   asm("clr r1");
   asm("clr r2");
   asm("clr r24");
   asm("clr r25");
   asm("clr r6");
   asm("ldi r26,16");
   asm("m03: rol r19");
   asm("rol r0");
   asm("rol r1");
   asm("rol r2");
   asm("rol r19");
   asm("rol r0");
   asm("rol r1");
   asm("rol r2");
   asm("lsl r24");
   asm("rol r25");
   asm("rol r6");
   asm("cp  r24,r0");
   asm("cpc r25,r1");
   asm("cpc r6,r2");
   asm("brsh m01");
   asm("sbc r0,r24");
   asm("sbc r1,r25");
   asm("sbc r2,r6");
   asm("subi r24,-2");
   asm("m01: dec r26");
   asm("sbrs r26,0");
   asm("sbrc r26,1");
   asm("rjmp m03");
   asm("breq m08");
   asm("mov r19,r18");
   asm("mov r18,r17");
   asm("mov r17,r16");
   asm("rjmp    m03");
   asm("m08: lsr r6");
   asm("ror r25");
   asm("ror r24");
   asm("mov r17,r25");
   asm("mov r16,r24");
}
//============================================================================
//    16位有符号小数乘法(16bitx16bit=16bit)
//============================================================================
int fmuls16x16_16(int a,int b)
{   asm("st		-y, R6");
	asm("clr	R6");
	asm("fmuls	R17, R19");   // ((signed)ah * (signed)bh ) << 1
	asm("movw	R4, R0");    //
	asm("fmul	R16, R18");   // ( al * bl ) << 1
	asm("adc	R4, R6");    //
	asm("movw	R2, R0");    //
	asm("fmulsu	R17, R18");   // ( (signed)ah * bl ) << 1
	asm("sbc	R5, R6"); 	  //
	asm("add	R3, R0");
	asm("adc	R4, R1");
	asm("adc	R5, R6");
	asm("fmulsu	R19, R16");   // ( (signed)bh * al ) << 1
	asm("sbc	R5, R6");
	asm("add	R3, R0");
	asm("adc	R4, R1");
	asm("adc	R5, R6");
	asm("movw	R16, R4");
    asm("ld		R6, y+");
}
//============================================================================
//    16位有符号x无符号=有符号小数乘法(16bitx16bit=16bit)
//============================================================================
int fmulsu16x16_16(int a,unsigned int b)
{ 
    asm("clr R6");
	asm("fmulsu R17, R19");
	asm("movw R4, R0");
	asm("fmul R16, R18");
	asm("adc R4, R6");
	asm("movw R2, R0");
	asm("fmulsu R17, R18");
	asm("sbc R5, R6");
	asm("add R3, R0");
	asm("adc R4, R1");
	asm("adc R5, R6");
	asm("fmul R19, R16");
	asm("adc R5, R6");
	asm("add R3, R0");
	asm("adc R4, R1");
	asm("adc R5, R6");
	asm("rol r3");
	asm("adc r4,r6");
	asm("adc r5,r6");
	asm("movw R16, R4");
}
//============================================================================
//    16位无符号x无符号=无符号小数乘法(16bitx16bit=16bit)
//============================================================================
unsigned int fmul16x16_16(unsigned int a,unsigned int b)
{ 
    asm("clr R6");
	asm("fmul R17, R19");
	asm("movw R4, R0");
	asm("fmul R16, R18");
	asm("adc R4, R6");
	asm("movw R2, R0");
	asm("fmul R17, R18");
	asm("adc R5, R6");
	asm("add R3, R0");
	asm("adc R4, R1");
	asm("adc R5, R6");
	asm("fmul R19, R16");
	asm("adc R5, R6");
	asm("add R3, R0");
	asm("adc R4, R1");
	asm("adc R5, R6");
    asm("rol R3");
    asm("adc R4,r6");
    asm("adc R5,r6");
	asm("movw R16, R4");
}

⌨️ 快捷键说明

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