i2c_demo_master.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 533 行 · 第 1/2 页

C
533
字号
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2005 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML67Q4051/ML67Q4061 series                         */
/*     Module Name  :  ML67Q4051/ML67Q4061 i2c demo program (Master)      */
/*                                                     for AME-51         */
/*     File   Name  :  i2c_demo_master.c                                  */
/*     Revision     :  01.00                                              */
/*     Date         :  2005/05/18                                         */
/*                                                                        */
/**************************************************************************/

/*
The temperature sensor is a Texas Instruments part TMP100 (Burr Brown).
It performs A/D conversions with a resolution of 9 to 12 bits.
This program has the resolution set to 9 bits.
This allows conversions to be completed in 40ms.
12 bit conversions require 320ms.
The result of each conversion is stored at I2C_ReceivData[0:1].
Location I2C_ReceivData[0] contains the high byte.
Location I2C_ReceivData[1] contains the low byte.
The high byte is the temperature in degrees C (binary).
The low byte returns either 0x00 or 0x80.
If the low byte = 0x00 then the temperature is xx.0
If the low byte = 0x80 then the temperature is xx.5
*/

#include   "ml674061.h"
#include   "common.h"

#ifdef __IAR__
#include "intrinsics.h"
#endif

/* constants */
#define I2C_END_PATTERN 0xFF            /* data end pattern */
#define BUFF_SIZE	16
#define WRITE_MODE      0x0
#define READ_MODE       0x1
#define SLAVE_ADDRESS   0x48            /* For TI's TMP100 I2C temp. sensor. */
#define I2C_TEMP_INDEX  0x00            /* Index for temp reading */
#define I2C_TEMP_SIZE   0x02            /* The size of the temp reading. */
#define I2CCTL_400K	0x1
#define I2CBC_100K32    (0x28)          /* HCLK=32Mhz,I2CMD=400khz */
#define I2CBC_400K32	(0x0A)	        /* HCLK=32MHz,I2CMD=400kHz */
#define PORTSEL1_I2C	0x05000000
#define PORT            0               /* default test is for port UART0 */
                                        /* set PORT to 1 if test port UART1 */
#define PORT_OFFSET     0x1000


/* functions */
void init_i2c(void);			    /* Initialize I2C */
void i2c_send_data(void);		    /* I2C send process */
void i2c_receive_data(void);		    /* I2C receive process */
void send_addr_data(int);		    /* I2C send addrress data process */
void send_byte_data(UBYTE send_data);	    /* I2C send data process */
void wait_for_send_receive(void);	    /* Waiting for Sending data or Receiving data */
int  cmp_data_fn(UBYTE*, UBYTE*, int size); /* Data compare process */
void AME_51_Temp_Test(void);                /* temperature sensor routine */
void i2c_test(void);                        /* test i2c port */
void i2c_entry(void);
extern void    init_uart(int portNum);
extern void test_failure(void);
extern void both_switches(void);



/* global variables */
static volatile int temperature_buff[2];    /* temperature buffer */
unsigned  char  I2C_SendData[BUFF_SIZE];    /* Send buffer */
unsigned  char  I2C_ReceivData[BUFF_SIZE];  /* Receive buffer */
UBYTE led_pt;				    /* LED pattern */
int err_status;				    /* Error status */
extern  volatile int  counter;                       /* timer counter */
extern volatile char both_switches_flag;             /* will be cleared after both switches have been pushed */

extern volatile  UBYTE switch2_state;       /* 0=opened    1=closed */
extern volatile  UBYTE switch3_state;       /* 0=opened    1=closed */

enum err_num {		                    /* Error number */
	NO_ERR, 		            /* No error */
	DATA_ACK_ERR,	                    /* Data ACK non-receiving error */
	ADDR_ACK_ERR,	                    /* Address ACK non-receiving error */
	BUS_ERR,		            /* Arbitration lost error */
	DATA_CMP_ERR	                    /* Data comparison error */
};

unsigned char cmp_data[BUFF_SIZE]           /* compare data */
				= {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

/****************************************************************************/
/*  Entry point                                                             */
/*  Function : i2c demo                                                     */
/*      Parameters                                                          */
/*          Input  :  Nothing                                               */
/*          Output :  0                                                     */
/****************************************************************************/
void i2c_entry(void)
{
  int n10,n1,n;        /* this is the decimal equivalent of temperature */
  int remainder;                  /* used to do the binary to decimal conversion */

  init_uart(0);                   /* initialize UART */

  led_on(LED_3);                  /* Demo 3 - put "3" on LED display */

  both_switches_flag=1;           /* will be cleared to exit I2C demo */
  while (both_switches_flag)
  {
    if (counter>50)               /* do a reading every 500ms */
    {
      counter=0;                  /* reset counter */
      AME_51_Temp_Test();         /* get a reading from the temperature sensor */

      temperature_buff[0] = I2C_ReceivData[0];      /* save data */
      temperature_buff[1] = I2C_ReceivData[1];

      if (temperature_buff[0]<0x14)
      {
        put_value(PO4,7);          /* turn off all LEDs  */
      }
      else if (temperature_buff[0]<0x16)
      {
        put_value(PO4,6);          /* set LEDs to 001  */
      }
      else if (temperature_buff[0]<0x18)
      {
        put_value(PO4,5);          /* set LEDs to 010  */
      }
      else if (temperature_buff[0]<0x1A)
      {
        put_value(PO4,4);          /* set LEDs to 011  */
      }
      else if (temperature_buff[0]<0x1C)
      {
        put_value(PO4,3);          /* set LEDs to 100  */
      }
      else if (temperature_buff[0]<0x1E)
      {
        put_value(PO4,2);          /* set LEDs to 101  */
      }
      else if (temperature_buff[0]<0x20)
      {
        put_value(PO4,1);          /* set LEDs to 110  */
      }
      else
      {
        put_value(PO4,0);          /* set LEDs to 111  */
      }

//        n1000=(temperature_buff[0]/1000)+'0';   /* calculate 1000s digit and convert to ascii */
        remainder=temperature_buff[0]%1000;
//        n100=(remainder/100)+'0';               /* calculate 100s digit and convert to ascii */
        remainder=remainder%100;
        n10=(remainder/10)+'0';                 /* calculate 10s digit and convert to ascii */
        n1=(remainder%10)+'0';                  /* calculate 1s digit and convert to ascii */
        if (temperature_buff[1] == 0) n='0';    /* calculate first decimal place */
        else n='5';

        put_value(UARTTHR0+PORT*PORT_OFFSET,'T');   /* send "T" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'e');   /* send "e" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'m');   /* send "m" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'p');   /* send "p" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,' ');   /* send " " to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'i');   /* send "i" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'s');   /* send "s" to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,' ');   /* send " " to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,n10);   /* send 10s to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,n1);    /* send 1s to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,'.');   /* send "." to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,n);     /* send 0.1s to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,0x0D);  /* send CR to UART */
        put_value(UARTTHR0+PORT*PORT_OFFSET,0x0A);  /* send LF to UART */
    }

    both_switches();                                /* check for both switches pushed */
  }
  put_value(PO4,7);                                 /* turn off all LEDs */

  return;
}


/******************************************************************/
/*  Initialize I2C                                                */
/*  Function : init_i2c (Master)                                  */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_i2c(void)
{
	unsigned char  i;
	
        /* get a clean start */
        put_hvalue(I2CCTL, 0);
        put_hvalue(I2CSR, 0);

	/***********************************************************
	    Setup of I2C
	    I2CCTL_I2CMEN	I2C module is enabled.
	    I2CCTL_I2CMD	corresponds to Fast-mode(400kHz)
	    I2CBC_I2CBC		corresponds to HCLK=33MHz,I2CMD=400kHz
	***********************************************************/
	set_hbit(I2CCTL, I2CCTL_I2CMEN);
        set_hbit(I2CCTL, I2CCTL_400K);       /* set bit 0: 1 to 400k, 0 to 100k */
	put_hvalue(I2CBC, I2CBC_400K32);

	set_wbit(PORTSEL1, PORTSEL1_I2C);    /* selection of a secondary function */
	set_wbit(LSICNT, LSICNT_I2CNFON);    /* I2C noise filter available */
	
	/***********************************************************
	    Clear send_receive_buffer and err_status
	***********************************************************/
	for(i=0; i<BUFF_SIZE; i++)
	{
		I2C_SendData[i] = i;
		I2C_ReceivData[i] = I2C_END_PATTERN;
	}
	
	err_status = NO_ERR;
	return;
}

/******************************************************************/
/*  I2C Test for the AME_51 on-board temp sensor testing.         */
/*  Function : AME_51_Temp_Test (Master)                          */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void AME_51_Temp_Test(void)
{
    int i;

    set_hbit(I2CCTL, I2CCTL_I2CMTX);			/* Master sends data */
	
    while((get_hvalue(I2CSR)&I2CSR_I2CMBB) == I2CSR_I2CMBB);	/* Waiting for bus free */

    /* Slave address and W are set */
    put_hvalue(I2CDR, ((SLAVE_ADDRESS<<1)|WRITE_MODE)&0xFF);
    set_hbit(I2CCTL, I2CCTL_I2CMSTA);	/* start sequence */

    if((get_hvalue(I2CSR)&I2CSR_I2CMAL) == I2CSR_I2CMAL)
    {	/* Master received failure */
	err_status = BUS_ERR;
	led_pt = LED_3;			    /* turn on LED error */
	put_hvalue(I2CSR, 0);		    /* I2CSR register clear */
        return;
    }
    else
    {
	wait_for_send_receive();	    /* waiting for sending data */
    }

    if((get_hvalue(I2CSR)&I2CSR_I2CRXAK) == I2CSR_I2CRXAK)
    {	/* Master transmitting failure */
	err_status = ADDR_ACK_ERR;	    /* addres ACK error is set */
	led_pt = LED_2;			    /* turn on LED error */
	clr_hbit(I2CCTL, I2CCTL_I2CMSTA);   /* stop sequence */
	put_hvalue(I2CSR, 0);		    /* I2CSR register clear */
	return;
    }
	
    put_hvalue(I2CSR, 0);		    /* I2CSR register clear */

⌨️ 快捷键说明

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