📄 last5.c
字号:
{current_b_fault_flag=1;}
if(current_c_fault_counter>5)
{current_c_fault_flag=1;}
if(volt_ab_fault_counter>2) // 如果电压故障连续2次以上(时间<3s),则置电压故障标志并退出
{volt_ab_fault_flag=1;}
if(volt_bc_fault_counter>2)
{volt_bc_fault_flag=1;}
if(volt_ca_fault_counter>2)
{volt_ca_fault_flag=1;}
}// 工频启动循环监测结束
}// end of "if(gp_start_flag==1)"
goto mainprog;
}//main end
//----------------------------------------------------------------------------------------------
// 子程序
//----------------------------------------------------------------------------------------------
void init_cpu(void)
{
//晶振设置
//OSCXCN = 0x67;// start external oscillator with
// 11.0592MHz crystal
//for (i=0; i < 256; i++) ;
// XTLVLD blanking interval (>1ms)
//while (!(OSCXCN & 0x80));
// Wait for crystal osc. to settle
//OSCICN = 0x88;// select external oscillator as
// SYSCLK source and enable missing
// clock detector
OSCICN=0x95; // start internal oscillator with 4MHz crystal
//-----------------------------------------------
//复位源设置
EA = 0;
WDTCN = 0xDE; // 屏蔽看门狗
// 写0XDE和写0XAD必须发生在4个时钟周期之内 WDTCN = 0xAD;
RSTSRC= 0x00; // 复位源寄存器设置?
//-----------------------------------------------
//交叉开关配制:PCA0 - CEX0、CEX1
// UART0- RX0、TX0
// SMBUS- SDA、SCL
// UART1- RX1、TX1连到端口引脚
XBR0 = 0x15;
XBR1 = 0x00;
XBR2 = 0x84; // 弱上拉全局禁止(允许)
//-----------------------------------------------
//SMBus(IIC总线)设置
SMB0CR = 0xfb; // SMBus时钟频率= 400kHz.
//SMB0CN
//SMB0DAT
//SMB0ADR
//SMB0STA
//-----------------------------------------------
//P0、P1、P2、P3、P4、P5、P6、P7端口设置
//通过设置输出方式为漏极开路并向端口数据寄存器中
//的相映位写1可将端口引脚配置为输入
P0MDOUT = 0x00; // P0口为漏极开路输出
P1MDIN = 0xff; // P1口用作数字输入输出
P1MDOUT = 0x07; // P1.0-P1.2设置为推挽输出
// P1.3-P1.7设置为漏极开路,做输入
key_in1 =1; // P1.3
key_in2 =1; // P1.4
key_in3 =1; // P1.5
key_in4 =1; // P1.6
in_wz1 =1; // P1.7
P2MDOUT = 0x00; // P2口设置为漏极开路输出
// P2.0 - P2.4做输入
in_wz2 =1; // P2.0
in_bp_start =1; // P2.1
in_gp_start =1; // P2.2
in_bp_fault =1; // P2.3
in_add =1; // P2.4
P3MDOUT = 0xff; // P3口为推挽输出
P74OUT = 0xff; // P4 - P7口为推挽输出
//-----------------------------------------------
// AD、DA参考电压设置
REF0CN = 0x07;// ADC0电压基准取自VREF0引脚
// ADC1电压基准取自VREF0引脚
// 温度传感器工作
// 内部偏压发生器工作
// 内部电压基准缓冲器允许
//-----------------------------------------------
//ADC0设置
AMX0CF = 0x00; // 设置8路ADC0均为单端输入
AMX0SL = 0x01; // ADC0通道选择
ADC0CF = 0x20; // ADC0转换时钟频率为1MHz,增益为1
ADC0CN = 0x80; // 采用跟踪方式
// 转换结果寄存器数据右对齐
// ADC0转换过程控制如下:
// 1、写0到AD0INT
// 2、向ADBUSY写1
// 3、查询并等待AD0INT变1
// 4、处理ADC0H和ADC0L数据
//-----------------------------------------------
//DAC0设置
DAC0CN = 0x84; // DAC0允许
// 设置输出更新发生在写DAC0H时
// 输出数据在DAC0H和DAC0L中为左对齐
DAC0L = 0x00; // DAC0 Low Byte Register
DAC0H = 0x00; // DAC0 High Byte Register
//-----------------------------------------------
//数据存储器设置
EMI0CF = 0x34; // 外部数据存储器挂在高端口P4-P7
// 使用非复用方式
// 使用不带块选择的分片方式
//-----------------------------------------------
// 可编程计数器阵列设置(PWM)
// 由于该8位PWM完全受硬件控制不需要额外的CPU周期来维持
// 固定的占空度,改变占空度只需要向模块的比较寄存器
// PCA0CP0H的高字节写一个8位数
PCA0CPL0 =0; // 初始化PCA0的PWM值
PCA0CPH0 =0; //
PCA0CPM0 = 0x42; // 选择8位PWM方式
// 频率输出允许
// 禁止CCFN中断
// 写PCA0CPH0改变占空比
PCA0MD = 0x00; // 系统处于等待方式时,PCA0继续正常工作
// 禁止CF中断
// PCA0时基 = SYSCLK / 12
PCA0CN = 0x40; // 允许PCA计数器
//-----------------------------------------------
//UART设置
SCON0 = 0x40; // 设置UART0工作在方式1,8位UART
T2CON = 0x34; // 用定时器2产生串口波特率
RCAP2H = 0xff; // Timer 2 Capture Register High Byte
RCAP2L = 0xe6; // Timer 2 Capture Register Low Byte
TH2 = 0xff; // Timer 2 High Byte
TL2 = 0xe6; // Timer 2 Low Byte
// 使用内部4MHz晶振,波特率设置为 4800 bps
//PT2=1;
TR2=1;
//-----------------------------------------------
//定时器1设置
TMOD= 0x01; // 用定时器0作软件时钟
// 16位定时器
// system's clock is internal 4MHz
TH0 = 0xF2; // 10ms定时器初值0xF2F9 (0xDBFF---11.0592MHz)
TL0 = 0xF9;
PT0 = 1;
TR0 = 1;
//-----------------------------------------------
//中断设置
ET0=1;
EA=1;
//-----------------------------------------------
XBR2 = 0xc4; // 启动交叉开关设置
//-----------------------------------------------
}
//----------------------------------------------------------------------------------------------
//----------------------延时程序
void delay(uint i)
{ uint j;
for(j=0;j<=i;j++);
}
//----------------------------------------------------------------------------------------------
void switch_bp_gp(void)//----------------------变频停止,工频启动
{
out_bgq=0;// 工频起
for(timer0_10ms=0;timer0_10ms<30;);
out_bgq=1;
out_bgt=0; // 变频停
}
//----------------------------------------------------------------------------------------------
void ad_channel_select(uchar ad_channels_select)
{
AMX0SL = ad_channels_select; //ADC0通道选择: 0x00电流,0x01电压
}
//----------------------------------------------------------------------------------------------
//----------------------模拟开关通道切换
void iu_channel_select(uchar iu_channels_select)
{
switch(iu_channels_select) //三相电流电压通道选择
{
case 1: {out_ad_select_iu1=0;
out_ad_select_iu2=0;
break;
}
case 2: {out_ad_select_iu1=0;
out_ad_select_iu2=1;
break;
}
case 3: {out_ad_select_iu1=1;
out_ad_select_iu2=0;
break;
}
default:{out_ad_select_iu1=1;
out_ad_select_iu2=1;
break;
}
}
for(timer0_10ms=0;timer0_10ms<40;);//模拟开关切换延时
}
//----------------------------------------------------------------------------------------------
//----------------------将两个字节合成一个字
uint change_2byte_1word(uchar datah,uchar datal)
{ uint wqy_word1,wqy_word2;
wqy_word1=datah;
wqy_word2=datal;
return ((wqy_word1<<8)|wqy_word2);
}
//----------------------------------------------------------------------------------------------
//----------------------AD采样,连续20毫秒采样取平均
//使用软件算法去除坏点
//采样结果:高位ADC0H、低位ADC0L
uint ad_sampling(void)
{
uint measure_counter, ad_temp_word, j;
uchar i;
float ad_total;
for(timer0_10ms=0;timer0_10ms<1;) // 连续10毫秒采样去坏点
{
AD0INT = 0;
AD0BUSY= 1;
while(AD0INT==0);
}
measure_counter=0;
for(timer0_10ms=0;timer0_10ms<1;) // 连续10毫秒采样取平均
{
AD0INT = 0;
AD0BUSY= 1;
while(AD0INT==0);
measure_counter+=1;
measure_data16[measure_counter]=change_2byte_1word(ADC0H,ADC0L);
if(measure_counter>500) measure_counter=500;
//delay(100);
}
for(i=1;i<=10;i++) // 查找10个最大值排在前10位
{for(j=i+1; j<=measure_counter; j++)
{if(measure_data16[i]<measure_data16[j])
{ad_temp_word=measure_data16[i];
measure_data16[i]=measure_data16[j];
measure_data16[j]=ad_temp_word;
}
}
}
for(i=0;i<=9;i++) // 查找10个最小值排在后10位
{for(j=1; j<=(measure_counter-i); j++)
{if(measure_data16[measure_counter-i]>measure_data16[j])
{ad_temp_word=measure_data16[measure_counter-i];
measure_data16[measure_counter-i]=measure_data16[j];
measure_data16[j]=ad_temp_word;
}
}
}
ad_total=0; // 去除10个最大值和10个最小值后求和、取平均
for(j=11; j<=(measure_counter-10); j++)
{ad_total+=measure_data16[j];
}
ad_temp_word=(uint)(ad_total/(measure_counter-20));
return (ad_temp_word);
}
//----------------------------------------------------------------------------------------------
//----------------------BCD转换成十进制数
uchar change_bcd_hex(uchar shu)
{ uchar shu_h;
uchar shu_l;
shu_l=shu&0x0f;
shu_h=shu&0xf0;
shu_h=shu_h>>4;
return (shu_h*10+shu_l);
}
//----------------------------------------------------------------------------------------------
//----------------------十进制数转换成BCD
uchar change_hex_bcd(uchar shu)
{ uchar shu_h;
uchar shu_l;
shu_l=shu%10;
shu_h=shu/10;
return ((shu_h<<4)|shu_l);
}
//----------------------------------------------------------------------------------------------
//----------------------串口发射1字节
void sp_out(uchar shu)
{ SBUF0=shu;
while(TI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -