本帖最后由 cecwxf 于 2011-8-19 08:50 编辑
NUC120RE3AN操作AT24C16。写用中断、读用查询。串口指定从机地址、EEPROM地址来写入数据和读取数据。参考了三心的IIC和板子的例程,小弟是菜鸟,大家轻拍。
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
/*---------------------------------------------------------------------------------------------------------*/
/******************************************************************************
文件名: NUC120_AT24C16.c
说 明: 本文件为“NUC120RE3AN用IIC总线主机模式读写AT24C16的主函数。
操作说明: (1) 写数据格式:|35| | 从机地址(此处为A0)| |EEPROM地址| |要写入地址的数据| |02| 共5个字节,16进制发送
(2) 读数据格式:|36| | 从机地址(此处为A0)| |EEPROM地址| |02| |02| 共5个字节,16进制发送
UART的波特率为115200
申明: 本程序参考三心的IIC程序和例程,写数据用IIC中断,读数据用查询的方式。请原作者海涵。
开 始: 2011.8.19
修 改: V1.0
******************************************************************************/
#include <stdio.h>
#include "Driver\DrvGPIO.h"
#include "Driver\DrvI2C.h"
#include "Driver\DrvSYS.h"
#include "Driver\DrvUART.h"
#include "global.h"
int main()
{
SYSTEM_Config();
UART_Config();
GPIO_Config();
AT24C16_Config();
printf("+-----------------------------------------------------------+\n");
printf("| 菜鸟学习菜农大叔助学板之IIC |\n");
printf("| IIC写用中断、读用查询。参考三心的例子和BSP例程 |\n");
printf("+-----------------------------------------------------------+\n");
printf(" I/O Configuration:\n");
printf(" GPA8 <--> GPA10\n");
printf(" GPA9 <--> GPA11\n");
printf("\n");
while(1)
{
if(IIC_Start_Flag==TRUE)
{ IIC_Start_Flag =FALSE;
switch(UART_Buffer_Rx[0])
{
case 0x35:
printf("开始写数据到AT24C16\n");
AT24C16_Func_Write();
printf("已将数据写入AT24C16\n");
break;
case 0x36:
UART_Buffer_Tx[0]=UART_Buffer_Rx[1];
UART_Buffer_Tx[1]=UART_Buffer_Rx[2];
UART_Buffer_Tx[2]=AT24C16_Func_Read(UART_Buffer_Rx[2]);
printf("读取从机地址为:0x%x!\n",UART_Buffer_Tx[0]);
printf("EEPROM地址为:0x%x!\n",UART_Buffer_Tx[1]);
printf("地址中的内容为:0x%x!\n",UART_Buffer_Tx[2]);
break;
}
}
}
}
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvSYS.h"
#include "DrvI2C.h"
extern unsigned int Device_Addr0;
extern unsigned int Tx_Data0[3];
extern unsigned int DataLen0;
extern volatile unsigned int EndFlag0;
extern unsigned int u32data;
extern unsigned int UART_Buffer_Rx[4];
/*此处为IIC中断函数调用的回调函数,开启IIC中断,在进入每一个状态之后都会有SI置位*/
void I2C1_Callback_Tx(uint32_t status)
{
if (status == 0x08) /* START has been transmitted */
{
DrvI2C_WriteData(I2C_PORT1, Device_Addr0);
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
printf("Status 0x%x is processed\n", status);
}
else if (status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
DrvI2C_WriteData(I2C_PORT1, Tx_Data0[DataLen0++]);
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
printf("Status 0x%x is processed\n", status);
}
else if (status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
DrvI2C_Ctrl(I2C_PORT1, 1, 1, 1, 0);
printf("Status 0x%x is processed\n", status);
}
else if (status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if (DataLen0 != 3)
{
DrvI2C_WriteData(I2C_PORT1, Tx_Data0[DataLen0++]);
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
printf("Status 0x%x is processed\n", status);
}
else
{
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
EndFlag0 = 1;
printf("Status 0x%x is processed\n", status);
}
}
else
{
printf("Status 0x%x is NOT processed\n", status);
;
}
}
void AT24C16_Config()
{
DrvI2C_Open(I2C_PORT1, 50000);
u32data = DrvI2C_GetClockFreq(I2C_PORT1);
printf("I2C1的时钟为: %d Hz\n", u32data);
/*设置I2C0的从地址*/
DrvI2C_SetAddress(I2C_PORT1, 0, 0xA0, 0);
/* Enable I2C1 interrupt and set corresponding NVIC bit */
DrvI2C_EnableInt(I2C_PORT1);
/* Install I2C1 call back function for slave */
DrvI2C_InstallCallback(I2C_PORT1, I2CFUNC, I2C1_Callback_Tx);
DrvI2C_Open(I2C_PORT1, 50000);
DataLen0 = 0;
EndFlag0 = 0;
}
void AT24C16_Func_Write()
{
DrvI2C_Open(I2C_PORT1, 50000);
DrvI2C_EnableInt(I2C_PORT1);
/*回调函数和IIC_ISR挂钩*/
DrvI2C_InstallCallback(I2C_PORT1, I2CFUNC, I2C1_Callback_Tx);
/*器件的地址*/
Device_Addr0 = UART_Buffer_Rx[1];
/*EEPROM的地址*/
Tx_Data0[0] = UART_Buffer_Rx[2];
/*要写入的数据*/
Tx_Data0[1] = UART_Buffer_Rx[3];
/* I2C0 as master sends START signal */
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0);
/* Wait I2C1 Tx Finish */
while (EndFlag0 == 0);
EndFlag0 = 0;
printf("IIC写测试成功\n");
/* Disable I2C0 interrupt and clear corresponding NVIC bit */
DrvI2C_DisableInt(I2C_PORT1);
DrvI2C_Close(I2C_PORT1);
}
/*此段代码取自三心的IIC读查询例程,请作者海涵 因为我感觉这样写就很好啦 呵呵*/
uint8_t AT24C16_Func_Read(uint32_t address)
{
uint8_t TEMP;
DrvI2C_Open(I2C_PORT1, 50000);
DrvI2C_UninstallCallBack(I2C_PORT1, I2CFUNC);
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0); //设定I2C控制比特 START并清中断标志
while (I2C1->CON.SI == 0); //查询中断标志位 SI
I2C1->DATA = 0XA0; //发送写命令
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //清标志位 SI
while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
I2C1->DATA = address&0xFF; //发送地址
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //清标志位 SI 并使能应答
while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0); //设定I2C控制比特 START并清中断标志
while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
I2C1->DATA = 0XA1; //发送读命令
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //清标志位 SI 并使能应答
while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
//I2C1->DATA = 0xFF; //通过操作数据寄存器配合控制位的设置启动一次新的I2C操作(此句加与不加未影响到结果)
/*"Software should load the data byte (to be transmitted)into I2DAT before new I2CON setting is done." 手册中该句怎么解释?*/
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //清标志位 SI
while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
TEMP= I2C1->DATA; //读数据
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //清标志位 SI 并STOP
DrvI2C_Close(I2C_PORT1);
return TEMP;
}
|