哪位大神可以帮我翻译一下这个带液晶显示的充电器代码,多谢。

#include
#include

#define uint unsigned int
#define uchar unsigned char
#define nop nop

/*********端口定义********/
sbit GATE = P2^4;
sbit BP = P3^5;
sbit BusyFlag=P0^7;
//LCD控制接口
sbit E=P2^7;

sbit RW=P2^6;
sbit RS=P2^5;
sbit CS = P2^2;
sbit CLK = P2^1;
sbit DIO = P2^0;

sbit Lu=P3^4;
sbit Hu=P3^1;
sbit bit7=ACC^7; //单片机内部移位寄存器ACC声明;
sbit bit0=ACC^0;

//显示界面 LCD1602
uchar LCD_4,LCD_3,LCD_2,LCD_1,LCD_0;
uchar code LCDData[] ="0123456789";

uchar first_line[16]="Phone Charging "; //LCD第一行显示缓存数组
uchar second_line[16]="S:100% Volt=4.20"; //LCD第二行显示缓存数组,正常显示时间。
/*********************定义全局变量****************/
uint adval;//AD值
uint temp,num;
//uchar data temp_data[2]={0xff,0xff}; //读出温度暂放

//************************************
//延时程序
//************************************
void delay(unsigned int N)
{
unsigned int i;
for(i=0;i<N;i++);
}
//************************************

//LCD1602操作程序

//************************************
//LCD1602测忙
void check_busy(void)
{
while(1)
{
P0=0xff;
E=0;
nop();
RS=0;
nop();
nop();
RW=1;
nop();
nop();
E=1;
nop();
nop();

_nop_();
_nop_();
if((P0&0x80)==0)
{
    break;
}
E=0;
}

}
//LCD1602写命令
void write_command(uchar tempdata)
{
E=0;
nop();
nop();
RS=0;
nop();
nop();
RW=0;
P0=tempdata;
nop();
nop();
E=1;
nop();
nop();
E=0;
nop();
nop();

check_busy();
}
//LCD1602写数据
void write_data(uchar tempdata)
{
E=0;
nop();
nop();
RS=1;
nop();
nop();
RW=0;
P0=tempdata;
nop();
nop();
E=1;
nop();
nop();
E=0;
nop();
nop();

check_busy();
}
//初始化LCD1602
void init_lcd1602()
{
write_command(0x01); //清除屏幕
write_command(0x38); //功能设定(8位,2行,5*7点阵式)
write_command(0x0c); //显示器ON,光标OFF,闪烁OFF
write_command(0x06); //指针地址加1
delay(5);
}

void display(void)
{
uchar i;
write_command(0x80);
for(i=0;i<16;i++)
{
write_data(first_line[i]);
}
write_command(0xc0);
for(i=0;i<16;i++)
{
write_data(second_line[i]);
}
}
unsigned char A_D()
{
uchar i,dat;
CS=1; //一个转换周期开始
CLK=0; //为第一个脉冲作准备
CS=0; //CS置0,片选有效

DIO=1; //DIO置1,规定的起始信号

CLK=1; //第一个脉冲
CLK=0; //第一个脉冲的下降沿,此前DIO必须是高电平
DIO=1; //DIO置1, 通道选择信号

CLK=1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
CLK=0; //第二个脉冲下降沿
DIO=1; //DI置1,选择通道1
CLK=1; //第三个脉冲
CLK=0; //第三个脉冲下降沿
DIO=1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK=1; //第四个脉冲
for(i=0;i<8;i++) //高位在前
{
CLK=1; //第四个脉冲
CLK=0;
dat<<=1; //将下面储存的低位数据向右移
dat|=(uchar)DIO; //将输出数据DIO通过或运算储存在dat最低位
}

CS=1; //片选无效
return dat; //将读书的数据返回

}
void dis_0832(uint k)
{

uchar Int,Dec;
Int=(k)/51;
Dec=(k%51)*100/51;

second_line[12]=LCDData[Int];
second_line[13]='.';
second_line[14]=LCDData[Dec/10];
second_line[15]=LCDData[Dec%10];

}
void S_0832(uint l)
{

uchar Int,Dec;
Int=(l)/51;
Dec=(l%51)*100/51;

l=Int*100+Dec;
if(l<368)
{
second_line[2]=' ';
second_line[3]=' ';
second_line[4]=LCDData[0];
}

    else if(l<378) 
{
 second_line[2]=' ';
 second_line[3]='2';
 second_line[4]=LCDData[0];
 }
  else if(l<380) 
{
 second_line[2]=' ';
 second_line[3]='3';
 second_line[4]=LCDData[5];
 }   
  else if(l<385) 
{
 second_line[2]=' ';
 second_line[3]='4';
 second_line[4]=LCDData[8];
 }

    else if(l<390) 
{
 second_line[2]=' ';
 second_line[3]='6';
 second_line[4]=LCDData[8];
 }      else if(l<394) 
{
 second_line[2]=' ';
 second_line[3]='7';
 second_line[4]=LCDData[8];
 }
    else if(l<400) 
{
 second_line[2]=' ';
 second_line[3]='8';
 second_line[4]=LCDData[6];
}
     else if(l<403) 
{
second_line[2]=' ';
 second_line[3]='9';
 second_line[4]=LCDData[2];
}    else if(l<408) 
{
second_line[2]=' ';
 second_line[3]='9';
 second_line[4]=LCDData[8];
}

else 
{
 second_line[2]='1';
 second_line[3]=LCDData[0];
 second_line[4]=LCDData[0];
}         

}

uint t_count,int0_count;

/* 初始化 */

void init()
{
EA = 1; // 打开CPU中断
PT0 = 1; // T0中断设为高优先级

   TMOD = 0x11;             // 模式1,T0为16位定时/计数器
   TH0 = (65536-5000)/256;      // 5ms定时
   TL0 = (65536-5000)%256; 
   TH1 = (65536-5000)/256;      // 5ms定时
   TL1 = (65536-5000)%256; 

   ET0 = 1;               // 打开T0中断
   TR0=0;
   ET1 = 1;               // 打开T0中断
   TR1=0;

   IT0 = 1;                // 外部中断0设为边沿触发
   EX0 = 1;               // 打开外部中断0 

   GATE = 1;                  // 光耦正常输出电压
   BP = 1;                         // 关闭蜂鸣器

   int0_count = 0;        // 产生外部中断0的计数器清零

}

void main()
{

init_lcd1602();
init();

while(1)
{ adval=A_D();
dis_0832(adval);
S_0832(adval);
display() ;
delay(2000);
}
}
/* 定时器0中断服务子程序 */

void timer0() interrupt 1 using 1

{
TR0 = 0; // 停止计数
TH0 = (65536-5000)/256; // 重设计数初值
TL0 = (65536-5000)%256;
t_count++;

if ((t_count>600)) // // 外部中断0产生3s~5s的信号

   {

          if (int0_count==1)       // 还没有出现第二次外部中断0,则认为充电完毕
          {

                 GATE = 0;               // 关闭充电电源
                 BP = 0;                // 打开蜂鸣器报警
                 ET0 = 0;              // 关闭T0中断
                 EX0 = 0;             // 关闭外部中断0
                 Lu=0;
                 TR1=1;
          }

       else                       // 否则即是充电出错

          {
                 GATE = 1;      
                 BP = 1;
           }

          int0_count = 0;
          t_count = 0;
          }

   else

          TR0 = 1;                  // 启动T0计数

}
/* 外部中断0服务子程序 */

void int0() interrupt 0 using 1

{
if (int0_count==0)

   {
          TH0 = (65536-5000)/256;      // 5ms定时
          TL0 = (65536-5000)%256;   
          TR0 = 1;                  // 启动定时/计数器0计数
          t_count = 0;              // 产生定时器0中断的计数器清零

   }

          int0_count++;

}
void int1() interrupt 3

{
TH0 = (65536-5000)/256; // 5ms定时
TL0 = (65536-5000)%256;

num++;
if(num==1800)
{
Hu=0; //提醒灯
BP = 1; // 关闭蜂鸣器报警
TR1=0;
}

}

1个回答

不用翻译,猜测就行了。 ADC采集充电宝电压,然后在LCD上显示。出现过电压,过电流,终端控制继电器关闭充电通道。很简单51单片机知识

Mr_YuLei
Mr_YuLei 好吧,谢谢了。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐