打印
[Cortex-M0技术交流]

菜鸟学习菜农大叔助学板之第一帖IIC

[复制链接]
3611|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cecwxf|  楼主 | 2011-8-19 00:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
iic, I2c, vi, ST, TE
本帖最后由 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;
}

写IIC.jpg (69.12 KB )

写IIC.jpg

IIC.rar

924.69 KB

相关下载

相关帖子

沙发
cecwxf|  楼主 | 2011-8-19 00:17 | 只看该作者
第一个图是读 第二个图是写

使用特权

评论回复
板凳
cecwxf|  楼主 | 2011-8-19 00:22 | 只看该作者
抽空弄了下 很粗糙  现在老师又布置新任务了。 只能抽空弄弄这个 想开始LOOK

使用特权

评论回复
地板
hotpower| | 2011-8-19 08:42 | 只看该作者
应该把iic关键的读写代码再贴出来。
既然是参考,那么就要在关键读写代码里写自己详细的注解和认识。
甚至可以写参考原作者某些语句的不足之处,可圈之点。

使用特权

评论回复
5
Swallow_0322| | 2011-8-19 08:45 | 只看该作者
海涵? 有不妥的地方很望指教!

使用特权

评论回复
6
Swallow_0322| | 2011-8-19 08:49 | 只看该作者
第一帖就IIC,下一目标就LOOK,有前途!加油!:victory:

使用特权

评论回复
7
cecwxf|  楼主 | 2011-8-19 08:52 | 只看该作者
5# Swallow_0322 读的时候按查询方式  按照你那样写的。写的时候用中断。

使用特权

评论回复
8
cecwxf|  楼主 | 2011-8-19 08:53 | 只看该作者
4# hotpower 好的,谢谢大叔

使用特权

评论回复
9
wang0225| | 2011-8-19 08:53 | 只看该作者
大叔说的很好!:D

使用特权

评论回复
10
Swallow_0322| | 2011-8-19 09:03 | 只看该作者
7# cecwxf

IIC的中断方式:https://bbs.21ic.com/icview-232432-1-1.html
程序参考大叔的,思路更清晰更可靠,可参照下!

使用特权

评论回复
11
cecwxf|  楼主 | 2011-8-19 09:19 | 只看该作者
10# Swallow_0322 比我的清爽不少啊  思路更明晰

使用特权

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

本版积分规则

个人签名:充实灵魂,满足自己。做生活的强者,当时代的勇士!!!

2

主题

421

帖子

2

粉丝