打印
[新手园地]

ddllxxrr笔记七 向AT24C16写一字节

[复制链接]
3081|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AT24C16有它的器件地址。得严格按照IIC的通讯协议来读写。我要说的是新唐的IIC比较易用,只要设好通讯数率,然后就盯着一个寄存器的一个比特就行.

      这就是控制寄存器 (I2CON)

      CPU可以读写这个8位寄存器,其中2位受硬件影响:SI位在I2C硬件请求中断时置位,STO位在总线出现STOP条件时被清零,当ENS1="0"时STO位也被清零
EI 使能中断

ENSI 使能I2C功能模块。当ENSI=1时I2C功能使能,SDA1和SCL1口必须被设为逻辑高
STA I2C 开始标志,设置STA=1进入主模式,当总线空闲时I2C硬件发送一个START或重复START条件到总线上

STO I2C 停止标志,在主模式中设置STO可以发送STOP条件到总线上,I2C硬件将检测总线,如果一个STOP条件被检测到,STO位被硬件自动清零。在从模式中,设置STO可以复位I2C硬件为“未赋址"从模式,也就是已经不在从接收模式,不会再接收主发送设备的数据

SI I2C 中断标志,当新的SIO状态出现在I2STATUS寄存器中,SI标志被硬件置位,如果EA和EI 2位都被置位,将会产生I2C中断请求。SI位必须被软件写“1"清零。

AA 应答产生控制位,当AA=1时,在地址或数据接收之前,应答位(SDA低电平)将在如下两种情况的应答时钟脉冲周期被返回:1)从机应答主机发送的地址,2)接收设备应答发送设备的数据。当AA=0时,在地址或数据接收之前,无应答位(SDA高电平)将在SCL线应答时钟脉冲周期被返回

只要盯住SI位就行。因为NUV120的IIC收发都是清它的位,收到后清它,发完后也清它。

比如:写一个字节,就判断SI位就大功告成了。

void Write_24LC64(uint32_t address,uint8_t data )
{
uint32_t u32HCLK,i;
u32HCLK = DrvSYS_GetHCLKFreq() * 1000;
  //Open I2C1 and set clock = 50Kbps
DrvI2C_Open(I2C_PORT1,50000);

    //send i2c start
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0); //set start
while (I2C1->CON.SI == 0);   //poll si flag
//send writer command
I2C1->DATA = 0XA0;     //send writer command
    DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //clr si flag
    while( I2C1->CON.SI == 0 );      //poll si flag
//send address high
I2C1->DATA = (address>>8)&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
//send address low
I2C1->DATA = address&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
//send data
I2C1->DATA = data;     //write data to
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
    //send i2c stop
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //send stop
//while( I2C1->CON.SI == 0 );
for(i=0;i<60;i++);
DrvI2C_Close(I2C_PORT1);
   
for(i=0;i<6000;i++);
for(i=0;i<6000;i++);
}

下边说我的这个IIC测试程序。非常简单就是把一个字节数0x55,往指定位置写。然后读出若对了,串口输出来。

先上效果图:



再上程序:

#include <stdio.h>
#include "NUC1xx.h"
#include "..\Driver\DrvGPIO.h"
#include "..\Driver\DrvI2C.h"
#include "..\Driver\DrvSYS.h"
#include "..\Driver\DrvUART.h"
void Write_24LC64(uint32_t address,uint8_t data )
{
uint32_t u32HCLK,i;
u32HCLK = DrvSYS_GetHCLKFreq() * 1000;
  //Open I2C1 and set clock = 50Kbps
DrvI2C_Open(I2C_PORT1,50000);

    //send i2c start
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0); //set start
while (I2C1->CON.SI == 0);   //poll si flag
//send writer command
I2C1->DATA = 0XA0;     //send writer command
    DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //clr si flag
    while( I2C1->CON.SI == 0 );      //poll si flag
//send address high
I2C1->DATA = (address>>8)&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
//send address low
I2C1->DATA = address&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
//send data
I2C1->DATA = data;     //write data to
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->CON.SI == 0 );   //poll si flag
    //send i2c stop
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //send stop
//while( I2C1->CON.SI == 0 );
for(i=0;i<60;i++);
DrvI2C_Close(I2C_PORT1);
   
for(i=0;i<6000;i++);
for(i=0;i<6000;i++);
}
uint8_t Read_24LC64(uint32_t address)
{
uint8_t TEMP;
uint32_t u32HCLK;
  //Open I2C1 and set clock = 50Kbps
   u32HCLK = DrvSYS_GetHCLKFreq() * 1000;
DrvI2C_Open(I2C_PORT1,50000);
//send i2c start
    DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0);   //set start
while (I2C1->CON.SI == 0);    //poll si flag
  
    //send writer command
I2C1->DATA = 0XA0;
    DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);    //clr si
    while( I2C1->CON.SI == 0 );      //poll si flag

//send address high
    I2C1->DATA = (address>>8)&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);    //clr si and set ack
while( I2C1->CON.SI == 0 );      //poll si flag
   
//send address low
I2C1->DATA = address&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);    //clr si and set ack
while( I2C1->CON.SI == 0 );      //poll si flag

//send start flag
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0);    //clr si and send start
while( I2C1->CON.SI == 0 );      //poll si flag

//send read command
I2C1->DATA = 0XA1;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);    //clr si
    while( I2C1->CON.SI == 0 );      //poll si flag
//resive data
I2C1->DATA = 0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);    //clr si
while( I2C1->CON.SI == 0 );      //poll si flag
TEMP= I2C1->DATA;
//send i2c stop
  DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);    //clr si and set stop
DrvI2C_Close(I2C_PORT1);
return TEMP;
}


/*---------------------------------------------------------------------------------------------------------*/
/*MAIN Function*/
/*---------------------------------------------------------------------------------------------------------*/
int main (void)
{
uint8_t ddllxxrr;
uint32_t u32HCLK;
STR_UART_T sParam;
/* SYSCLK =>12Mhz*/
UNLOCKREG();
SYSCLK->;PWRCON.XTL12M_EN = 1;
u32HCLK = DrvSYS_GetHCLKFreq() * 1000;
/*
SET UART0
*/
    /* Set UART0 Pin */
    DrvGPIO_InitFunction(E_FUNC_UART0);
    /* UART Setting */
    sParam.u32BaudRate   = 9600;
    sParam.u8cDataBits   = DRVUART_DATABITS_8;
    sParam.u8cStopBits   = DRVUART_STOPBITS_1;
    sParam.u8cParity   = DRVUART_PARITY_NONE;
    sParam.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES;
    /* Select UART Clock Source From 12Mhz*/
    DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0);
    /* Set UART0 Configuration */
    DrvUART_Open(UART_PORT0, &sParam);
/* Set I2C I/O */
DrvGPIO_InitFunction(E_FUNC_I2C1);
/* Open I2C0 and set clock = 100Kbps */
DrvI2C_Open(I2C_PORT1,50000);
Write_24LC64(0x00000001,0x55);
ddllxxrr= Read_24LC64(0x00000001);
if(ddllxxrr==0x55)
{
printf("the read bites is :%d\n",ddllxxrr);
}
while(1);
}

最后上工程文件:

NUCtesttestI2C.rar (1.32 MB)

相关帖子

沙发
hotpower| | 2011-9-20 16:18 | 只看该作者
最好用code模式

使用特权

评论回复
板凳
ddllxxrr|  楼主 | 2011-9-20 19:52 | 只看该作者
code模式????

使用特权

评论回复
地板
Ryanhsiung| | 2011-12-4 16:31 | 只看该作者
本帖最后由 Ryanhsiung 于 2011-12-4 16:37 编辑

code不适用于可编程的I2C模式!
  还是这种比较好,可以任意组织,我的SMBUS代码还没完成,完成后在贴出!
  对了LZ与lixiaoxu2meng的I2C:的代码还没有考虑到超时!若总线GAMEOVER 你们俩的代码会卡死

使用特权

评论回复
5
Ryanhsiung| | 2011-12-4 16:35 | 只看该作者
CODE方式占用系统时间少,若为标准的I2C建议采用!

使用特权

评论回复
6
mcs8098| | 2011-12-20 12:42 | 只看该作者
COOL

使用特权

评论回复
7
ichuangj| | 2011-12-21 12:10 | 只看该作者
:lol可用!

使用特权

评论回复
8
kyzb001| | 2011-12-21 13:47 | 只看该作者
[code]
代码
[code]

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6949

帖子

66

粉丝