📄 motor.c
字号:
//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 + -