- /***********************************************
- File Name: S500.main
- Author:
- Date:230525
- Note:
- ************************************************/
- #include <STC8H.H>
- #include <intrins.h>
- #include <stdio.h>
- #include "common.h"
- #include "I2C.h"
- #include "OLED.h"
- #include "Display.h"
- #include "ScanKey.h"
- #include "Config.h"
- #include "NTC.c"
- #include "SPWM.h"
- #include "ADCaverage.h"
-
-
-
- //回读修正
- xdata float K_V = 8.338; //AD/显示
- xdata float K_I = 108.05; //AD/显示
- //基准输出比例
- xdata float K_V_REF = 13.087; //峰值电压基准/输出设定
- xdata float K_I_REF = 169.6; //峰值电流基准/输出设定
-
-
- //全局变量
- bit EN; //开关;0:关,1:开
- bit Start; //开关机状态
- bit Save; //保存
- xdata unsigned char StatusWord = 1; //0x00:待机;0x01:正常;0x11:故障;0x12输入欠压;0x13输入过压;0x14:过热;0x15:输出欠压;0x16:输出过压;0x17:过流
- xdata float Set_V = 0; //电压设置值
- xdata float Set_I = 0; //电流设置值
- xdata unsigned int Set_F = 0; //频率设置值
- unsigned int REF_V; //电压峰值基准
- unsigned int REF_I; //电流峰值基准
-
-
-
- xdata float Test_V = 0; //电压测量值
- xdata float Test_I = 0; //电流测量值
- xdata unsigned char Test_T = 0; //温度测量值
-
- unsigned int Sense_V, Sense_I, Sense_T, Sense_B, Sense_BUS; //AD采样值
-
- unsigned long SamplingV; //电压长采样值
- unsigned long SamplingI; //电流长采样值
- unsigned int SamplingCountV; //电压长采样计数
- unsigned int SamplingCountI; //电流长采样计数
- //bit SamplingNewV; //电压长采样更新
- //bit SamplingNewI; //电流长采样更新
- //bit ADC_Busy;
- xdata unsigned char inquireCount = 0; //查询定时
-
- bit IS_OK; //浪涌抑制完成
-
- //PWM部分
- bit PWM_EN; //PWM启动
- bit SoftStart = 1; //软启动标识,1:需要软启动;0:软启动完成
- unsigned char M; //调制
-
- //保护
- bit IN_O; //输入过压
- bit IN_U; //输入欠压
- bit OverV; //输出过压
- bit OverU; //输出欠压
- bit OverI; //输出过流
- bit OverC; //输出短路
- bit OverT; //过热
- xdata unsigned int OverTime; //过流事件|过流计时
- xdata unsigned int OverTimeMemory; //过流事件|过流计时
- xdata unsigned int OverRecover;
- bit ErrNew;
- bit busy;
-
- //显示部分
- xdata char Str_Set_V[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata char Str_Set_I[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata char Str_Set_F[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata char Str_V[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata char Str_I[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata char Str_F[6] = {'0', '0', '0', '0', '0', '\0'};
- xdata unsigned char Display_cls1 = 0, Display_cls2 = 0, Display_cls3 = 0;
- xdata unsigned char Display_clsrst = 0;
-
-
-
- void CLK_Init(void)
- {
- XOSCCR = 0xc8; //启动外部晶振
- while (!(XOSCCR & 1)); //等待时钟稳定
- CLKDIV = 0x00; //时钟不分频
- CLKSEL = 0x01; //选择外部高速晶振
- }
-
- void GPIO_Init(void)
- {
- P0M1 = 0xFD; P0M0 = 0x02; //P0(高高高高高高推高)
- P1M1 = 0xBF; P1M0 = 0x40; //P1(高推高高高高高高)
- P2M1 = 0x00; P2M0 = 0xF3; //P2(推推推推双双推推)
- P3M1 = 0xFD; P3M0 = 0x0E; //P3(高高高高开开推高)
- P4M1 = 0xEB; P4M0 = 0x14; //P4(高高高推高推高高)
- P5M1 = 0xFF; P5M0 = 0x00; //P5(高高高高高高高高)
-
- P01 = 1;
- P20 = 0;
- P21 = 0;
- P24 = 0;
- P25 = 0;
- P26 = 0;
- P27 = 0;
- P42 = 0;
- }
-
- void WDTInit(void)
- {
- WDT_CONTR |= 0x05; //配置看门狗定时器 1.26S@20M
- WDT_CONTR |= 0x10;
- WDT_CONTR |= 0x20;
- }
-
- void Timer1Init(void) //5毫秒@30.000MHz
- {
- AUXR &= 0xBF; //定时器时钟12T模式
- TMOD &= 0x0F; //设置定时器模式
- TL1 = 0x2C; //设置定时初始值
- TH1 = 0xCF; //设置定时初始值
- TF1 = 0; //清除TF1标志
- ET1 = 1; //允许中断
- TR1 = 0; //定时器1开始计时
- }
-
-
- void Config()
- {
- REF_V = (unsigned int)(Set_V * K_V_REF);
- REF_I = (unsigned int)(Set_I * K_I_REF);
- PWMA_ARR = MainClock/Element/Set_F+0.5;
- MiddleValue = (PWMA_ARR/2)+0.5;
- }
-
- void Change()
- {
- xdata unsigned char str[7];
- if(Direction != 0)
- {
- if(CursorPosition == 0)
- {
- if(Direction == 1)
- {
- if(Set_V <= S_O_V_H - 0.1) Set_V +=0.1;
- }
- if(Direction == 2)
- {
- if(Set_V >= S_O_V_L + 0.1) Set_V -=0.1;
- }
- if(Direction == 10)
- {
- if(Set_V <= S_O_V_H - 1) Set_V +=1;
- }
- if(Direction == 20)
- {
- if(Set_V >= S_O_V_L + 1) Set_V -=1;
- }
- REF_V = (unsigned int)(Set_V * K_V_REF);
- sprintf(str, "%5.1f", Set_V);
- //str[5] = '\0';
- Display_cls1 = 1;
- Display_cls2 = 0;
- Display_cls3 = 0;
- OLED_P6x8Str_R(68,5,str);
- }
- if(CursorPosition == 1)
- {
- if(Direction == 1)
- {
- if(Set_I <= S_O_I_H - 0.1) Set_I +=0.1;
- }
- if(Direction == 2)
- {
- if(Set_I >= S_O_I_L + 0.1) Set_I -=0.1;
- }
- if(Direction == 10)
- {
- if(Set_I <= S_O_I_H - 1) Set_I +=1;
- }
- if(Direction == 20)
- {
- if(Set_I >= S_O_I_L + 1) Set_I -=1;
- }
- sprintf(str, "%5.2f", Set_I);
- REF_I = (unsigned int)(Set_I * K_I_REF);
- //str[5] = '\0';
- Display_cls1 = 0;
- Display_cls2 = 1;
- Display_cls3 = 0;
- OLED_P6x8Str_R(68,6,str);
- }
- if(CursorPosition == 2)
- {
- if(Direction == 1)
- {
- if(Set_F <= S_O_F_H - 1) Set_F +=1;
- }
- if(Direction == 2)
- {
- if(Set_F >= S_O_F_L + 1) Set_F -=1;
- }
- if(Direction == 10)
- {
- if(Set_F <= S_O_F_H - 10) Set_F +=10;
- }
- if(Direction == 20)
- {
- if(Set_F >= S_O_F_L + 10) Set_F -=10;
- }
- PWMA_ARR = MainClock/Element/Set_F+0.5;
- MiddleValue = (PWMA_ARR/2)+0.5;
- str[0] = Set_F/100+48;
- str[1] = Set_F/10%10+48;
- str[2] = Set_F%10+48;
- str[3] = '\0';
- Display_cls1 = 0;
- Display_cls2 = 0;
- Display_cls3 = 1;
- OLED_P6x8Str_R(80,7,str);
- }
- Direction = 0;
- }
- }
-
- //刷新
- void Display_Refresh()
- {
- xdata unsigned char i;
- xdata unsigned char str[7];
-
- ET0 = 0;
-
- //Change();
- if(Refresh_Count > 250)
- {
- Refresh_Count = 0;
- if((Display_cls1 == 1) || (Display_cls2 == 1) || (Display_cls3 == 1))
- {
- if(Direction == 0) Display_clsrst++;
- if(Display_clsrst > 10)
- {
- Display_cls1 = 0;
- Display_cls2 = 0;
- Display_cls3 = 0;
- Display_clsrst = 0;
- //save
- }
- }
-
- sprintf(str, "%5.1f", Test_V);
- for(i=0; i<6; i++)
- {
- Str_V[i] = str[i];
- }
-
- sprintf(str, "%5.2f", Test_I);
- for(i=0; i<6; i++)
- {
- Str_I[i] = str[i];
- }
-
- if(StatusWord == 0x01)
- {
- Str_F[0] = Set_F/100+48;
- Str_F[1] = Set_F/10%10+48;
- Str_F[2] = Set_F%10+48;
- Str_F[3] = '\0';
- }
- else
- {
- Str_F[0] = '0';
- Str_F[1] = '0';
- Str_F[2] = '0';
- Str_F[3] = '\0';
- }
-
- Display_Cursor(CursorPosition); //更新光标位置
- Display_Fill1(StatusWord);
- if(Display_cls1 == 0) Display_Fill(4, Str_V);
- if(Display_cls2 == 0) Display_Fill(5, Str_I);
- if(Display_cls3 == 0) Display_Fill(6, Str_F);
-
-
- //OLED_Display_16bit_number(68,3,Test_T-40); //test
- OLED_Display_16bit_number(68,3,PWMA_ARR); //test
- }
- ET0 = 1;
- }
-
- void ONOFF()
- {
- //开机过程
- if((EN) && (IS_OK)) //开机
- {
- Start = 1;
- }
- else
- {
- Start = 0;
- }
-
- if(Start)
- {
- PWM_EN = 1;
- }
- else
- {
- M = 0;
- PWM_EN = 0;
- SoftStart = 1;
- }
-
- if((PWM_EN == 1) && (SoftStart == 1)) //软启动
- {
- TR1 = 1; //定时器1计时控制
- }
- }
-
-
-
- //定时器1中断
- void timer1_isr() interrupt 3 //软起动&保护
- {
-
- //软启动
- if((PWM_EN == 1) && (SoftStart == 1))
- {
- M++;
- if(M >= Level-20)
- {
- SoftStart = 0;
- }
-
- //Sense_V = Absolute(Get_ADC(0x01), Get_ADC(0x00));
- if(Sense_V >= REF_V - 50)
- {
- SoftStart = 0;
- }
- }
-
- //温度查询
- inquireCount++;
- if(inquireCount > 100)
- {
- xdata unsigned char i;
- inquireCount = 0;
- Sense_T = ADCaverage(0x02);
- if(Sense_T < 6)
- {
- Test_T = 254;
- }
-
- if(Sense_T > 3104)
- {
- Test_T = 255;
- }
-
- for(i=0;i<160;i++)
- {
- if(NTCV[i] >= Sense_T)
- {
- Test_T = i;
- break;
- }
- }
- }
- }
-
- unsigned int Absolute(unsigned int a, unsigned int b)
- {
- unsigned int c;
- if(a >= b)
- {
- c = a - b;
- }
- else
- {
- c = b - a;
- }
- return (c);
- }
-
- void inquire()
- {
- Sense_B = ADCaverage(0x0c);
- Sense_BUS = ADCaverage(0x0b);
- }
-
- void Sampling() //20uS
- {
-
- }
- void status()
- {
- //bit IN_O; //输入过压
- //bit IN_U; //输入欠压
- //bit OverV; //输出过压
- //bit OverU; //输出欠压
- //bit OverI; //输出过流
- //bit OverC; //输出短路
- //bit OverT; //过热
- }
-
- void PID() //12bit:23uS/45uS
- {
- unsigned char Factor = 15; //比例系数
- unsigned int Diffe; //差值
- bit Direction; //差值方向
- unsigned int P; //增量
-
- if(SinPeak)
- {
- SinPeak = 0;
- Sense_V = Absolute(Get_ADC1(0x01), Get_ADC1(0x00));
-
- if(Sense_V >= REF_V)
- {
- Diffe = Sense_V - REF_V;
- Direction = 1;
- SoftStart = 0;
- }
- else
- {
- Diffe = REF_V - Sense_V;
- Direction = 0;
- }
-
- P = Diffe / Factor; //P
-
- if(!SoftStart)
- {
- if(Direction)
- {
- M = M - P;
- }
- else
- {
- M = M + P;
- }
- }
-
- //
- if(M <= 0)
- {
- M = 0;
- }
- if(M >= Level)
- {
- M = Level - 1;
- }
-
- //电压长采样
- SamplingV += Sense_V;
- SamplingCountV++;
- if(SamplingCountV >= (Element - 1))
- {
- Test_V = (float)(SamplingV / SamplingCountV) / K_V;
- SamplingV = 0;
- SamplingCountV = 0;
-
- //SamplingNewV = 1;
- }
- //电流长采样
- Sense_I = Absolute(Get_ADC1(0x0e), Get_ADC1(0x0d));
- SamplingI += Sense_I;
- SamplingCountI++;
- if(SamplingCountI >= (Element - 1))
- {
- Test_I = (SamplingI / SamplingCountI) / K_I;
- SamplingI = 0;
- SamplingCountI = 0;
-
- //SamplingNewV = 1;
- }
-
- }
-
- }
-
- void ADC_Isr() interrupt 5
- {
-
- ADC_CONTR &= ~0x20; //清中断标志
- EA = 1;
- TR0 = 1; //定时器0开始计时
- EADC = 0; //使能ADC中断
- PID();
- }
-
- void main()
- {
- P_SW2 |= 0x80; //使能访问 XFR
- CLK_Init();
- GPIO_Init();
- ADCInit();
- ConfigRead();
- PWM_Init();
- Config();
- I2C_Init();
- OLED_Init();
- //Display_Start();
- Display_Frame();
- Timer0Init();
- Timer1Init();
-
- //OLED_Display_16bit_number(68,3,REF_I);
- EN = 1;
- IS_OK = 1;
- M = 98;
- ///////////////////////
-
-
- IP = 0x10;
- IPH = 0x20;
- IP2 = 0x04;
- IP2H = 0x04;
- EA = 1;
- Change();
- while(1)
- {
- Change();
- ONOFF();
- Display_Refresh();
-
-
-
-
- if(Save == 1)
- {
- Save = 0;
- OLED_P8x16Str(68,3,"Save...");
- ConfigWrite();
- OLED_P8x16Str(68,3," ");
- }
-
- //P26 = TR0;
-
- ///////////////////////////////////////////////////////
- WDT_CONTR |= 0x10;
- }
-
- }
复制代码
|