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 + -
显示快捷键?