📄 text1.c
字号:
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
//数据口定义
#define lcd1602_bus P3
#define key_bus P1
//引脚定义
sbit rs_1602=P2^7;
sbit rw_1602=P2^6;
sbit e_1602=P2^5;
sbit cs_549=P0^2;
sbit data_549=P0^3;
sbit clk_549=P0^4;
sbit SCL=P2^0;
sbit SDA=P2^1;
uchar state;
uchar bdata adc_549;
sbit adc_549low=adc_549^0;
uchar s;
uchar mea,m[2];
uint in[2];
uchar code table0[]="1.mea2.dis3.plo";
uchar code table1[]="please measure";
uchar code table2[]="complete";
uchar code table3[]="in:";
uchar code asc[]="0123456789";
uchar code table4[]="display:";
uchar code table[1]=".";
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++);
}
//================IIC总线的操作子程序====================
/*****************启动总线**********************/
void IICStart(void)
{
SCL=0;
SDA=1;SCL=1;SCL=1;SCL=1;SCL=1;
SDA=0;SDA=0;SDA=0;SDA=0;SDA=0;
SCL=0;SCL=0;SCL=0;
SDA=1;
}
/*****************停止IIC总线****************/
void IICStop(void)
{
SCL=0;SDA=0;
SCL=1;SCL=1;SCL=1;SCL=1;
SDA=1;SDA=1;SDA=1;SDA=1;
SCL=0;
}
/**************检查应答位*******************/
bit IICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;SCL=1;SCL=1;SCL=1;SCL=1;
CY=SDA; //因为返回值总是放在CY中的
SCL=0;
return(CY);
}
/*****************不对IIC总线产生应答***************/
void IICNoAck(void)
{
SDA=1;
SCL=1;SCL=1;SCL=1;SCL=1;SCL=1;SCL=0;
}
/*******************向IIC总线写数据*********************/
void IICSendByte(uchar sendbyte)
{
uchar j;
for(j=8;j>0;j--)
{
SCL=0;
sendbyte<<=1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7;
SDA=CY;
SCL=1;
}
SCL=0;
}
/**********************从IIC总线上读数据子程序**********/
uchar IICReceiveByte(void)
{
uchar receivebyte,ii;
SCL=0;
ii=8;
while(ii--)
{
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}
/**************************************************************************************************
*
*IIC总线写函数
*函数声明:bit IICWrite(uint address,uchar buf);
*函数参数:address为AT24C64的地址,buf为要在这个地址写的数据
*函数作用:往地址写一个字节的数据
**************************************************************************************************/
bit IICWrite(uint address,uchar buf)
{
bit flag;
flag=1;
IICStart();
IICSendByte(0xa0);
if(IICRecAck())
flag=0;
IICSendByte((uchar)(address>>8));
if(IICRecAck())
flag=0;
IICSendByte((uchar)address);
if(IICRecAck())
flag=0;
IICSendByte(buf);
if(IICRecAck())
flag=0;
IICStop();
delay(255);
delay(255);
delay(255);
delay(255);
return(flag);
}
uchar IICRead(uint address)
{ uchar buf;
IICStart();
IICSendByte(0xa0);
if(IICRecAck())
buf=0xff;
IICSendByte((uchar)(address>>8));
if(IICRecAck())
buf=0xff;
IICSendByte((uchar)address);
if(IICRecAck())
buf=0xff;
IICStart();
IICSendByte(0xa1);
if(IICRecAck())
buf=0xff;
buf=IICReceiveByte();
//read last byte data
IICNoAck();
IICStop();
delay(50);
return(buf);
}
/**************adc_549convert*******************/
uchar adc_549convert()
{ unsigned char i;
cs_549=1;
cs_549=0;
clk_549=0;
for(i=0;i<8;i++)
{
data_549=1;
clk_549=1;
adc_549low=data_549; //read one bit
clk_549=0;
if(i<7) adc_549=adc_549<<1;//经八次左移adc初值可以不付
}
clk_549=0;
cs_549=1;
return(adc_549);
}
/***********忙判断标志,返回一个位BF********************/
bit lcd1602_busy(void)
{
uchar busy_flag;
rs_1602=0;
rw_1602=1;
_nop_();
e_1602=1;
_nop_();
lcd1602_bus=0xff;
busy_flag=lcd1602_bus; //e在高电平时读
e_1602=0;
return (bit)(busy_flag&0x80); //BF=1; BUSY 返回一个位
}
/********写命令,有两个参数,一个是要写的命令控制字,
第二个是用来控制是否进行忙标志的判断。
busyflag=1;
判断: 为0
***************/
void lcd1602_wrcmd(unsigned char lcdcmd)
{
while(lcd1602_busy()); //等待空闲
lcd1602_bus=lcdcmd;
rs_1602=0;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0; //产生一个下沿
}
/***************向液晶写数据******************/
void lcd1602_wrdata(uchar lcddata)
{
while(lcd1602_busy()); //等待空闲
lcd1602_bus=lcddata; //在下沿的时候写数据
rs_1602=1;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0;
//lcd_bus=0xff;
}
/************液晶的清屏************/
void lcd1602_clear(void)
{
lcd1602_wrcmd(0x01); //液晶清屏控制字 并延时>40us
delay(100);
}
/***********1602液晶的初始化***************/
void lcd1602_init(void)
{
lcd1602_wrcmd(0x38); //功能设置-----8位数据接口,两行显示,5*7点阵字符显示
delay(100);
lcd1602_wrcmd(0x0e); //显示开关控制----显示开关开,光标开关关,闪烁开关关
delay(100);
lcd1602_wrcmd(0x06); //输入方式设置,AC自增1, S=0;
delay(100);
lcd1602_wrcmd(0x01); //清屏
delay(100);
}
/************键盘扫描*************/
uchar keyscan(void)
{
uchar scancode,tmpcode;
key_bus = 0xf0;
if ((key_bus&0xf0)!=0xf0)
{
delay(125);
if ((key_bus&0xf0)!=0xf0)
{
scancode = 0xfe;
while((scancode&0x10)!=0)
{
key_bus = scancode;
if ((key_bus&0xf0)!=0xf0)
{
tmpcode = (key_bus&0xf0)|0x0f;
return((~scancode)+(~tmpcode));
}
else scancode = (scancode<<1)|0x01;
}
}
}
return(0);
}
void enter0()
{
uchar i;
state=0;
lcd1602_clear();
lcd1602_wrcmd(0x80);
for(i=0;i<15;i++)
lcd1602_wrdata(table0[i]);
}
void enter1()
{
uchar i;
state=1;
lcd1602_clear();
lcd1602_wrcmd(0x80);
for(i=0;i<14;i++)
lcd1602_wrdata(table1[i]);
}
void enter3()
{
uchar i;
state=3;
lcd1602_clear();
lcd1602_wrcmd(0x80);
for(i=0;i<3;i++)
lcd1602_wrdata(table3[i]);
}
void measure()
{
uchar i;
mea=adc_549convert();
lcd1602_wrcmd(0xc0);
for(i=0;i<8;i++)
lcd1602_wrdata(table2[i]);
}
void measurebiao()
{
uchar i;
m[s]=adc_549convert();
lcd1602_wrcmd(0xc0);
for(i=0;i<8;i++)
lcd1602_wrdata(table2[i]);
lcd1602_wrcmd(0x0f);
lcd1602_wrcmd(0x83);
state=4;
}
void getnum(uchar u)
{
if(u==0x12)
{
in[s]=in[s]*10+0;
lcd1602_wrdata(asc[0]);
}
else if(u==0x21)
{
in[s]=in[s]*10+1;
lcd1602_wrdata(asc[1]);
}
else if(u==0x22)
{
in[s]=in[s]*10+2;
lcd1602_wrdata(asc[2]);
}
else if(u==0x24)
{
in[s]=in[s]*10+3;
lcd1602_wrdata(asc[3]);
}
else if(u==0x41)
{
in[s]=in[s]*10+4;
lcd1602_wrdata(asc[4]);
}
else if(u==0x42)
{
in[s]=in[s]*10+5;
lcd1602_wrdata(asc[5]);
}
else if(u==0x44)
{
in[s]=in[s]*10+6;
lcd1602_wrdata(asc[6]);
}
else if(u==0x81)
{
in[s]=in[s]*10+7;
lcd1602_wrdata(asc[7]);
}
else if(u==0x82)
{
in[s]=in[s]*10+8;
lcd1602_wrdata(asc[8]);
}
else if(u==0x84)
{
in[s]=in[s]*10+9;
lcd1602_wrdata(asc[9]);
}
}
void cunchu()
{
uchar i,j;
j=s*3;
IICWrite(j,m[s]);
i=(uchar)(in[s]);
IICWrite(j+1,i);
i=(uchar)(in[s]>>8);
IICWrite(j+2,i);
}
void display()
{
uint i,ax,bx;
uchar cx,dx,j[2];
cx=IICRead(0);
dx=IICRead(3);
ax=IICRead(2);
ax=ax<<8+IICRead(1);
bx=IICRead(5);
bx=bx<<8;+IICRead(4);
i=(in[0]*m[1]-m[0]*in[1]+m[0]*mea-m[1]*mea)/(in[0]-in[1]);
j[0]=i/100;
i=i%100;
j[1]=i/10;
i=i%10;
j[2]=i;
lcd1602_clear();
lcd1602_wrcmd(0x80);
for(i=0;i<8;i++)
lcd1602_wrdata(table4[i]);
lcd1602_wrdata(asc[j[0]]);
lcd1602_wrdata(table[0]);
lcd1602_wrdata(asc[j[1]]);
lcd1602_wrdata(asc[j[2]]);
}
main()
{
uchar key;
s=0;
delay(2);
lcd1602_bus=0xff;
lcd1602_init();
enter0();
while(1)
{
key=0;
while(key==0)
key=keyscan();
while(key_bus!=0xf0)
key_bus=0xf0;
if(state==0)
{
if(key==0x21)
enter1();
else if(key==0x22)
{
state=2;
display();
}
else if(key==0x24)
enter3();
}
else if(state==1)
{
if(key==0x18)
{
measure();
}
else if(key==0x88)
enter0();
}
else if(state==2)
{
if(key==0x88)
enter0();
}
else if(state==3)
{
if(key==0x18)
{
measurebiao();
in[s]=0;
}
else if(key==0x88)
enter0();
}
else if(state==4)
{
getnum(key);
if(key==0x18)
{
cunchu();
lcd1602_wrcmd(0x0e);
enter3();
s++;
if(s==2)
s=0;
}
else if(key==0x88)
{
in[s]=0;
enter3();
measurebiao();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -