历史上的今天
返回首页

历史上的今天

今天是:2024年10月30日(星期三)

正在发生

2019年10月30日 | MSP430杂谈--AD7745硬件IIC驱动与模拟IIC驱动

2019-10-30 来源:eefocus

和上一篇AD7793类似,项目中也涉及到利用AD7745读取电容值,来测环境湿度。编写了基于MSP430的AD7745的硬件IIC驱动和模拟IIC驱动,分享给大家。


AD7745硬件IIC驱动完整版下载链接:https://download.csdn.net/download/qq_42580947/11041942


AD7745模拟IIC驱动完整版下载链接:https://download.csdn.net/download/qq_42580947/11041947


PS:目前资源积分无法自行调整,有谁知道可以修改积分的方法请告知,我想免费分享给大家。


1. AD7745的硬件IIC驱动


MCU:MSP430F57XX


AD7745的硬件IIC驱动失败的几个原因有:单片机配置IIC资源错误(包括IIC的时钟,IIC的运行模型等配置错误),单片机的系统时钟配置错误(注意MCLK, SMCLK, ACLK的分配)


1.1 AD7745的写函数


void AD7745_W(unsigned char addr, unsigned char data)

{

  while(UCB0STAT& UCBBUSY)

    InitUCB0();

  UCB0CTL1 |= UCTR;

  UCB0CTL1 |= UCTXSTT;   

 

  UCB0TXBUF = addr;

  delayus(200);

  while(!(UCB0IFG & UCTXIFG0));

  

  UCB0TXBUF = data;

  delayus(200);

  while(!(UCB0IFG & UCTXIFG0));

 

  UCB0CTL1 |= UCTXSTP;

  while (UCB0CTL1 & UCTXSTP);

}

1.2 AD7745的读函数


void AD7745_R(unsigned char addr, unsigned char *buffer, char n)

{

  unsigned char index;

  UCB0CTL1 |= UCTR;

  UCB0CTL1 |= UCTXSTT; 

  delayus(200);

  UCB0TXBUF = addr;

  delayus(200);

  while(!(UCB0IFG & UCTXIFG0));

  while (UCB0CTL1 & UCTXSTP);

 

  UCB0CTL1 &=~ UCTR;

  RXByteCtr = n;

  UCB0CTL1 |= UCTXSTT;  

  delayus(200);

  while (UCB0CTL1 & UCTXSTP);

  for(index=0; index < n-1; index++)

  {

    while(!(UCB0IFG & UCRXIFG0));            

    *buffer++ = UCB0RXBUF;

    delayus(200);

  }

 

  UCB0CTL1 |= UCTXSTP+UCTXNACK;

  delayus(200);

  while((UCB0IFG&UCRXIFG)==0);

  *buffer = UCB0RXBUF;

  delayus(200);

  while (UCB0CTL1 & UCTXSTP); 

}

1.3 AD7745的复位


void Reset_AD7745()

{

  while(UCB0STAT& UCBBUSY)

    InitUCB0();

  UCB0CTL1 |= UCTR;

  UCB0CTL1 |= UCTXSTT; 

  delayus(200);

  UCB0TXBUF = 0xBF;

  while(!(UCB0IFG & UCTXIFG0));

  

  UCB0CTL1 |= UCTXSTP;

  while (UCB0CTL1 & UCTXSTP); 

}

1.4 AD7745的初始化


void Init_AD7745(void)

{

  AD7745_W(0x0D, offset_buf[0]);

  AD7745_W(0x0E, offset_buf[1]);

  capdac_offset = Capdac_Parameter;                           

  out_buff[4] = 0x80+capdac_offset;               //CAPDACA is set to capdac_offset

  out_buff[5] = 0x80;                             //CAPDACB is set to 0

  CAPDAC = (float)(capdac_offset*CAPDAC_UNIT);   //CAPDAC只会取4值,即4.25,8.5,12.75,17

  AD7745_W(0x07, out_buff[0]);                    // data collect

  AD7745_W(0x08, out_buff[1]);

  AD7745_W(0x09, out_buff[2]);

  AD7745_W(0x0A, out_buff[3]);

  AD7745_W(0x0B, out_buff[4]); 

  AD7745_W(0x0C, out_buff[5]);

 

  memset(DataArr,0,sizeof(float)*DataNumber);

}

1.5 读取测量数据


void ReadData(void)

{

  AD7745_R(0x01, in_buff, sizeof(in_buff));  // read the data register

  CDC_Register_data = in_buff[1];

  CDC_Register_data = 0;

  CDC_Register_data = in_buff[1];

  CDC_Register_data <<= 8;

  CDC_Register_data += in_buff[2];

  CDC_Register_data <<= 8;

  CDC_Register_data += in_buff[0];

  CDC_Register_data &= 0x00ffffff;

 

  CDC_Capacitance2 = (float)(FULL_SCALE-SEMI_SCALE);

 

  if(CDC_Register_data>= SEMI_SCALE)

  {

      CDC_Capacitance1 = (float)(CDC_Register_data-SEMI_SCALE);

      CDC_Capacitance = 4.096 * (CDC_Capacitance1/CDC_Capacitance2);

  }

  else

  {

      CDC_Capacitance1 = (float)(SEMI_SCALE-CDC_Register_data);

      CDC_Capacitance = -4.096 * (CDC_Capacitance1/CDC_Capacitance2);

  }

 

  CDC_Capacitance = CAPDAC+CDC_Capacitance;

  Capacitance  = CDC_Capacitance;

}

2. AD7745模拟IIC驱动


模拟IIC驱动失败的最主要原因是:时钟!时钟!时钟!注意时钟的配置和延时的处理


2.1 AD7745基础子函数的处理


void start()

{

    SCL_OUT;

    SDA_OUT;

    SDA_H;

    delayms(1);

    SCL_H;

    delayms(1);

    SDA_L;

    delayms(1);

    SCL_L;

    delayms(1);

}

 

void stop()

{

  SDA_OUT;

  SCL_OUT;

  SDA_L;

  delayms(1);

  SCL_H;

  delayms(1);

  SDA_H;

  delayms(1);

}

 

void Ack()

{

  SDA_OUT;

  SCL_OUT;

  SCL_L;

  SDA_L;

  delayms(1);

  SCL_H;

  delayms(1);

  SCL_L;

}

void NAck()

{

  SDA_OUT;

  SCL_OUT;

  SCL_L;

  SDA_H;

  delayus(2);

  SCL_H;

  delayus(2);

  SCL_L;

}

 

unsigned int WAck()

{

    SDA_H;

    SDA_IN;

    SCL_H;

    

    while(P1IN & BIT6)

    {

    }

  SCL_L;

  delayms(1);

  return 0;

}

1.2 读取字节数据


uchar read_byte()

{

  uchar i,read_data;

  SDA_OUT;

  SCL_L;

  SDA_H;

  for(i = 0;i<8;i++)

  {

    SDA_H;

    delayus(2);

    SCL_H;

    SDA_IN;

    delayus(2);

    read_data <<= 1;

    if(P1IN & BIT6)

      read_data |= 0x01;

    SDA_OUT;

    SCL_L;   

  }

  delayms(5);

  return(read_data);

}

1.3 写字节数据


void write_byte(uint data)

{

  uchar i;

  SCL_OUT;

  SDA_OUT;

  for(i = 0;i<8;i++)

  {

    if(data & 0x80)

      SDA_H;

    else

      SDA_L; 

 

    delayms(1);

    SCL_H;

    delayms(1);

    SCL_L;

    delayms(1);

    data = data << 1;

  }

  delayms(5);

}

1.4 向指定地址写数据


void write_dat(uchar addr,uchar write_data)

{

  start();

  write_byte(OP_WRITE);

  WAck();

  write_byte(addr);

  WAck();

  write_byte(write_data);

  WAck();

  stop();

  delayus(1000);

}

1.5 从指定地址读数据


uchar read_random(uint random_addr)

{

  uchar i;

  start();

  write_byte(OP_WRITE);

  WAck();

  write_byte(random_addr);

  WAck();

  start();

  write_byte(OP_READ);

  WAck();

  i = read_byte();

  stop();

  return i;

}

1.6 AD7745的初始化


void Init_AD7745()

{

  start();

  write_byte(0X09);

  WAck();

  write_byte(0xBF);

  delayus(500);

  WAck();

  stop();

}

1.7 写数组与读数组


void EEPROM_WriteArray (unsigned char dest_addr, unsigned char* src_addr,

                        unsigned char len)

{

   unsigned char i;

   start();

   write_byte(OP_WRITE);

   WAck();

   write_byte(dest_addr);

   WAck();

   for( i = 0; i < len; i++ )

   {

   write_byte(src_addr[i]);

   WAck();

   }

   stop();

   delayus(1000);

}

void EEPROM_ReadArray (unsigned char* dest_addr, unsigned char src_addr,

                       unsigned char len)

{

  uchar i;

  start();

  write_byte(OP_WRITE);

  WAck();

  write_byte(src_addr);

  WAck();

  start();

  write_byte(OP_READ);

  WAck();

  for( i = 0; i < len; i++ )

  {

    dest_addr[i] = read_byte();

    if(i!=len-1)

    Ack();

    else

    NAck();

  }

    stop();

}

1.8 AD7745的配置


void Capdacsetup(void)

{

   EEPROM_WriteArray(0x0D, offset_buf, sizeof(offset_buf));      // OFFSET寄存器初始化

   Capdac_Parameter = 127;

   capdac_offset = Capdac_Parameter;                           

   out_buff[4] = 0x80+capdac_offset;                            

   out_buff[5] = 0x80;                                         //CAPDACB is set to 0

   CAPDAC = (float)(capdac_offset*CAPDAC_UNIT);                                 

   EEPROM_WriteArray(0x07, out_buff, sizeof(out_buff));         // data collect

   memset(DataArr,0,sizeof(float)*DataNumber);

}

1.9 读取测量数据


void ReadData(void)

{

EEPROM_ReadArray(in_buff, 0x01, sizeof(in_buff));  // read the data register

CDC_Register_data = 0;

CDC_Register_data = in_buff[0];

CDC_Register_data <<= 8;

CDC_Register_data += in_buff[1];

CDC_Register_data <<= 8;

CDC_Register_data += in_buff[2];

CDC_Register_data &= 0x00ffffff;

CDC_Capacitance2 = (float)(FULL_SCALE-SEMI_SCALE);

 

if(CDC_Register_data>= SEMI_SCALE)

{

CDC_Capacitance1 = (float)(CDC_Register_data-SEMI_SCALE);

CDC_Capacitance = 4.096 * (CDC_Capacitance1/CDC_Capacitance2);

}

else

{

CDC_Capacitance1 = (float)(SEMI_SCALE-CDC_Register_data);

CDC_Capacitance = -4.096 * (CDC_Capacitance1/CDC_Capacitance2);

}

CDC_Capacitance = CAPDAC+CDC_Capacitance;

DataArr[Int_dec++]=CDC_Capacitance;

if(Int_dec==DataNumber)

Int_dec=0;

}

推荐阅读

史海拾趣

登丰微(GSTEK)公司的发展小趣事

歌普电子科技有限公司以自有品牌(GEPU歌普)创立于2006年,公司最初在台湾设立,随后逐步扩展至江苏和东莞,形成了跨区域的研发、生产和销售网络。公司自创立之初便专注于各式线对板连接器、板对板连接器、网络连接器等产品的研发与设计。通过不断的技术积累和市场需求洞察,歌普逐渐在连接器领域建立了自己的市场地位。

Artaflex公司的发展小趣事

面对全球电子市场的不断扩张,Artaflex公司制定了全球化的发展战略。公司通过设立海外分支机构、拓展国际市场、参与国际展会等方式,不断提升品牌知名度和市场份额。同时,公司还积极引进国际先进技术和管理经验,提升自身的竞争力。这一战略的实施使得Artaflex在全球电子行业中占据了重要地位。

CONTEC公司的发展小趣事

在互联网+的浪潮下,CONTEC公司积极拥抱变革。2010年,公司开始布局“互联网+”领域,通过建立河北省医疗检查监测仪器工程技术研究中心,探索将互联网技术应用于医疗设备。这一举措不仅拓宽了公司的业务范围,还提高了产品的智能化和便捷性。

GTK UK Ltd公司的发展小趣事
太阳光强度变化、云层遮挡、大气湍流等环境因素都可能对光电传感器产生影响,导致检测误差。
功得(CONQUER)公司的发展小趣事

随着公司实力的不断增强,功得公司开始将目光投向国际市场。他们积极参加国际电子展会,与全球各地的客户建立联系,拓展销售渠道。同时,功得公司还根据不同国家和地区的市场需求,推出定制化的产品和服务。通过不懈努力,功得公司逐渐在国际市场上打开了局面,产品出口量稳步增长。

承兴(CX)公司的发展小趣事

经过多年的努力和发展,承兴公司已经成为一家具有全球影响力的电子企业。除了在中国市场保持领先地位外,承兴还积极拓展海外市场,并在美国、新加坡等地设立了分公司和研发中心。通过与全球合作伙伴的紧密合作和资源共享,承兴不断提升其全球竞争力,并努力实现国际化的发展目标。

请注意,由于承兴(CX)公司的具体发展历程和细节可能因时间和市场变化而有所不同,以上故事仅为虚构示例,旨在展示承兴公司在电子行业中的发展脉络和关键事件。

问答坊 | AI 解惑

你开发的项目文档化了吗?看看老外是怎么做的。希望参与项目管理的朋友都进来看看

出差报告 引言        我于8月24日~10月22日在瑞典研究所出差,为期2个月,这里把工作情况做一下回顾和总结,以期对今后自己以及产品今后的工作和发展有一点作用。 任务完成情况     此次到瑞典研究所主要是 ...…

查看全部问答>

LPC1343

LPC1343开发板申请!…

查看全部问答>

如何将石英表改装成24小时指示时间?

如何让石英表按24小时指示时间?…

查看全部问答>

请问大家,在BSP内核中加载I2C内核,在evc调用出现超时错误,这是怎么回事啊?

I2C_Open ---- >I2C_IOControl(0x40004, 0x1a02f244, 16, 0x0) I2C IOCTL_I2C_WRITE 090704 I2C IOCTL_I2C_WRITE 090704 MapPtrToProcess +I2C_Write[1]: 0x9E, 0x1, 0x20, 1 EnterCriticalSection ResetEvent Be ResetEvent Af SyncIst ...…

查看全部问答>

为什么wince5.0模拟器设置时没有Serial over DMA这个选项,急急急急!!!!!!!!!

如题,多谢大侠,救救小女子~~~~本人没有分,可怜可怜我吧~~~…

查看全部问答>

采用Marvell公司最新的基于第三代 Intel XScale 技术CPU PXA 310开发平台

CES-310开发平台简介 深圳市海天雄电子有限公司 CES-310 开发平台(实用型)简介 ■ 功能与特色 CES-310 开发平台采用Marvell公司最新的基于第三代 Intel XScale 技术CPU PXA 310 设计而成,本平台在多媒体处理,速度等方面较之前推出的CPU 平台 ...…

查看全部问答>

关于STM32进入待机模式后很容易自动复位

把STM32按照正确的时序进入待机模式之后, 一开始都还正常..外部中断是不能唤醒的, 除非在PA0(WAKE UP PIN)上加一个上升沿. 但是很奇怪的是, 我发现我开一下台灯, 系统居然自己复位了, 就好像我按了复位键或者按了PA0一样....随后发现,貌似外 ...…

查看全部问答>

关于clock()函数的使用

我在程序中写了这样一段代码。 clock_t start,stop,overhead; start=clock(); stop=clock(); overhead=stop-start; start=clock(); doSth(); stop=clock(); printf(\\"%d\\\\n\\",stop-start-overhead); 我发现输出的结果总是0,调 ...…

查看全部问答>

关于低功耗的实验!!!!请大侠指点!!!!

我的项目是手持产品,目前已经进入尾声,但是在关机之后还会有约5个毫安的电流。请问如何解决?一般情况下,关机之后都进行那些处理才能达到TI宣称的功耗值。???????!!!!!!…

查看全部问答>