//*****************矩形波100KHZ,占空比可调**********************// 改成低电平导通,占空比num1=num0,为导通比,即值越大,导通率越大
#include <STC12C5410AD.h> //晶振 11.0592Mhz MAX:542.53KHZ
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit beep=P2^5;
uchar cc=0; //测试电池类别
uchar stop=0;
/***************类别*****************/
float start_voltage,last_voltage;
uchar start_current,middle_current,last_current;
uchar code qishi_li1[]={"锂 3.7V*1 charge"};
uchar code qishi_nie1[]={"镍 1.2V*1 charge"};
uchar code qishi_nie2[]={"镍 1.2V*2 charge"};
/****************PWM*******************/
sbit led1=P2^4;
sbit P2_6=P3^2; // ++ 占空比加减按键
sbit P2_7=P3^3; // --
uchar ii=0;
uchar all=250; //总时长,一个周期步数 //60KHZ
uchar num0=10; //占空步数
uchar num1=10; //加减步数 //有个初始电压在,开始时,电流...
/******************灯与光敏电阻检测**************************/
sbit lig0=P2^3; // 0123灯低电平导通,大于某个值时,动作
sbit lig1=P2^2;
sbit lig2=P2^1;
sbit lig3=P2^0;
float light[4]; //0123代表灯号(光敏电阻检测数值)
float test_A; //电流检测存储
float test_V; //电压检测存储
/*****************AD相关************************/
uchar buf[9]=" 1234567"; //有八位,排序: _*.***V_ //存储转换后的十进制数
float consult; //参考电压设置
float Val_Av2=0; //是AD转换暂存值
float test_V,test_A;
uchar tab;
/********************延时1mS*********************/
void delayms(uchar bb)
{
uint jj;
for(;bb>0;bb--)
for(jj=0;jj<280;jj++);
}
/****************初始化***************************/
void init_timer()
{
//num0=16; //执行num步时,中断
TMOD|=0x01; //GATE C/~T M1 M0 13 16 8 //两个八位重装
TH0=255; //赋初值
TL0=254; //有个初值,为低1,高all-num0 + 低电平导通,ok //解决开始电流大的问题
led1=0;
EA=1; //开总中断
ET0=1; //开两个中断
TR0=1; //开两个定时器
}
void init_scon()
{
TMOD|=0X20; //定时器1,八位重装
TH1=0XFA; //对于晶振11.0592MHZ 256-2*11.0592M/(12*32*9600) //9600波特率
TL1=0XFA;
PCON|=0X80; //SMOD=1 波特率加倍
SCON|=0X40; //方式寄存器 方式2
REN=1; //允许接收
ES=1; //串行口允许中断
TR1=1; //开中断定时器1
}
/*********************按键加减******************************/
void keyboard()
{
uchar aa;
EA=0;
aa=P2_6;
if(aa==0)
{
delayms(10);
aa=P2_6;
if(aa==0)
{
num1++;
led1=0; //下一个周期为正
if(num1>=all)
{
num1=all;
ET0=0; //关定时器0
led1=0;
}
else ET0=1;
}
while(aa==0)
{
aa=P2_6;
}
num0=num1;
SBUF=num0;
delayms(100);
}
aa=P2_7;
if(aa==0)
{
delayms(10);
aa=P2_7;
if(aa==0)
{
num1--;
led1=0;
if(num1<=0)
{
num1=1; // 要等于1,不然下次再减一,就变为255了,因为num1为char型
ET0=0;
led1=1; //占空比为零
}
else ET0=1;
}
while(aa==0)
{
aa=P2_7;
}
num0=num1;
SBUF=num0;
delayms(100);
}
EA=1;
}
/***********************12864显示******************************/
/******************液晶显示***************************/
sbit CS=P3^7;//sbit CS=P2^1;
sbit SID=P2^7;//sbit SID=P2^0;
sbit SCLK=P2^6;//sbit SCLK=P1^7;
//PSB接低电平,串口模式 //
uchar code start[]={"Sunshine regular"}; //
uchar code diskey[]={"0123456789ABCDEF "}; //
uchar code nowvol[]={"Voltage: . V"}; // 15个数
uchar code nowcur[]={"Current: . A"};
void delay_1ms(uint x)
{
uint i,j;
for(j=0;j<x;j++)
for(i=0;i<110;i++);
}
/*************************写命令**********************************/
void send_command(uchar command_data)
{
uchar i;
uchar i_data;
i_data=0xf8; // 1111 1000 -写指令
CS=1;
SCLK=0;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80); //一位一位地传送
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data&=0xf0; // 1111 0000 写前四个数据
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data<<=4; // 写后四位数据
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
CS=0;
delay_1ms(1);
}
/************************写数据*********************************/
void send_data(uchar command_data)
{
uchar i;
uchar i_data;
i_data=0xfa; //写数据 1111 1010
CS=1;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data&=0xf0; //写前四位数据 **** 0000
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data<<=4; //写后四位数据
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
CS=0;
delay_1ms(1);
}
/*************************LCD初始化设置***********************************/
void lcd_init()
{
delay_1ms(100);
send_command(0x30);//设置8位数据接口,基本指令模式
send_command(0x02);//清DDRAM
send_command(0x06);//游标及显示右移一位
send_command(0x0e);//整体显示开,游标开,反白关
send_command(0x01);//写入空格清屏幕
}
/****************************坐标 设定显示位置************************************/
void lcd_pos(uchar X,uchar Y) // 汉字显示坐标 第一行80H-87H 第二行为90H-97H 第三行88H-8FH 第四行98H-9FH
{
uchar pos;
if(X==0)
{X=0X80;}
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0X88;}
else if(X==3)
{X=0x98;}
pos=X+Y;
send_command(pos); //显示地址
}
/*****************************************************/
void init_12864() //显示开始坐标与终止坐标
{
uchar i;
lcd_pos(0,0);
for(i=0;i<16;i++) //
{
send_data(start[i]); //光标开始的位置
}
lcd_pos(1,0);
for(i=0;i<16;i++) //
{
send_data(nowvol[i]); //光标开始的位置
}
lcd_pos(2,0);
for(i=0;i<16;i++) //
{
send_data(nowcur[i]); //光标开始的位置
}
}
/*****************************************************/
void AD_init()
{
P1M0|=0xff; //P口 作A/D转换
P1M1|=0xff; //
ADC_CONTR=0XE0;// 开A/D电源,速度最快
delayms(100);
}
/***************************************/
uint GetAD(uchar channel) // 0-7通道
{
uchar AD_finished=0;
uint result=0;
ADC_CONTR=0;//ADC_CONTR=1; // 这不是启动了吗????????????????
ADC_CONTR|=channel; //通道选择 | //这个要为& 不然,P1.0没效 ,还不行,这样P1.1没效 ,在前加=1 =1不就启动了吗
ADC_CONTR|=0xe8; //启动A/D转换
while(AD_finished==0) //判断FLAG位是否等于1
{
AD_finished=(ADC_CONTR&0X10); //ADC_FLAG 模转换结束标志,A/D转换完成后,=1,必须由软件清0
}
result=ADC_DATA*4+ADC_LOW2;
ADC_CONTR&=0Xe7; //清除转换标志ADC_FLAG,控制位ADC_START=0 //是这里
return(result);
}
float Ad_Av(uchar channel) // 执行这里时,要求ADC_START=1 //100次启动AD,求各,取平均值
{
uchar num; //100,小了一点,电压不稳
float Val_Av=0;
for(num=100;num>0;num--) //100次,取平均值
{
Val_Av+=GetAD(channel);
}
Val_Av/=100.0; //
Val_Av=Val_Av*consult/1024; // consult 为参考电压
Val_Av2=Val_Av;
return(Val_Av);
}
void transfer_char(float fudian)//float转成十进制 //有八位,格式: _*.***V_ 只取前四位 //读数后的转换,下一步,发送显示
{
uchar ge,shifen,baifen,qianfen,wanfen,shiwanfen,baiwanfen,qianwanfen;
unsigned long int mon; //兼顾两个显示
mon=fudian*10000000; //这里不要加0x30
ge=mon/10000000+0x30;
shifen=mon%10000000/1000000+0x30;
baifen=mon%1000000/100000+0x30;
qianfen=mon%100000/10000+0x30;
wanfen=mon%10000/1000+0x30;
shiwanfen=mon%1000/100+0x30;
baiwanfen=mon%100/10+0X30;
qianwanfen=mon%10+0X30;
buf[1]=ge;buf[3]=shifen;buf[4]=baifen;buf[5]=qianfen;//buf[4]=wanfen;buf[5]=shiwanfen;
}
/************************LCD显示函数********************************/
void Lcd_Uartdisplay()
{
uchar