⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text1.c

📁 这是一段关于用89C51单片机和AD芯片做定标电压表的源程序
💻 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 + -