******************************************************************//
#include // 20M
#include "math.h"
#include "absacc.h"
#define inv_flag ET1 //T1中断开关,用作逆变信号点//
#define overload 380 //过载封锁值//
#define overload_L 320 //过载报警值//
#define batlow 615
#define batlow_L 650
sbit led=P2^7;
sbit sce=P3^4; //片选
sbit res=P2^1; //复位,0复位
sbit dc=P1^6; //1写数据,0写指令
sbit sdin=P1^5; //数据
sbit sclk=P1^7; //时钟
bit batlow_flag;
unsigned int m,pwm_1,pwm_2;
unsigned char k=0,i,j,pwm1,pwm2;
unsigned char code pwm[31]={13,39,64,89,112,135,156,176,193,209,
223,234,243,249,254,255,254,249,243,234,
223,209,193,176,156,135,112,89,64,39,13};
void delay(unsigned int time)
{
unsigned int a=0,b;
for(a=0;a
for(b=0;b<1200;b++);
}
void delayus()
{unsigned char k;
for(k=0;k<120;k++);
}
void LCD_init(void);
void LCD_clear(void);
void LCD_write_byte(unsigned char dt,unsigned char command);
void display(unsigned char t,unsigned char y);
unsigned int bat=660,out=640,load=325;
unsigned char code han[]={
//输--0
0x44,0xF4,0x4F,0xE4,0x44,0x64,0x90,0x98,0x94,0x93,0x14,0x98,0x08,0xD0,0x10,0x00,0x04,0x04,0x04,0xFF,0x02,0x02,0xFF,0x4A,0x8A,0x7F,0x00,0x3F,0x80,0xFF,0x00,0x00,
//出--1
0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0xFC,0x00,0x00,0x00,0x00,0x7E,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x7E,0x00,0x00,
//入--2
0x00,0x00,0x00,0x00,0x01,0x83,0x76,0x18,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x06,0x01,0x00,0x00,0x00,0x00,0x03,0x04,0x18,0x30,0x10,0x00,
//电--3
0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0x3F,0x44,0x44,0x44,0x44,0x4F,0x40,0x70,0x00,
//压--4
0x00,0x00,0xFE,0x02,0x42,0x42,0x42,0x42,0xFA,0x42,0x42,0x42,0x62,0x42,0x02,0x00,0x20,0x18,0x27,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x21,0x2E,0x24,0x20,0x20,0x00,
//池--5
0x10,0x60,0x02,0x8C,0x60,0x80,0xF8,0x40,0x40,0xFE,0x20,0x20,0x10,0xF0,0x00,0x00,0x08,0x08,0x7C,0x03,0x00,0x00,0x3F,0x40,0x40,0x5F,0x40,0x42,0x44,0x43,0x70,0x00,
//负--6
0x00,0x20,0x10,0xF8,0x14,0x13,0x12,0x92,0x12,0x1A,0x16,0xF0,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x4F,0x40,0x20,0x18,0x07,0x08,0x10,0x20,0xEF,0x40,0x00,0x00,0x00,
//载--7
0x10,0x50,0x54,0xD4,0x74,0x5F,0x54,0x54,0x10,0xFF,0x10,0x12,0x14,0xD0,0x10,0x00,0x00,0x12,0x13,0x12,0x12,0xFF,0x0A,0x4A,0x20,0x10,0x0F,0x1C,0x23,0x40,0x30,0x00,
//充--8
0x00,0x04,0x84,0xC4,0xA4,0xB4,0x9D,0x96,0x84,0x94,0xA4,0xC4,0x84,0x04,0x00,0x00,0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x3F,0x40,0x40,0x41,0x40,0x70,0x00,0x00,
};
unsigned char code shuzi[]={
/*-- 文字: 0 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, //0
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, //1
/*-- 文字: 2 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, //2
/*-- 文字: 3 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, //3
/*-- 文字: 4 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, //4
/*-- 文字: 5 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, //5
/*-- 文字: 6 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, //6
/*-- 文字: 7 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, //7
/*-- 文字: 8 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, //8
/*-- 文字: 9 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, //9
/*-- 文字: : --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00 //10
};
//---------------------------------------
//-----------------------------------------
void LCD_init(void)
{
LCD_write_byte(0x21,0);//LCD功能设置:芯片活动,水平寻址,使用扩展指令
LCD_write_byte(0xaa,0);//设置VOP值
LCD_write_byte(0x20,0);//LCD功能设置:芯片活动,水平寻址,使用基本指令
LCD_write_byte(0x0C,0);//设定显示配置:普通模式
}
//---------------------------------------
void LCD_clear(void)
{
unsigned char t;
unsigned char k;
for(t=0;t<6;t++)
{
for(k=0;k<84;k++)
{
LCD_write_byte(0,1);
}
}
}
void LCD_set_XY(unsigned char X, unsigned char Y)
{
LCD_write_byte(0x40 | Y, 0);
LCD_write_byte(0x80 | X, 0);
}
//---------------------------------------
void init_spi()
{
P1M0=0X00;
P1M1=0XA0;
SPCTL=0XD0;
SPSTAT=0XC0;
}
//---------------------------------------
//-----------------------------------------
void LCD_write_byte(unsigned char dt, unsigned char command)
{
sce=0;
dc=command;
SPDAT=dt;
while(!(SPSTAT&0X80));
SPSTAT=0XC0;
dc=1;
sce=1;
sdin=1;
}
//---------------------------------------
//-----------------------------------------
void disp16_16(unsigned char x,unsigned char y,unsigned char address)
{
unsigned char c;
LCD_set_XY(x*8, y);
for(c=0;c<16;c++)
{
LCD_write_byte(han[address*32+c],1);
}
LCD_set_XY(x*8, y+1);
for(c=16;c<32;c++)
{
LCD_write_byte(han[address*32+c],1);
}
}
//---------------------------------------
//-----------------------------------------
void disp8_16(unsigned char x,unsigned char y,unsigned char c)
{
unsigned char i;
LCD_set_XY(x*8, y);
for(i=0; i<8;i++)
{
LCD_write_byte(shuzi[c*16+i],1);
}
LCD_set_XY(x*8, y+1);
for(i=8; i<16;i++)
{
LCD_write_byte(shuzi[c*16+i],1);
}
}
//---------------------------------------
void delay1ms()
{
unsigned int k;
for(k=0;k<12000;k++);
}
//***********************显示程序*********************************//
void disp(unsigned char t,unsigned char y)
{
if(y==0)//第一屏
{ switch(t)
{
case 0 ://第一排
{
disp16_16(0,0,0); //第一排第一字为:输
disp16_16(2,0,1); //第一排第二字为:出
disp8_16(4,0,10); //:
disp8_16(6,0,(out/2)/100);
disp8_16(7,0,((out/2)%100)/10);
disp8_16(8,0,((out/2)%100)%10);
}
case 1 ://第二排
{
disp16_16(0,2,3);//电
disp16_16(2,2,5);//池
disp8_16(4,2,10);//:
disp8_16(6,2,(bat)/100);
disp8_16(7,2,((bat)%100)/10);
disp8_16(8,2,((bat)%100)%10);
}
case 2 ://第三排
{
disp16_16(0,4,6);//负
disp16_16(2,4,7);//载
disp8_16(4,4,10);//:
disp8_16(6,4,(load)/100);
disp8_16(7,4,((load)%100)/10);
disp8_16(8,4,((load)%100)%10);
}
default :break;
}
}
if(y==1)//第二屏
{
switch(t)
{
case 0 :
{
disp16_16(0,0,0)//输
disp16_16(2,0,2)//入
disp8_16(4,0,10)//:
}
case 1 :
{
disp16_16(0,2,3);//电
disp16_16(2,2,5);//池
disp8_16(4,2,10);//:
disp8_16(6,2,(bat)/100);
disp8_16(7,2,((bat)%100)/10);
disp8_16(8,2,((bat)%100)%10);
}
case 2 :
{
disp16_16(0,4,8);//充电
disp16_16(2,4,3)//
disp8_16(4,0,10)//:
}
}
}
// ********************************PWM初始化*****************************************//
void pwm_init()
{
CMOD=0X04; //0000;0100设置PCA计数器工作频率为定时器0溢出//
CCON=0X00; //清零计数器和溢出标志//
CL=0X00; //计数器低8位和高8位全部清零//
CH=0X00;
CCAPM0=0X42; //设置PWM0口//
CCAPM1=0X42;
CCAPM2=0X42;
CCAPM3=0X42;
CCAP0L=0X00;
CCAP0H=0X00;
CCAP1L=0X00;
CCAP1H=0X00;
CCAP2L=0X00;
CCAP2H=0X00;
CCAP3L=0X00;
CCAP3H=0X00;
CR=1;//开启PCA计数器//
}
//****************//定时器初始化//*************************//
void time_init()
{
TMOD=0X02;//0000;0010定时器0工作在模式2;定时器1工作在方式0;//
AUXR=0X80;//1000;0000定时器0设置为12倍频率//
TH0=0XF8; //设置定时器0处置并处于自动重装状态//
TL0=0XF8;
ET1=1; //开定时器0中断//
TH1=0XEF;
TL1=0X0B; //定时器初值为8192-512 31个点晶振20M//
TR1=1;//开启定时器1//
TR0=1;//开启定时器0//
}
//****************************定时器中断装PWM***************************************** //
void int_time0(void) interrupt 3
{
TH1=0XEF;
TL1=0X0B;//重装计数值//
TR1=1;
CCAP0H=pwm1;
CCAP2H=pwm1;
CCAP1H=pwm2; //装入脉宽值//
CCAP3H=pwm2;
k++;
if(k<31)
{ i=k;
pwm_1=m*pwm[i]/255;
pwm1=(unsigned char)pwm_1;
pwm2=0;
}
else if(k<62)
{ j=k-31;
pwm1=0;
pwm_2=m*pwm[j]/255;
pwm2=(unsigned char)pwm_2;
}
else
{
k=0;
i=k;
pwm_1=m*pwm[i]/255;
pwm1=(unsigned char)pwm_1;
pwm2=0;
}
}
//**********************AD转换初始化**********************************
void AD_init()
{ P1M0=0X1E;
P1M1=0X00; //设置P1.1到P1.4为高阻输入//
ADC_CONTR = ADC_CONTR|0xE0; //1110,0000打开A/D转换电源;270个时钟周期转换一次//
delay(2);
ADC_CONTR = ADC_CONTR&0xE0; //1000,0000 清ADC_FLAG,ADC_START位和低3位
}
//******************************************************************//
unsigned int ad(unsigned char i) //AD 转换0————7对应P1.0到P1.7; 0--charge; 1--u_bat; 2--out;3--input; 4--load//
{ unsigned int u_out=0;
ADC_DATA=0;
ADC_LOW2=0;
ADC_CONTR=ADC_CONTR|(0X08|i);//0000,1010开启AD转换P1.2//
delayus();
do
{
;
}
while((ADC_CONTR&0X10)==1);//等待转换结束//
ADC_CONTR=ADC_CONTR&0XE0;//1110;0000清除ADC_FLAG,ADC_START//
u_out=((u_out|ADC_DATA)<<2)|(ADC_LOW2&0X03);
if(u_out>1024)
u_out=1024;
return(u_out);
}
void shutdown()
{
inv_flag=0;//禁止中断//
CCAP0H=0;
CCAP3H=0;
CCAPM1=0X00;//设置PMW1,PWM2关闭//
CCAPM2=0X00;////
//P2&=0XFE;//1111,1110将P2^0置低//
// P3&=0XEF;//1110,1111将P3^5置低;关闭两只上管//
}
//***************************软启动*******************************//
void soft_start(void)
{unsigned char i;
m=0;
do
{
m=m+9;
for(i=0;i<20;i++)
{
load+=ad(4);
bat+=ad(1);
}
bat/=20;
load/=20;
if((batoverload))
{
shutdown();
}
delay(10);
}while(m<189);
}
//*****************************逆变程序*******************************************//
void nibian()
{ unsigned char i;
out=0;
load=0;
bat=0;
for(i=0;i<20;i++)
{
out+=ad(2);
load+=ad(4);
bat+=ad(1);
}
out/=60;
load=load/20;
bat=bat/20;
if((batoverload)||batlow_flag)
{ shutdown();
if(bat
{
batlow_flag=1;
}
}
if((batoverload_L))
{
led=1; //过载,电池低压,亮灯//
}
else
led=0;
if(fabs(out-220)>4) //调整输出电压//
{ if(out>220)
m=m-3;
else
m=m+3;
}
}
void main()
{
unsigned char n,l;
init_spi();
res=0;
for(n=0;n<250;n++);
res=1; //LCD复位
LCD_init(); //初始化LCD模块
LCD_clear(); //清屏幕
pwm_init();
time_init();
AD_init();
soft_start();
while(1)
{
for(l=0;l<3;l++)
{
nibian();
disp(l,0);
}
}
}