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

📄 main.c

📁 如文件名
💻 C
字号:
/* David Wolpoff (david AT sparkfun DOT com)
 * Last modified 7 September 2006 
 *
 * I2C Example For LPC2138 and PCF8575, HMC6352, AD7746 
 * 
 */


#include <stdio.h>
#include "LPC214x.h"
#include "system.h"
#include "intcomm.h"
#include "iic.h"
#include "printmacros.h"

/* Function Prototypes */
void PCF8575_breakout(void);
void HMC6352_breakout(void);
void AD7746_breakout(void);

/* Number of functions in current test rig */
#define NUM_FUNCS 3

/* Function pointer array */
void (*funcs[NUM_FUNCS])(void) = {
PCF8575_breakout,
HMC6352_breakout,
AD7746_breakout
};

/* IIC Address array
 * PLEASE NOTE!
 * These addresses are in 8 bit format!
 * If your device assumes 7-bit i2c addresses,
 * you should take its address and shift left
 * one position.
 * The tx/rx functions will automagically
 * add the R/W bit
 */
char r_addy[NUM_FUNCS] = { 
0x40, 
0x42,
0x90
};

/* Device Names array */
char * names[NUM_FUNCS] = {
"PCF8575",
"HMC6352",
"AD7746"
};

int main(void)
{
  int v=0;
  unsigned char bs=0;
  int p=0;
  unsigned char data[2]={0,0};

/* Do basic initialization */
  boot_up(); /* From system.c */

/* Initialize IIC Module */
  i2c0_init();  /* From iic.c */
  i2c0ISR_init(); /* From iic.c */

  /* There IS a method to the madness!
   * PRINTF# macros are used to wrap sprintf calls
   * as output routines. This is done to reduce 
   * calls to malloc and avoid needing to fflush(stdout)
   * in order for output to show up.
   * This is because I am too lazy to rebuild newlib yet again
   */
  PRINTF0("I2C started\n\r");


  /* Forever!
   * Spin through the list of devices, announcing which device we're
   * currently attempting to communicate with. Whenever we
   * are successful in writing to a device (meaning the device gave
   * an acknowledge on the I2C interface) we call that device's 
   * routine. 
   * Basically, that means that if the iic.c routine doesn't throw an
   * error for a given device, we assume that device is working,
   * and we call its function.
   * Note that I don't actually expect any of the routines to return.
   * This loop is infinite because A. I've been taught to never let
   * anything go to the weeds. B. We use this code as a testbed, 
   * and it's not necessarily true that the device is connected prior
   * to reset.
   */
  while(1)
  {
    PRINTF1("Trying %s\n\r",names[p]);
    if(i2c0_master_send(r_addy[p],data,1) == 0) /* i2c0 routines
                                                   come from iic.c */
    {
      PRINTF1("Found %s\n\r",names[p]);
      funcs[p](); /* Call the function from the function pointer table */
    }
    p = (p+1)%NUM_FUNCS; /* Roll through a loop */
    delay_ms(1000); /* But pause for ~1 second */
  }
}

void PCF8575_breakout(void)
{
  int v=0;
  unsigned char bs=0;
  int p=0;
  unsigned char data[2]={0,0};

  while(1)
  {
    /* We test a case where we have a PCF8575 i2c bus expander
     * breakout board, and have resistors+leds connected from VCC
     * to P05 P06 P07
     * We make those LED's blink incrementing binary values.
     */
    p = (p+1)&7;  /* Calc number */
    data[0]=p<<5; /* Shift to the rigth position */
    if(i2c0_master_send(0x40,data,2)) /* Send the data to the device */
    {
      PRINTF0("Error communicating with PCF8578\n\r"); /* Self explanatory */
    }
    delay_ms(1000); /* Otherwise pause, and tick to next number */
  }
}

void HMC6352_breakout(void)
{
  int v=0;
  unsigned char bs=0;
  int p=0;
  unsigned char data[2]={0,0};
  while(1)
  {
    /* We just want to know that the HMC6352 is working
     * and generally points us in the right direction
     */
    data[0]='A'; /* Send a "Get Data" command to the compass */
    if(i2c0_master_send(0x42,data,1))
    {
      PRINTF0("HMC6352 Communication Error!\n\r"); /* Self explanatory */
    }
    if(i2c0_master_receive(0x42,data,2)==0) /* read out the two bytes of data */
    {
      /* Compute and print out a heading.
       * Note the conversion to floating point and 0.1 deg accuracy */
      PRINTF1("Heading: %3.1fdeg\n\r",((data[0] << 8)+data[1])/10.0); 
      delay_ms(500); /* Wait to avoid spamming too much */
    }
    else
    {
      PRINTF0("Reading failed \n\r"); /* Self explanatory */
    }
  }
}

void AD7746_breakout(void)
{

/* Relatively complete interface 
 * Set up assorted registers to get the modes we want
 * read out all the registers to verify correctness,
 * then take an infinite sequence of readings
 * reporting "raw" values to the terminal
 */
  unsigned char *ptr;
  int v=0;
  unsigned char bs=0;
  int i=0;
  int p=0;
  unsigned int c = 0;
  unsigned char data[20];
  for(v=0;v<20;v++)
  {
    data[v]=0;
  }
  v=0;

  /* Set addy to config reg */
  data[0]=0x0A;
  /* Write data = calibration mode, slow sampling */
  data[1]=0x01 | (7 << 3);
  
  PRINTF0("Performing first write\n\r");
  i2c0_master_send(0x90,data,2);
  
  /* Set addy to cap setup reg */
  data[0]=0x07;
  /* Write data = 0x80 = cap enabled */
  data[1]=0x80;
  i2c0_master_send(0x90,data,2);
  
  /* Set addy to EXC reg */
  data[0]=0x09;
  /* Set EXC source A */
  data[1]=0x08;
  i2c0_master_send(0x90,data,2);

  /*   Set addy to CAPDAC A reg */
  data[0]=0x0B;
  /* Set capdac a enabled and offset by about 1.2pF*/
  data[1]=0x00 | 39;
  i2c0_master_send(0x90,data,2);

  /* Set addy to config reg */
  data[0]=0x0A;
  /* Write data = 0x01 = continuous mode */
  data[1]=0x01 | (7 << 3);
  i2c0_master_send(0x90,data,2);
  
  /* Now hopefully configured */
  PRINTF0("Configuration steps complete\n\r");

  data[0]=0;
  data[1]=0;
  data[2]=0;
  
  i2c0_master_send(0x90,data,1);

  data[0]=0;
  data[1]=0;
  data[2]=0;

  /* Read all registers */
  PRINTF0("Reading all regs\r\n");
  for(i=0;i<18;i++)
  {
    data[0]=i;
    i2c0_master_send_receive(0x90,data,1,1);
    /* And print each register value out in hex */
    PRINTF2("%d: %X\n\r",i,data[0]);
    delay_ms(500);
  }

  /* OK-- now enter a loop */
  while(1)
  { 
    /* First read the status reg */
    data[0]=0x00;
    i2c0_master_send_receive(0x90,data,1,1);
    /* IF we've got a valid cap reading */
    if((data[0] & 0x01)==0)
    {
     
      /* read the data and report it */
      data[0]=0x01;
      i2c0_master_send_receive(0x90,data,1,3);
      PRINTF1("Measured %d\n\r",((data[0]<<16)+(data[1]<<8)+data[2]));
      delay_ms(1000);
    }
  }

}

⌨️ 快捷键说明

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