tlc549_3.c

来自「自己的平时一些制作 现在整理一下 与大家一起分享」· C语言 代码 · 共 304 行

C
304
字号

#pragma ot(5,SIZE)
#include <reg51.h>
#include <intrins.h>
#define ERRORCOUNT 10
sbit SDA=P3^3;
sbit SCL=P3^5;
enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
enum eepromtype EepromType;           /* 器件类型枚举变量取值为0-8 */

//定义显示数组d[4]以及一个变量n用于动态显示
unsigned char d[4],n;
//定义显示用的查找表
unsigned char code table[11]={0x3f,6,0x5b,0x4f,
                   0x66,0x6d,0x7d,7,0x7f,0x6f,0}; //0--9 最后再有一个空
unsigned char code digit[4]={0xf8,0xf4,0xf2,0xf1};

//定义TLC549转换接口
sbit tlc549_cs=P1^6;
sbit tlc549_clk=P1^5;
sbit tlc549_data=P1^4;

//定义可位寻址的变量adc用于存放ad转换值,
//以及一个bit变量用于移位,它指示了ad的最最低一位
unsigned char bdata adc;
sbit  adclow=adc^0;

//ad转换函数
unsigned char adconvert()
{   unsigned char i;
    tlc549_cs=1;
    tlc549_cs=0;
    tlc549_clk=0;
    for(i=0;i<8;i++)
    {   tlc549_clk=1;
        adclow=tlc549_data;
        tlc549_clk=0;
        if(i<7) adc=adc<<1;
    }
    tlc549_clk=0;
    tlc549_cs=1;
    return(adc);
}

/******将ad转换BCD码值显示出来**********/
vtobcd(unsigned int hexs)
{       
        d[0]=hexs/1000;
        hexs=hexs % 1000;
        d[1]=hexs/100;
        hexs=hexs % 100;
        d[2]=hexs/10;
        hexs=hexs % 10;
        d[3]=hexs;
}

/*******延时函数***********/
void delay(unsigned char dy)
{
   while(--dy);
}

/***********************************************************************************/
bit RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address,
unsigned char ControlByte,enum eepromtype EepromType)
{
  void Delay(unsigned char DelayCount);
  void IICStart(void);
  void IICStop(void);
  bit IICRecAck(void);
  void IICNoAck(void);
  void IICAck(void);
  unsigned char IICReceiveByte(void);
  void IICSendByte(unsigned char sendbyte);
  unsigned char data j,i=ERRORCOUNT;
  bit errorflag=1;                      /* clr errorflag */
  while(i--)                            /* 启动IIC总线并发送EEPROM从器件地址 */
   {
    IICStart();                         /* 启动IIC总线 */
    IICSendByte(ControlByte&0xfe);      /* 发送EEPROM地址 */
    if(IICRecAck())                     /* 接收EEPROM应答信号 */
      continue;                         /* 接收EEPROM应答信号,为1重新启动 */
    if(EepromType>M2416)                /* EEPROM为24C32以上器件内地址为2字节 */
      {
        IICSendByte((unsigned char)(Address>>8));/* 先发送高字节,参考硬件相关说明 */
        if(IICRecAck())
           continue;
      }
    IICSendByte((unsigned char)Address);/* 再发送低字节或单字节地址 */
    if(IICRecAck())
      continue;
    if(!(ControlByte&0x01))             /* 以下为写操作 */
      {
        j=ByteQuantity;                 /* ByteQuantity为写入字节数 */
        errorflag=0;
        while(j--)
          {
            IICSendByte(*DataBuff++);   /* DataBuff写操作缓冲区 */
            if(!IICRecAck())
              continue;
            errorflag=1;
            break;
          }
        if(errorflag==1)
          continue;
        break;
     }
    else                                /* 以下为读操作 */
     {
      IICStart();                       /* 重新启动IIC总线并发送EEPROM从器件地址 */
      IICSendByte(ControlByte);
      if(IICRecAck())
        continue;
      while(--ByteQuantity)             /* 每次读一字节,共ByteQuantity字节 */
       {
         *DataBuff++=IICReceiveByte();  /*读1字节并存入DataBuff为指针的存储单元 */
         IICAck();                      /* 发送应答信号 */
       }
      *DataBuff=IICReceiveByte();       /*read last byte data*/
      IICNoAck();                       /* 读入最后一字节无须发送应答信号 */
      errorflag=0;
      break;
     }
    }
   IICStop();                           /* 停止IIC总线信号 */
   if(!(ControlByte&0x01))              /* 写入操作需延时,确保足够长写入时间 */
      {
       Delay(255);
       Delay(255);
       Delay(255);
       Delay(255);
      }
   return(errorflag);
}

/*******************
以下是对IIC操作子程序
*******************/
/*******************
      启动IIC
*******************/
void IICStart(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
SDA=1;
}
/*****************
   停止IIC总线
*****************/
void IICStop(void)
{
SCL=0;
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=0;
}
/**************
   检查应答位
**************/
bit IICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
CY=SDA;                                 /* 应答位返回值在CY中,0有效 */
SCL=0;
return(CY);
}
/***************
对IIC总线产生应答
***************/

void IICAck(void)
{
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
SDA=1;
}

/*****************
不对IIC总线产生应答
*****************/
void IICNoAck(void)
{
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}

/*******************
   向IIC总线写数据
*******************/
void IICSendByte(unsigned char sendbyte)
{
unsigned char data j=8;
for(;j>0;j--)
{
SCL=0;
sendbyte<<=1;  /* 发送字节变量sendbyte左移1位,CY=sendbyte^7,并回存 */
SDA=CY;
SCL=1;
}
SCL=0;
}

/********************
从IIC总线读数据子程序
********************/
unsigned char IICReceiveByte(void)
{
register receivebyte,i=8;
SCL=0;
while(i--)
{
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}

/*****定时器初始化函数********/
void Init_Timer (void)
{
    TMOD=0X21;
    TR0=1;
    ET0=1;
    EA=1;
}

/**********定时器0中断服务函数*****************/
void timer0() interrupt 1 using 1
{
    TH0=(65536-1000)/256;
    TL0=(65536-1000)%256;
    n=n++;
    if(n>3) n=0;
    P0=0;
    P2=digit[n];
    P0=table[d[n]]; 
}

/******主函数main*************/
//效果就是多次测量求平均值然后显示测量的电压值;
//电压值用mv为单位,范围 0--5000mv
//由于测量值的范围为0--255,所以中间要乘一个系数19.6
//并且将测量的值存入24c64
/*****************************/
void main()
{   
	unsigned char ad,j;
	unsigned int sum_ad=0;
	unsigned int *adc=0x30;
	Init_Timer();
    //变量初始化
    n=0;
  while(1)
     {  
    	for(j=0;j<10;j++)
   		{	ad=adconvert();  //ad转换
			sum_ad=sum_ad+ad;
			delay(250);
		}
		sum_ad=sum_ad/10;
  		vtobcd(sum_ad*19.6);    //将ad转换BCD码
		*adc=sum_ad*19.6;
		RW24XX(0x30,2,0x0010,0xa0,6);  /*把0x30开始的 待写入数据存储指针,写入字节数 */
   	   	for(j=0;j<200;j++)  delay(250);
		RW24XX(0x40,2,0x0010,0xa1,6);
		for(j=0;j<200;j++)  delay(250);
     }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?