打印
[新手园地]

HOT大叔NUC120助学板第九贴----I2C(中断方式)

[复制链接]
7653|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Swallow_0322 于 2011-4-26 17:07 编辑

     好久没有好好学习了,今天抽空来个IIC中断方式进行单字节或页读写AT24C16,完全参照HOT大叔IIC操作例程,有理解不当地方望大叔及各位高手不吝指教!因为是练习,所以所有的功能函数均在一个主文件内了。

源程序见二楼。


工程结构:


串口调试截图:



工程文件:
NUC120_HOT_I2C_Interrupt.rar (1.97 MB)

相关帖子

沙发
Swallow_0322|  楼主 | 2011-4-26 17:05 | 只看该作者
源程序:

/**************************************************
** 文件名称:NUC120_HOT_I2C_Interrupt.c
** 文件说明:NUC120助学板练习程序
** 创建日期:2011-04-26
** 修改日期:
** 备    注:I2C中断方式读写数据
**************************************************/
#include <stdio.h>
#include "NUC1xx.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSYS.h"
#include "Driver\DrvUART.h"
#include "Driver\DrvI2C.h"
uint8_t  Run_Led = 4;    //2----LED1  3----LED2   4----LED3  5----LED4
volatile uint8_t Receive_Data = 0;
volatile uint8_t IsStart = FALSE; //为1表示上位机发送指令正在执行 为0表示上位机发送指令处理完毕

typedef enum
{
I2C_START            = 0x08,
I2C_REP_START        = 0x10,
I2C_MT_SLA_ACK        = 0x18,
I2C_MT_SLA_NACK        = 0x20,
I2C_MT_DATA_ACK        = 0x28,
I2C_MT_DATA_NACK       = 0x30,
I2C_MT_ARB_LOST        = 0x38,
I2C_MR_ARB_LOST        = 0x38,
I2C_MR_SLA_ACK        = 0x40,
I2C_MR_SLA_NACK        = 0x48,
I2C_MR_DATA_ACK        = 0x50,
I2C_MR_DATA_NACK       = 0x58,
I2C_ST_SLA_ACK         = 0xA8,
I2C_ST_ARB_LOST_SLA_ACK   = 0xB0,
I2C_ST_DATA_ACK        = 0xB8,
I2C_ST_DATA_NACK       = 0xC0,
I2C_ST_LAST_DATA       = 0xC8,
I2C_SR_SLA_ACK        = 0x60,
I2C_SR_ARB_LOST_SLA_ACK   = 0x68,
I2C_SR_GCALL_ACK      = 0x70,
I2C_SR_ARB_LOST_GCALL_ACK = 0x78,
I2C_SR_DATA_ACK        = 0x80,
I2C_SR_DATA_NACK    = 0x88,
I2C_SR_GCALL_DATA_ACK   = 0x90,
I2C_SR_GCALL_DATA_NACK   = 0x98,
I2C_SR_STOP            = 0xA0,
I2C_NO_INFO            = 0xF8,
I2C_BUS_ERROR        = 0x00,
I2C_BUS_OK            = 0xFF
}NU_I2C_STATUS_ENUM;
typedef struct
{
unsigned char Busy;
unsigned int State;
unsigned int SystickCount;
unsigned int Count;
unsigned int MainCount, SubCount;
unsigned int SubAddr;
unsigned char MainComm, SubComm;
unsigned char TxBuffer[16], RxBuffer[16];
}I2C_HOT_T;
volatile I2C_HOT_T I2c;

/***************
**  函数声明  **
***************/
void Init_System (void);
void Init_Uart (void);
void Init_I2C(void);
void I2C_Start(void);
void I2C_REStart(void);
void I2C_Stop(void);
void I2C_Exit(void);
void UART_INT_HANDLE(uint32_t u32IntStatus);
void I2C1_INT_HANDLE (uint32_t status);

/*****************************
** Name:      UART_INT_HANDLE
** Function:  UART Callback function
** Input:     u32IntStatus
** OutPut:    None
** Data:      2011-03-17
** Note:      
****************************/
void UART_INT_HANDLE(uint32_t u32IntStatus)
{
  uint8_t bInChar[1]={0xFF};
if(u32IntStatus & DRVUART_RDAINT)
{
  /* Get all the input characters */
  while(UART0->ISR.RDA_IF==1)
  {
   /* Get the character from UART Buffer */
   DrvUART_Read(UART_PORT0,bInChar,1);
   if (IsStart!=TRUE)
   {
    IsStart = TRUE;
    Receive_Data = bInChar[0];
   }
  }
}
}
/*****************************
** Name:      I2C1_INT_HANDLE
** Function:  I2C1 Callback function
** Input:     status
** OutPut:    None
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
void I2C1_INT_HANDLE (uint32_t status)
{
switch(status & 0xf8)
{
     case I2C_START://主机收到自己发送的开始信号
      if (I2c.State == I2C_START) {//本次中断应该接收TW_START信号
    I2C1->DATA = I2c.SubAddr & 0xfe;//发送子机地址(写)
      DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //STA位必须清除,否则死机 清除中断标志
     I2c.State = I2C_MT_SLA_ACK;//Status下次I2C_MT_SLA_ACK
      }
      else I2C_Exit();//通讯失败
         break;
  case I2C_REP_START://主机收到自己发送的重新开始信号
      if (I2c.State == I2C_REP_START) {//本次中断应该接收TW_RESTART信号
          I2C1->DATA = I2c.SubAddr | 0x01;//发送子机地址(读)
        I2c.State = I2C_MR_SLA_ACK;//Status下次I2C_MR_SLA_ACK
     DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //STA位必须清除,否则死机 清除中断标志
      }
      else I2C_Exit();//通讯失败
         break;
  case I2C_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令
         if (I2c.State == I2C_MT_SLA_ACK) {//本次中断应该接收TW_MT_SLA_ACK信号
       I2c.State = I2C_MT_DATA_ACK;//Status下次应该收TW_MT_DATA_ACK
       I2C1->DATA = I2c.SubComm;//发送子机命令
     DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
      }
      else I2C_Exit();//通讯失败
         break;
  case I2C_MR_SLA_ACK://主收机接收到从机的地址应答信号
         if ((I2c.State == I2C_MR_SLA_ACK) && I2c.SubCount) {//本次中断应该接收TW_MR_SLA_ACK信号
        I2c.State = I2C_MR_DATA_ACK;//Status下次应该收TW_MR_DATA_ACK
     DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
      }
     else I2C_Exit();//通讯失败
      break;
  case I2C_MT_DATA_ACK://主收机接收到从机的数据应答信号
         if ((I2c.State == I2C_MT_DATA_ACK) && (I2c.Count < I2c.MainCount)) {//本次中断应该接收TW_MT_DATA_ACK信号
           I2C1->DATA = I2c.TxBuffer[I2c.Count ++];//发送子机数据
        DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
       }
      else {
          if ((I2c.State == I2C_MT_DATA_ACK) && (I2c.Count == I2c.MainCount) && (I2c.SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号
           I2C_REStart();//
     }
              else I2C_Stop();//通讯成功
      }
      break;
  case I2C_MR_DATA_ACK:
        if ((I2c.State == I2C_MR_DATA_ACK) && (I2c.Count < I2c.SubCount)) {
           I2c.RxBuffer[I2c.Count ++] = I2C1->DATA;//接收子机数据
     if (I2c.Count < I2c.SubCount) {
          DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
    }
    else {
        DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
        I2c.State = I2C_MR_DATA_NACK;//下次进入I2C_MR_DATA_NACK,接收数据准备完成
    }
      }
      else I2C_Exit();//通讯失败
     break;
  case I2C_MR_DATA_NACK://数据接收结束
        if ((I2c.State == I2C_MR_DATA_NACK) && (I2c.Count == I2c.SubCount)) {
       I2C_Stop();//通讯成功
     }
     else I2C_Exit();//通讯失败
     break;
// case I2C_MT_DATA_NACK:
//     Exit();//通讯失败
//     break;
default:
     I2C_Exit();//通讯失败
  }
}
/*****************************
** Name:      Init_System
** Function:  系统初始化函数
** Input:      None
** OutPut:     None
** Data:       2011-03-17
** Note:      
****************************/
void Init_System(void)
{
/* Unlock the locked registers before access */
    UNLOCKREG();  
/* Enable the 12MHz oscillator oscillation */
DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);     //SYSCLK->PWRCON.XTL12M_EN = 1;
/* Waiting for 12M Xtal stable */
DrvSYS_Delay(5000);
LOCKREG();
}
/*****************************
** Name:      Init_Uart
** Function:  UART初始化函数
** Input:      None
** OutPut:     None
** Data:       2011-03-17
** Note:      
****************************/
void Init_Uart(void)
{
STR_UART_T param;

DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0);      //使能UART时钟
//SYSCLK->CLKSEL1.UART_S = 0;  //UART时钟源选择. 00 =外部12MHz 晶振 01 = PLL 1x =内部 22MHz 振荡器
DrvGPIO_InitFunction(E_FUNC_UART0);          //GPB_MFP0-1-2-3置位 GPIO使能UART功能
param.u32BaudRate        = 115200;       //  波特率
param.u8cDataBits        = DRVUART_DATABITS_8;    //  数据位
param.u8cStopBits        = DRVUART_STOPBITS_1;    //  停止位
param.u8cParity          = DRVUART_PARITY_NONE;    //  校验位
param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;    //  FIFO存储深度 1 字节
param.u8TimeOut          = 0;        //  FIFO超时设定
/* Set UART Configuration */
  if(DrvUART_Open(UART_PORT0,&param) != E_SUCCESS)   //  串口开启、结构体整体赋值
  printf("UART0 open failed\n");      

DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);

}
/*****************************
** Name:      Init_I2C
** Function:  I2C初始化函数
** Input:      None
** OutPut:     None
** Data:       2011-04-26
** Note:       拷贝HOT大叔C++例程中IIC的操作   
****************************/
void Init_I2C(void)
{
/* Set I2C I/O */
DrvGPIO_InitFunction(E_FUNC_I2C1);
I2c.SubAddr = 0xA0;
}
/*****************************
** Name:      I2C_Start
** Function:  I2C启动函数
** Input:     None
** OutPut:    None
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
void I2C_Start(void)
{
I2c.Busy = TRUE;
   I2c.State = I2C_START;//主机准备发送启始位
   I2c.Count = 0;//发送数据个数
/* Open I2C1, and set clock = 50Kbps */
DrvI2C_Open(I2C_PORT1,50000);

/* 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_INT_HANDLE);

DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0);
DrvSYS_Delay(8000);
}
/*****************************
** Name:      I2C_REStart
** Function:  I2C重新启动函数
** Input:     None
** OutPut:    None
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
void I2C_REStart(void)
{
I2c.Busy = TRUE;
   I2c.State = I2C_REP_START;//主机准备发送启始位
   I2c.Count = 0;//发送数据个数
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0);
}
/*****************************
** Name:      I2C_Stop
** Function:  I2C停止函数
** Input:     None
** OutPut:    None
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
void I2C_Stop(void)
{
I2c.Busy= FALSE;
I2c.State = I2C_BUS_OK;//通讯成功
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
}
/*****************************
** Name:      I2C_Exit
** Function:  I2C退出函数
** Input:     None
** OutPut:    None
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
void I2C_Exit(void)
{
I2c.Busy = FALSE;
I2c.State = I2C_BUS_ERROR;//通讯失败
  DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
}
/*****************************
** Name:      I2C_ReadByte
** Function:  I2C写单字节函数
** Input:     unsigned int Address, unsigned char &Data
** OutPut:    I2c.State
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
unsigned char I2C_ReadByte(unsigned int Address, unsigned char *Data)
{
I2c.SubAddr |= 0x01;
I2c.MainCount = 0;//发送0个数据(只读)
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
I2c.SubComm = Address;//读出地址
I2c.SubCount = 1;//接收1个数据
I2C_Start();//启动I2C模块
if (I2c.State == I2C_BUS_OK) {//通讯成功
  Data[0] = I2c.RxBuffer[0];//从接收缓冲区取出一个字节
}
return I2c.State;//(读出数据在RxBuffer[0]~RxBuffer[15])
}
/*****************************
** Name:      I2C_ReadBuffer
** Function:  I2C写多字节函数
** Input:     unsigned int Address, unsigned char &Data,unsigned int Cnt
** OutPut:    I2c.State
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
unsigned char I2C_ReadBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
{
int i;
I2c.SubAddr |= 0x01;
I2c.MainCount = 0;//发送0个数据(只读)
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
I2c.SubComm = Address;//读出地址
I2c.SubCount = (Cnt <= sizeof(I2c.RxBuffer)) ? Cnt : sizeof(I2c.RxBuffer);//接收Cnt个数据
I2C_Start();//启动I2C模块
if (I2c.State == I2C_BUS_OK) {//通讯成功
  for (i = 0; i < I2c.SubCount; i ++) Data[i] = I2c.RxBuffer[i];//从接收缓冲区取出Cnt个字节
}
return I2c.State;//(读出数据在RxBuffer[0]~RxBuffer[15])
}
/*****************************
** Name:      I2C_WriteByte
** Function:  I2C读单字节函数
** Input:     unsigned int Address, unsigned char &Data
** OutPut:    I2c.State
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
unsigned char I2C_WriteByte(unsigned int Address, unsigned char Data)
{
I2c.SubAddr &= 0xfe;
I2c.MainCount = 1;//发送1个数据
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
I2c.SubComm = Address;//写入地址
I2c.TxBuffer[0] = Data;//写入1个数据到发送缓冲区
I2c.SubCount = 0;//接收0个数据
I2C_Start();//启动I2C模块
DrvSYS_Delay(100);
return I2c.State;
}
/*****************************
** Name:      I2C_WriteBuffer
** Function:  I2C写多字节函数
** Input:     unsigned int Address, unsigned char &Data,unsigned int Cnt
** OutPut:    I2c.State
** Data:      2011-04-26
** Note:      拷贝HOT大叔C++例程中IIC的操作
****************************/
unsigned char I2C_WriteBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
{
int i;
I2c.SubAddr &= 0xfe;
I2c.MainCount = (Cnt <= sizeof(I2c.TxBuffer)) ? Cnt : sizeof(I2c.TxBuffer);//发送Cnt个数据
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
I2c.SubComm = Address;//写入地址
for (i = 0; i < I2c.MainCount; i ++) I2c.TxBuffer[i] = Data[i];//写入Cnt个数据到发送缓冲区
I2c.SubCount = 0;//接收0个数据
I2C_Start();//启动I2C模块
DrvSYS_Delay(100);
return I2c.State;
}

int main (void)
{
uint8_t test = 250;
uint8_t EEPROM_Data = 0;  //IIC地址0x00读写数据
uint8_t I2C_Page_Test[16];  //IIC地址0x10页读写数据
uint8_t i = 0;  

Init_System();
Init_Uart();
Init_I2C();
DrvGPIO_Open(E_GPA,Run_Led, E_IO_OUTPUT);      //程序运行指示
DrvGPIO_ClrBit(E_GPA,Run_Led);
printf("\n");
printf("/*==========================\n");
printf("======菜农 %d 助学计划======\n",test);
printf("========NUC120助学板========\n");
printf("====程序参考新唐BSP库及HOT大叔例程====\n");
printf("=======2011年04月26日=======\n");
printf("========I2C(中断)实验=======\n");
printf("I2C中断方式完成对AT24C16的读写操作\n");
printf("'r'为读地址0x00单字节指令、'u'为地址0x00单字节加1并存储指令\n");
printf("'d'为地址0x00单字节减1并存储指令\n");
printf("'R'为读地址0x10开始单页指令、'u'为地址0x10开始单页加1并存储指令\n");
printf("'d'为地址0x10开始单页减1并存储指令\n");
printf("===========================/\n");
if(I2C_BUS_OK==(I2C_ReadByte(0x00,&EEPROM_Data)))
  printf("AT24C16地址0的内容为:0x%x!\n",EEPROM_Data);
else
  printf("AT24C16地址0的内容读取失败!\n");
if (I2C_BUS_OK==I2C_ReadBuffer(0x10,I2C_Page_Test,16))
{
  printf("AT24C16地址0x10开始16字节的内容为:\n");
  for (i=0;i<16;i++)
   printf("0x%x ",I2C_Page_Test[i]);
}
else
  printf("AT24C16地址0x10开始16字节的内容读取失败!\n");
printf("\n====请输入字符开始测试!===\n");
printf("==========================*/\n");
    while(1)
    {
        if (IsStart)
        {
         switch (Receive_Data)
         {
          case 'R':
     if (I2C_BUS_OK==I2C_ReadBuffer(0x10,I2C_Page_Test,16))
     {
      printf("\nAT24C16地址0x10开始16字节的内容为:\n");
      for (i=0;i<16;i++)
       printf("0x%x ",I2C_Page_Test[i]);
     }
     else
      printf("\nAT24C16地址0x10开始16字节的内容读取失败!");
     break;
    case 'r':
     if (I2C_BUS_OK==I2C_ReadByte(0x00,&EEPROM_Data))
      printf("\nAT24C16地址0的内容为:0x%x!",EEPROM_Data);
     else
      printf("\nAT24C16地址0的内容读取失败!");
     break;
    case 'U':
     for (i=0;i<16;i++)
      I2C_Page_Test[i]++;
     if (I2C_BUS_OK==I2C_WriteBuffer(0x10,I2C_Page_Test,16))
      printf("\nAT24C16地址0x10开始16字节的内容加1成功!");
     else
     {
      printf("\nAT24C16地址0x10开始16字节的内容加1失败!");
      for (i=0;i<16;i++)
       I2C_Page_Test[i]--;
     }
     break;
    case 'u':
     if (I2C_BUS_OK==I2C_WriteByte(0x00,++EEPROM_Data))
      printf("\nAT24C16地址0的内容加1成功!");
     else
      printf("\nAT24C16地址0的内容加1失败!");
     break;
    case 'D':
     for (i=0;i<16;i++)
      I2C_Page_Test[i]--;
     if (I2C_BUS_OK==I2C_WriteBuffer(0x10,I2C_Page_Test,16))
      printf("\nAT24C16地址0x10开始16字节的内容减1成功!");
     else
     {
      printf("\nAT24C16地址0x10开始16字节的内容减1失败!");
      for (i=0;i<16;i++)
       I2C_Page_Test[i]++;
     }
     break;
    case 'd':
     if (I2C_BUS_OK==I2C_WriteByte(0x00,--EEPROM_Data))
      printf("\nAT24C16地址0的内容减1成功!");
     else
      printf("\nAT24C16地址0的内容减1失败!");
     break;
    default:
     printf("\n请确认您输入的指令是否合法!");
   
         }
         IsStart = FALSE;
        }
    }
}


使用特权

评论回复
板凳
hotpower| | 2011-4-26 17:17 | 只看该作者
很好,这个中断方式与你以前的有什么不同?
请谈谈区别和各自的优点。

使用特权

评论回复
地板
Swallow_0322|  楼主 | 2011-4-26 19:43 | 只看该作者
呵呵!恕我菜鸟,理解浅薄,还望大叔多多教诲!
中断方式执行效率高一些,数据处理在中断中完成,而查询方式要一直等待I2C1->CON.SI的状态变化;
查询方式较中断方式感觉操作更直观些;
而大叔的I2C中断方式的不同之处是除了查询中断的状态码之外还增加I2c.State,双重确认,更加可靠!

使用特权

评论回复
5
hotpower| | 2011-4-26 23:12 | 只看该作者
这个程序套路在很多芯片上应用,从无败绩,效果甚佳。
它实际是一个一主多从的I2C主控模式的程序,可以操作任何I2C芯片。
它基于状态机的控制,每一步都严格遵守状态机的次序,出错立即咔嚓放弃。
特别适于I2C总线通讯,在收到数据处再加一个回调函数,就彻底为零耗时了。

使用特权

评论回复
6
tlb| | 2011-4-27 05:58 | 只看该作者
跟着大叔学习

使用特权

评论回复
7
hotpower| | 2011-4-27 09:37 | 只看该作者
大家一起学习,俺也是学了不久。

使用特权

评论回复
8
weshiluwei6| | 2011-4-27 19:01 | 只看该作者
支持下  学习了

使用特权

评论回复
9
tlb| | 2011-4-28 07:22 | 只看该作者
M0的学习气氛还是很好的
我要把握好这个机会狠狠的学习下M0

使用特权

评论回复
10
Swallow_0322|  楼主 | 2011-4-28 13:40 | 只看该作者
共同学习!:handshake

使用特权

评论回复
11
ShaoKn| | 2011-8-19 11:52 | 只看该作者
标记,找个时间好好学习学习

使用特权

评论回复
12
wang0225| | 2011-8-19 21:14 | 只看该作者
给力,学习啦:lol

使用特权

评论回复
13
zhaor| | 2011-11-4 08:22 | 只看该作者
源文件解压出现错误。
另外,我自己组织文件,编译的时候出现错误。
compiling NUC120_HOT_I2C_Interrupt.c...
User Files\NUC120_HOT_I2C_Interrupt.c(133): error:  #136: struct "<unnamed>" has no field "DATA"
User Files\NUC120_HOT_I2C_Interrupt.c(141): error:  #136: struct "<unnamed>" has no field "DATA"
User Files\NUC120_HOT_I2C_Interrupt.c(150): error:  #136: struct "<unnamed>" has no field "DATA"
User Files\NUC120_HOT_I2C_Interrupt.c(164): error:  #136: struct "<unnamed>" has no field "DATA"
User Files\NUC120_HOT_I2C_Interrupt.c(176): error:  #136: struct "<unnamed>" has no field "DATA"
楼主看到的时候,麻烦处理一下啊。谢谢了!

使用特权

评论回复
14
Swallow_0322|  楼主 | 2011-11-4 15:59 | 只看该作者
本帖最后由 Swallow_0322 于 2011-11-4 16:02 编辑

13# zhaor
上述错误是因为你使用的NUCxx.h和我的不是一个版本的,如果使用你的版本把原程序中的I2C1->DATA调整为I2C1->I2CDAT即可!


另外楼主位的压缩包我下载后解压没问题啊?如果需要可以QQ留言给我我发给你!

使用特权

评论回复
15
hotpower| | 2011-11-4 20:22 | 只看该作者
版本不同,即头文件不同,知道思想即可。

使用特权

评论回复
16
zibozhang| | 2012-2-28 11:20 | 只看该作者
我用这个例程怎么 读写数据不对啊 为什么

使用特权

评论回复
17
Swallow_0322|  楼主 | 2012-3-3 14:12 | 只看该作者
我用这个例程怎么 读写数据不对啊 为什么
zibozhang 发表于 2012-2-28 11:20


怎么验证的?
贴图!

使用特权

评论回复
18
timeismoney| | 2013-10-23 09:24 | 只看该作者
十分感谢!

使用特权

评论回复
19
ningtao66| | 2015-3-26 11:30 | 只看该作者
Swallow_0322 发表于 2011-4-26 19:43
呵呵!恕我菜鸟,理解浅薄,还望大叔多多教诲!
中断方式执行效率高一些,数据处理在中断中完成,而查询方 ...

查询方式要一直等待I2C1->CON.SI的状态变化

遇到过IIC连续读几个小时后,目标芯片未发送返回数据,程序始终停在这个语句,造成看门狗超时动作的问题。

使用特权

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

本版积分规则

121

主题

1393

帖子

4

粉丝