|
发表于 2023-5-17 10:57:44
|
显示全部楼层
#include "STC8G.h"
#include "intrins.h"
#include "stdio.h"
#include "tm1640.h"
#define FOSC 11059200L //11059200L //System frequency
#define BAUD 9600 //UART baudrate
/*Define UART parity mode*/
#define NONE_PARITY 0 //None parity
#define ODD_PARITY 1 //Odd parity
#define EVEN_PARITY 2 //Even parity
#define MARK_PARITY 3 //Mark parity
#define SPACE_PARITY 4 //Space parity
#define PARITYBIT EVEN_PARITY //Testing even parity
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x20 //ADC complete flag
#define ADC_START 0x40 //ADC start control bit
//#define ADC_SPEEDLL 0x00 //420 clocks
//#define ADC_SPEEDL 0x02 //280 clocks
//#define ADC_SPEEDH 0x04 //140 clocks
//#define ADC_SPEEDHH 0x06 //70 clocks
//typedef unsigned char uchar;
//typedef unsigned int uint;
#define uchar unsigned char //方便书写
#define uint unsigned int
int ADC_LOW2;
int val;
int val1;
uchar ADC_JS;
uchar ch = 0; //ADC channel NO.
uchar time1 = 0; //ADC中断计时器
int *BGV; //内部1.19V参考电压值
char AA=123;
bit busy;
bit ADC_O;
bit play;
uchar buf[30];
char temp[20]="电压:";
uchar TempData[8]; //存储显示值的全局变量
sbit RELAY = P3^7; //定义继电器位置
bit KeySensor = 0; //扫描标志
sbit rst_k1 = P1^2; //设置按钮
bit rst_k1State = 0; //设置
bit rst_k1Last = 0; //设置历史
bit rst_k1_b = 0; //设置标志
sbit rst_k2 = P1^3; //加一按钮
bit rst_k2State = 0; //加一
bit rst_k2Last = 0; //加一历史
bit rst_k2_b = 0; //加一标志
sbit rst_k3 = P1^4; //减一按钮
bit rst_k3State = 0; //减一
bit rst_k3Last = 0; //减一历史
bit rst_k3_b = 0; //减一标志
sbit rst_k4 = P1^5; //确认按钮
bit rst_k4State = 0; //确认
bit rst_k4Last = 0; //确认历史
bit rst_k4_b = 0; //确认标志
uint KeyCounter; //长按计时
bit chansu_SYS ; //参数设置标志
uchar chansu_b = 0; //参数设置标号
uchar V_L; //低压设置值
uchar V_H; //高压设置值
uint wengding; //稳定延时设置值
#define sysset 4 //系统参数2总数
uchar MemorySys[sysset]; //系统参数
/*----------------------------
eeprom关闭
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*----------------------------
eeprom读取
----------------------------*/
char IapRead(int addr)
{
char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
//读取Eeprom中的运行参数数据,以便程序调用
void EepromRead(unsigned int Eeprom_Address, unsigned char MaxPara, uchar *P)
{
unsigned char i;
// DelayMS(5);
for( i=0; i<MaxPara; i++ )
{
// *P =(unsigned int)(IapRead(Eeprom_Address+i*2))*0xFF+IapRead(Eeprom_Address+1+i*2); //读Eeprom的值,存到read_Eeprom
*P =IapRead(Eeprom_Address+i) ;
P++;
}
}
/*----------------------------
eeprom写入
----------------------------*/
void IapProgram(int addr, char dat)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
//存储系统参数,以便将来应用
void EepromSave(unsigned int Eeprom_Address, unsigned char MaxPara, uchar *P)
{
unsigned char i;
// DelayMS(10);
// Sector_Erase(Eeprom_Address); //擦除扇区 这次把擦除扇区写在程序外面,可以先全部擦除再写入
for( i=0; i<MaxPara; i++ )
{
// IapProgram(Eeprom_Address+i*2,(unsigned char)( *P /0xFF));
// IapProgram(Eeprom_Address+i*2+1,(unsigned char)( *P %0xFF));
IapProgram(Eeprom_Address+i,*P);
P++;
}
}
/*----------------------------
eeprom擦除
----------------------------*/
void IapErase(int addr)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
/*----------------------------
发送一个字符
----------------------------*/
void SendData(uchar dat)
{
while (busy); //Wait for the completion of the previous data is sent
ACC = dat; //Calculate the even parity bit P (PSW.0)
if (P) //Set the parity bit according to P
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //Set parity bit to 0
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 1; //Set parity bit to 1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 1; //Set parity bit to 1
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 0; //Set parity bit to 0
#endif
}
busy = 1;
SBUF = ACC; //Send data to UART buffer
}
/*发送字符串*/
void send_string(char *s)
{
while (*s) //Check the end of the string
{
SendData(*s++); //Send current char and increment string ptr
}
}
void delayms(uint MS) //
{
uchar a;
uint b;
for(b=MS;b>0;b--)
for(a=113;a>0;a--);
}
/*****将数字转化为字符,发送到串口*****/
void NumToStr(uint Data, unsigned char Num)
{
uchar i;
for( i=5+Num; i>5; i--)
{
temp[i] = Data%10 + 0x30;
Data = Data / 10;
}
}
/*****将数字拆分,以便显示*****/
void NumToStr1(uint Data, unsigned char Num)
{
uchar i;
for( i=Num; i>0; i--)
{
data1[i] = Data%10;
Data = Data / 10;
}
}
void KeySensor0(void) //设置按钮
{
bit KeyTem;
KeyTem = rst_k1;
if( KeyTem == rst_k1Last )
{
if(KeyTem == 1)
{
KeyCounter = 0;
rst_k1_b=0;
}
if(KeyTem == 0)
{
KeyCounter++; //长按进入参数查看状态
if(KeyCounter>2000 )
{
chansu_SYS = 1; //参数设置标志
chansu_b = 1; //参数号
}
if(KeyCounter<2000 && chansu_SYS == 1 && rst_k1_b==0)
{
chansu_b ++;
rst_k1_b=1;
if(chansu_b>4)
{
chansu_b = 1;
}
}
}
}
rst_k1Last = KeyTem;
}
void KeySensor1(void) //加一按钮
{
bit KeyTem;
KeyTem = rst_k2;
if( KeyTem == rst_k2Last )
{
if(KeyTem == 0 && chansu_SYS == 1 && rst_k2_b==0)
{
rst_k2_b=1;
if(chansu_b == 1)
{
MemorySys[0]++;
if(MemorySys[0]>150)
{
MemorySys[0]=150 ;
}
}
if(chansu_b == 2)
{
MemorySys[1]++;
if(MemorySys[1]>220)
{
MemorySys[1] =220;
}
}
if(chansu_b == 3)
{
MemorySys[2]++;
if(MemorySys[2]>100)
{
MemorySys[2]=100 ;
}
}
}
else if(KeyTem == 1)
{
rst_k2_b=0;
}
}
rst_k2Last = KeyTem;
}
void KeySensor2(void) //减一按钮
{
bit KeyTem;
KeyTem = rst_k3;
if( KeyTem == rst_k3Last )
{
if(KeyTem == 0 && chansu_SYS == 1 && rst_k3_b==0)
{
rst_k3_b=1;
if(chansu_b == 1)
{
MemorySys[0]--;
if(MemorySys[0]<50)
{
MemorySys[0]=50 ;
}
}
if(chansu_b == 2)
{
MemorySys[1]--;
if(MemorySys[1]<150)
{
MemorySys[1]=150 ;
}
}
if(chansu_b == 3)
{
MemorySys[2]--;
if(MemorySys[2]<10)
{
MemorySys[2]=10 ;
}
}
}
else if(KeyTem == 1)
{
rst_k3_b=0;
}
}
rst_k3Last = KeyTem;
}
void KeySensor3(void) //确认按钮
{
bit KeyTem;
KeyTem = rst_k4;
if( KeyTem == rst_k4Last )
{
if(KeyTem == 0 && chansu_SYS == 1 && rst_k4_b==0)
{
rst_k4_b=1;
if(chansu_b < 4)
{
chansu_b ++;
}
else
{
chansu_SYS = 0;
IapErase(0x0000); //擦除第一扇区
EepromSave(0x0000, sysset, MemorySys); //保存系统参数
}
}
else if(KeyTem == 1)
{
rst_k4_b=0;
}
}
rst_k4Last = KeyTem;
}
/*----------------------------
按键扫描
----------------------------*/
void KeyScan(void)
{
KeySensor0(); //
KeySensor1();
KeySensor2();
KeySensor3();
play=1;
// KeySensor4();
}
/*----------------------------
ADC初始化
----------------------------*/
void InitADC()
{
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置ADC内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x0f; //设置ADC时钟为系统时钟/2/16 | ADC_SPEEDLL
// ADC_CONTR = 0x80; //使能ADC模块
ADC_RES = 0; //清ADC转化结果
ADC_CONTR = ADC_POWER; // 使能ADC电源
delayms(2); //ADC power-on delay and Start A/D conversion
}
/*----------------------------
初始化Uart通讯
----------------------------*/
void InitUart()
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD = 0x00; //定时器0模式0 定时器1为波特率发生器
TMOD &= 0x0F; //清除T1的控制位
TMOD |= 0x20; //T1的工作模式2
// TH1 = TL1 = -(FOSC/12/32/BAUD); //12T 8位自动重装载
TH1 = TL1 = -(FOSC/32/BAUD); //1T 8位自动重装载
// TL1 = 0xDC; //设置定时初始值
// TH1 = 0xDC; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
//定时器0设置
TL0 = 0x00; //定时器0 12T 65536-11.0592M/12/100
TH0 = 0xDC;
TR0 = 1; //启动定时器0
ET0 = 1; //使能定时器中断
EADC = 1; //ADC中断允许位
ES = 1; //Enable UART interrupt
EA = 1; //Open master interrupt switch
EA = 1;
}
void IniCPU(void)
{
P0M0 = 0x00;
P0M1 = 0x03; //设置P1.1为ADC口
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
InitUart();
RELAY = 1;
}
/*******************************************************************************
* 文件名:void VoltageCheckRefresh()
* 描 述: 电压检测
* 功 能:
* 作 者:
* 版本号:
*******************************************************************************/
void VoltageCheckRefresh()
{
//val = (int)((1024-ADC_LOW2+80)* 6 / 22); // (long)((ADC_LOW2) * 5*380/36 / 1024);
val = 230-val1/4; //
//val = val1; //
if(val<0)
{
val = 0;
}
//val = (int)(1024L*191/ADC_LOW2); //*BGV
}
void main()
{
IniCPU();
BGV=(int idata *)0xef; //参考电压寄存器
EepromRead(0x0000, sysset, MemorySys); //读取系统参数
// send_string("HLW8032 Text!\r\n");
// P0=0x0F;
data1[0]=0;
data1[1]=1;
data1[2]=2;
data1[3]=3;
ADC_JS=0;
ADC_O=0;
InitADC(); //Init ADC sfr
ADC_CONTR = ADC_POWER | ADC_START | ch; //启动AD转换
ch = 1;
val1=0;
RELAY= 1;
while(1)
{
uint wd;
if(play==1)
{
if(chansu_SYS == 0)
{
NumToStr1(val, 3);
data1[0] = 16;
tm1640send();
}
if(chansu_SYS == 1)
{
if(chansu_b == 1)
{
NumToStr1(MemorySys[0], 3);
data1[0] = 1;
tm1640send();
}
if(chansu_b == 2)
{
NumToStr1(MemorySys[1], 3);
data1[0] = 2;
tm1640send();
}
if(chansu_b == 3)
{
NumToStr1(MemorySys[2], 3);
data1[0] = 3;
tm1640send();
}
}
play=0;
}
if( KeySensor != 0 ) //按键扫描
{
KeyScan();
}
if(ADC_O==1)
{
if(ADC_JS>10)
{
val1=val1/(ADC_JS-1);
VoltageCheckRefresh(); //计算电压值
play=1;
NumToStr(val, 5);
send_string(temp);
if(val<MemorySys[0]) //掉电检测
{
RELAY= 1;
wd=0;
}
if(val>MemorySys[1]) //来电检测
{
// if(RELAY== 1)
// {
//wd++;
//if((wengding*10)<wd)
//{
RELAY= 0;
wd=0;
//}
// }
}
val1=0;
ADC_JS = 0;
}
else
{
val1=ADC_LOW2+val1;
}
ADC_O=0;
}
if(time1>=1) //ADC转换,10ms一次
{
ADC_RES = 0; //清ADC转化结果
ADC_CONTR = ADC_POWER | ADC_START | ch;
time1 = 0;
}
}
}
/*----------------------------
ADC 中断处理
----------------------------*/
void adc_isr() interrupt 5
{
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_LOW2= ADC_RES;
ADC_LOW2 <<= 2;
ADC_LOW2 |= ADC_RESL;
ADC_JS++;
ADC_O=1;
// if (++ch > 7) ch = 0; //switch to next channel
ADC_CONTR = ADC_POWER | ch;
}
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x20 //ADC complete flag
#define ADC_START 0x40 //ADC start control bit
/*----------------------------
定时器0 中断处理
----------------------------*/
void TM0_10ms() interrupt 1
{
time1++;
KeySensor = 1;
}
/*串口中断处理函数*/
void Uart_Isr() interrupt 4
{
if(RI)
{
RI = 0;
}
if (TI)
{
TI = 0; //Clear transmit interrupt flag
busy = 0; //Clear transmit busy flag
}
}
完整的程序 |
|