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