i2c_sample_slave.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 249 行

C
249
字号
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2005 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML67Q4051/ML67Q4061 series                         */
/*     Module Name  :  ML67Q4051/ML67Q4061 i2c sample program (Slave)     */
/*     File   Name  :  i2c_sample_slave.c                                 */
/*     Revision     :  01.00                                              */
/*     Date         :  2005/02/15                                         */
/*                                                                        */
/**************************************************************************/
#include   "ml674061.h"
#include   "common.h"

/* constants */
#define I2C_LED_NORMAL	LED_NORMAL_END_PATTERN	/* OK pattern */
#define I2C_END_PATTERN	0xFF	/* data-end pattern */
#define BUFF_SIZE		16
#define WRITE_MODE		0x0
#define READ_MODE		0x1
#define SLAVE_ADDRESS	0x30
#define I2CCTL_100K		0x0
#define I2CCTL_400K		0x1
#define I2CBC_400K32	(0x0A)	/* HCLK=32MHz,I2CMD=400kHz */
#define PORTSEL1_I2C	0x5000000

/* functions */
int  main(void);						/* Main routine */
void init_i2c(void);					/* Initialize I2C */
void i2c_send_data(void);				/* I2C send process */
void i2c_receive_data(void);			/* I2C receive 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 */

/* global variables */
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 */

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 : main (Slave)                                       */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  0                                           */
/******************************************************************/
int main(void)
{
	int i;
	
	init_i2c();                 /* initialize i2c */
	init_led();                 /* initialize led */
	led_on(LED_START_PATTERN);  /* light led start pattern */
	
	led_pt = LED_NORMAL_END_PATTERN;
	
	for(i=0; i<2; i++)
	{
		while((get_hvalue(I2CSR)&I2CSR_I2CMAAS) != I2CSR_I2CMAAS)
			;	/* Slave address detect */
		
		if((get_hvalue(I2CSR)&I2CSR_I2CSRW)!=I2CSR_I2CSRW)
		{	/* receive mode */
			put_hvalue(I2CSR, 0);		/* I2CSR register clear */
			
			i2c_receive_data();
			if(err_status!=NO_ERR)
				break;
				
			if(cmp_data_fn(I2C_ReceivData, cmp_data, BUFF_SIZE)==NG)
			{	/* received data compare */
				err_status = DATA_CMP_ERR;
				led_pt = LED_4;	/* turn on LED error */
				break;
			}
		}
		else
		{	/* transmit mode */
			put_hvalue(I2CSR, 0);		/* I2CSR register clear */
			
			i2c_send_data();
			if(err_status!=NO_ERR)
				break;
		}
	}
	
	led_on(led_pt);             /* turn on lower square LED */
	return 0;
}

/******************************************************************/
/*  Initialize I2C                                                */
/*  Function : init_i2c (Slave)                                   */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_i2c(void)
{
	unsigned char  i;
	
	/***********************************************************
	    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);
	put_hvalue(I2CBC, I2CBC_400K32);
	
	put_hvalue(I2CSADR, SLAVE_ADDRESS<<1);	/* slave address is set */
	
	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-Data send                                                 */
/*  Function : i2c_send_data (Slave)                              */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void i2c_send_data(void)
{
	int i = 0;
	
	for(i=0; i<BUFF_SIZE; i++)
	{
		send_byte_data(I2C_SendData[i]);		/* 1 byte data transmit function */
		
		if((get_hvalue(I2CSR)&I2CSR_I2CRXAK) == I2CSR_I2CRXAK)
		{
			put_hvalue(I2CSR, 0);			/* I2CSR register clear */
			break;
		}
		
		clr_hbit(I2CSR, I2CSR_I2CMCF);		/* I2CMCF bit clear */
		
		while((get_hvalue(I2CSR)&I2CSR_I2CDR_LD) != I2CSR_I2CDR_LD)
			;	/* data loading is not available */
	}
	return;
}

/******************************************************************/
/*  I2C-Data receive                                              */
/*  Function : i2c_receive_data (Slave)                           */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void i2c_receive_data(void)
{
	int i = 0;
	
	while(1)
	{
		if((get_hvalue(I2CSR)&I2CSR_I2CMCF) != I2CSR_I2CMCF)
		{	/* Before data receiving or During data receiving */
			if((get_hvalue(I2CSR)&I2CSR_I2CSTP) == I2CSR_I2CSTP)
			{	/* Slave receiving finish  */
				put_hvalue(I2CSR, 0);			/* I2CSR register clear */
				break;
			}
		}
		else
		{	/* Finish of data receiving */
			I2C_ReceivData[i] = (UBYTE)(get_hvalue(I2CDR)&0xFF);	/* read data */
			put_hvalue(I2CSR, 0);				/* I2CSR register clear */
			i++;
		}
	}
	return;
}

/******************************************************************/
/*  I2C-Data send                                                 */
/*  Function : send_byte_data                                     */
/*      Parameters                                                */
/*          Input  :  send data                                   */
/*          Output :  Nothing                                     */
/******************************************************************/
void send_byte_data(UBYTE send_data)
{
	put_hvalue(I2CDR, send_data);	/* send data is set */
	wait_for_send_receive();		/* waiting for sending data */
	
	return;
}

/******************************************************************/
/*  I2C-Data send/receive                                         */
/*  Function : wait_for_send_receive                              */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void wait_for_send_receive(void)
{
	while((get_hvalue(I2CSR)&I2CSR_I2CMCF) != I2CSR_I2CMCF)
		;	/* During 1 byte data transmission */
	return;
}

/******************************************************************/
/*  Compare received data                                         */
/*  Function : cmp_data_fn                                        */
/*      Parameters                                                */
/*          Input  :  received data, compare data, data size      */
/*          Output :  OK/NG                                       */
/******************************************************************/
int cmp_data_fn(UBYTE *r_data, UBYTE *c_data, int n)
{
	UBYTE *rp = r_data;
	UBYTE *cp = c_data;
	
	for( ; 0<n; ++rp, ++cp, --n)
		if(*rp != *cp)
			return NG;
	return OK;
}

⌨️ 快捷键说明

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