[新手园地] HOT大叔NUC120助学板第九贴----I2C(中断方式)

[复制链接]
 楼主| Swallow_0322 发表于 2011-4-26 16:59 | 显示全部楼层 |阅读模式
本帖最后由 Swallow_0322 于 2011-4-26 17:07 编辑

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

源程序见二楼。


工程结构:


串口调试截图:



工程文件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| Swallow_0322 发表于 2011-4-26 17:05 | 显示全部楼层
源程序:

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

  17. typedef enum
  18. {
  19. I2C_START            = 0x08,
  20. I2C_REP_START        = 0x10,
  21. I2C_MT_SLA_ACK        = 0x18,
  22. I2C_MT_SLA_NACK        = 0x20,
  23. I2C_MT_DATA_ACK        = 0x28,
  24. I2C_MT_DATA_NACK       = 0x30,
  25. I2C_MT_ARB_LOST        = 0x38,
  26. I2C_MR_ARB_LOST        = 0x38,
  27. I2C_MR_SLA_ACK        = 0x40,
  28. I2C_MR_SLA_NACK        = 0x48,
  29. I2C_MR_DATA_ACK        = 0x50,
  30. I2C_MR_DATA_NACK       = 0x58,
  31. I2C_ST_SLA_ACK         = 0xA8,
  32. I2C_ST_ARB_LOST_SLA_ACK   = 0xB0,
  33. I2C_ST_DATA_ACK        = 0xB8,
  34. I2C_ST_DATA_NACK       = 0xC0,
  35. I2C_ST_LAST_DATA       = 0xC8,
  36. I2C_SR_SLA_ACK        = 0x60,
  37. I2C_SR_ARB_LOST_SLA_ACK   = 0x68,
  38. I2C_SR_GCALL_ACK      = 0x70,
  39. I2C_SR_ARB_LOST_GCALL_ACK = 0x78,
  40. I2C_SR_DATA_ACK        = 0x80,
  41. I2C_SR_DATA_NACK    = 0x88,
  42. I2C_SR_GCALL_DATA_ACK   = 0x90,
  43. I2C_SR_GCALL_DATA_NACK   = 0x98,
  44. I2C_SR_STOP            = 0xA0,
  45. I2C_NO_INFO            = 0xF8,
  46. I2C_BUS_ERROR        = 0x00,
  47. I2C_BUS_OK            = 0xFF
  48. }NU_I2C_STATUS_ENUM;
  49. typedef struct
  50. {
  51. unsigned char Busy;
  52. unsigned int State;
  53. unsigned int SystickCount;
  54. unsigned int Count;
  55. unsigned int MainCount, SubCount;
  56. unsigned int SubAddr;
  57. unsigned char MainComm, SubComm;
  58. unsigned char TxBuffer[16], RxBuffer[16];
  59. }I2C_HOT_T;
  60. volatile I2C_HOT_T I2c;

  61. /***************
  62. **  函数声明  **
  63. ***************/
  64. void Init_System (void);
  65. void Init_Uart (void);
  66. void Init_I2C(void);
  67. void I2C_Start(void);
  68. void I2C_REStart(void);
  69. void I2C_Stop(void);
  70. void I2C_Exit(void);
  71. void UART_INT_HANDLE(uint32_t u32IntStatus);
  72. void I2C1_INT_HANDLE (uint32_t status);

  73. /*****************************
  74. ** Name:      UART_INT_HANDLE
  75. ** Function:  UART Callback function
  76. ** Input:     u32IntStatus
  77. ** OutPut:    None
  78. ** Data:      2011-03-17
  79. ** Note:      
  80. ****************************/
  81. void UART_INT_HANDLE(uint32_t u32IntStatus)
  82. {
  83.   uint8_t bInChar[1]={0xFF};
  84. if(u32IntStatus & DRVUART_RDAINT)
  85. {
  86.   /* Get all the input characters */
  87.   while(UART0->ISR.RDA_IF==1)
  88.   {
  89.    /* Get the character from UART Buffer */
  90.    DrvUART_Read(UART_PORT0,bInChar,1);
  91.    if (IsStart!=TRUE)
  92.    {
  93.     IsStart = TRUE;
  94.     Receive_Data = bInChar[0];
  95.    }
  96.   }
  97. }
  98. }
  99. /*****************************
  100. ** Name:      I2C1_INT_HANDLE
  101. ** Function:  I2C1 Callback function
  102. ** Input:     status
  103. ** OutPut:    None
  104. ** Data:      2011-04-26
  105. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  106. ****************************/
  107. void I2C1_INT_HANDLE (uint32_t status)
  108. {
  109. switch(status & 0xf8)
  110. {
  111.      case I2C_START://主机收到自己发送的开始信号
  112.       if (I2c.State == I2C_START) {//本次中断应该接收TW_START信号
  113.     I2C1->DATA = I2c.SubAddr & 0xfe;//发送子机地址(写)
  114.       DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //STA位必须清除,否则死机 清除中断标志
  115.      I2c.State = I2C_MT_SLA_ACK;//Status下次I2C_MT_SLA_ACK
  116.       }
  117.       else I2C_Exit();//通讯失败
  118.          break;
  119.   case I2C_REP_START://主机收到自己发送的重新开始信号
  120.       if (I2c.State == I2C_REP_START) {//本次中断应该接收TW_RESTART信号
  121.           I2C1->DATA = I2c.SubAddr | 0x01;//发送子机地址(读)
  122.         I2c.State = I2C_MR_SLA_ACK;//Status下次I2C_MR_SLA_ACK
  123.      DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //STA位必须清除,否则死机 清除中断标志
  124.       }
  125.       else I2C_Exit();//通讯失败
  126.          break;
  127.   case I2C_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令
  128.          if (I2c.State == I2C_MT_SLA_ACK) {//本次中断应该接收TW_MT_SLA_ACK信号
  129.        I2c.State = I2C_MT_DATA_ACK;//Status下次应该收TW_MT_DATA_ACK
  130.        I2C1->DATA = I2c.SubComm;//发送子机命令
  131.      DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
  132.       }
  133.       else I2C_Exit();//通讯失败
  134.          break;
  135.   case I2C_MR_SLA_ACK://主收机接收到从机的地址应答信号
  136.          if ((I2c.State == I2C_MR_SLA_ACK) && I2c.SubCount) {//本次中断应该接收TW_MR_SLA_ACK信号
  137.         I2c.State = I2C_MR_DATA_ACK;//Status下次应该收TW_MR_DATA_ACK
  138.      DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
  139.       }
  140.      else I2C_Exit();//通讯失败
  141.       break;
  142.   case I2C_MT_DATA_ACK://主收机接收到从机的数据应答信号
  143.          if ((I2c.State == I2C_MT_DATA_ACK) && (I2c.Count < I2c.MainCount)) {//本次中断应该接收TW_MT_DATA_ACK信号
  144.            I2C1->DATA = I2c.TxBuffer[I2c.Count ++];//发送子机数据
  145.         DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
  146.        }
  147.       else {
  148.           if ((I2c.State == I2C_MT_DATA_ACK) && (I2c.Count == I2c.MainCount) && (I2c.SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号
  149.            I2C_REStart();//
  150.      }
  151.               else I2C_Stop();//通讯成功
  152.       }
  153.       break;
  154.   case I2C_MR_DATA_ACK:
  155.         if ((I2c.State == I2C_MR_DATA_ACK) && (I2c.Count < I2c.SubCount)) {
  156.            I2c.RxBuffer[I2c.Count ++] = I2C1->DATA;//接收子机数据
  157.      if (I2c.Count < I2c.SubCount) {
  158.           DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
  159.     }
  160.     else {
  161.         DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
  162.         I2c.State = I2C_MR_DATA_NACK;//下次进入I2C_MR_DATA_NACK,接收数据准备完成
  163.     }
  164.       }
  165.       else I2C_Exit();//通讯失败
  166.      break;
  167.   case I2C_MR_DATA_NACK://数据接收结束
  168.         if ((I2c.State == I2C_MR_DATA_NACK) && (I2c.Count == I2c.SubCount)) {
  169.        I2C_Stop();//通讯成功
  170.      }
  171.      else I2C_Exit();//通讯失败
  172.      break;
  173. // case I2C_MT_DATA_NACK:
  174. //     Exit();//通讯失败
  175. //     break;
  176. default:
  177.      I2C_Exit();//通讯失败
  178.   }
  179. }
  180. /*****************************
  181. ** Name:      Init_System
  182. ** Function:  系统初始化函数
  183. ** Input:      None
  184. ** OutPut:     None
  185. ** Data:       2011-03-17
  186. ** Note:      
  187. ****************************/
  188. void Init_System(void)
  189. {
  190. /* Unlock the locked registers before access */
  191.     UNLOCKREG();  
  192. /* Enable the 12MHz oscillator oscillation */
  193. DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);     //SYSCLK->PWRCON.XTL12M_EN = 1;
  194. /* Waiting for 12M Xtal stable */
  195. DrvSYS_Delay(5000);
  196. LOCKREG();
  197. }
  198. /*****************************
  199. ** Name:      Init_Uart
  200. ** Function:  UART初始化函数
  201. ** Input:      None
  202. ** OutPut:     None
  203. ** Data:       2011-03-17
  204. ** Note:      
  205. ****************************/
  206. void Init_Uart(void)
  207. {
  208. STR_UART_T param;

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

  221. DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);

  222. }
  223. /*****************************
  224. ** Name:      Init_I2C
  225. ** Function:  I2C初始化函数
  226. ** Input:      None
  227. ** OutPut:     None
  228. ** Data:       2011-04-26
  229. ** Note:       拷贝HOT大叔C++例程中IIC的操作   
  230. ****************************/
  231. void Init_I2C(void)
  232. {
  233. /* Set I2C I/O */
  234. DrvGPIO_InitFunction(E_FUNC_I2C1);
  235. I2c.SubAddr = 0xA0;
  236. }
  237. /*****************************
  238. ** Name:      I2C_Start
  239. ** Function:  I2C启动函数
  240. ** Input:     None
  241. ** OutPut:    None
  242. ** Data:      2011-04-26
  243. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  244. ****************************/
  245. void I2C_Start(void)
  246. {
  247. I2c.Busy = TRUE;
  248.    I2c.State = I2C_START;//主机准备发送启始位
  249.    I2c.Count = 0;//发送数据个数
  250. /* Open I2C1, and set clock = 50Kbps */
  251. DrvI2C_Open(I2C_PORT1,50000);

  252. /* Enable I2C1 interrupt and set corresponding NVIC bit */
  253. DrvI2C_EnableInt(I2C_PORT1);
  254.    
  255. /* Install I2C1 call back function for slave */
  256. DrvI2C_InstallCallback(I2C_PORT1, I2CFUNC, I2C1_INT_HANDLE);

  257. DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0);
  258. DrvSYS_Delay(8000);
  259. }
  260. /*****************************
  261. ** Name:      I2C_REStart
  262. ** Function:  I2C重新启动函数
  263. ** Input:     None
  264. ** OutPut:    None
  265. ** Data:      2011-04-26
  266. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  267. ****************************/
  268. void I2C_REStart(void)
  269. {
  270. I2c.Busy = TRUE;
  271.    I2c.State = I2C_REP_START;//主机准备发送启始位
  272.    I2c.Count = 0;//发送数据个数
  273. DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0);
  274. }
  275. /*****************************
  276. ** Name:      I2C_Stop
  277. ** Function:  I2C停止函数
  278. ** Input:     None
  279. ** OutPut:    None
  280. ** Data:      2011-04-26
  281. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  282. ****************************/
  283. void I2C_Stop(void)
  284. {
  285. I2c.Busy= FALSE;
  286. I2c.State = I2C_BUS_OK;//通讯成功
  287. DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
  288. }
  289. /*****************************
  290. ** Name:      I2C_Exit
  291. ** Function:  I2C退出函数
  292. ** Input:     None
  293. ** OutPut:    None
  294. ** Data:      2011-04-26
  295. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  296. ****************************/
  297. void I2C_Exit(void)
  298. {
  299. I2c.Busy = FALSE;
  300. I2c.State = I2C_BUS_ERROR;//通讯失败
  301.   DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
  302. }
  303. /*****************************
  304. ** Name:      I2C_ReadByte
  305. ** Function:  I2C写单字节函数
  306. ** Input:     unsigned int Address, unsigned char &Data
  307. ** OutPut:    I2c.State
  308. ** Data:      2011-04-26
  309. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  310. ****************************/
  311. unsigned char I2C_ReadByte(unsigned int Address, unsigned char *Data)
  312. {
  313. I2c.SubAddr |= 0x01;
  314. I2c.MainCount = 0;//发送0个数据(只读)
  315. //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
  316. I2c.SubComm = Address;//读出地址
  317. I2c.SubCount = 1;//接收1个数据
  318. I2C_Start();//启动I2C模块
  319. if (I2c.State == I2C_BUS_OK) {//通讯成功
  320.   Data[0] = I2c.RxBuffer[0];//从接收缓冲区取出一个字节
  321. }
  322. return I2c.State;//(读出数据在RxBuffer[0]~RxBuffer[15])
  323. }
  324. /*****************************
  325. ** Name:      I2C_ReadBuffer
  326. ** Function:  I2C写多字节函数
  327. ** Input:     unsigned int Address, unsigned char &Data,unsigned int Cnt
  328. ** OutPut:    I2c.State
  329. ** Data:      2011-04-26
  330. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  331. ****************************/
  332. unsigned char I2C_ReadBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
  333. {
  334. int i;
  335. I2c.SubAddr |= 0x01;
  336. I2c.MainCount = 0;//发送0个数据(只读)
  337. //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
  338. I2c.SubComm = Address;//读出地址
  339. I2c.SubCount = (Cnt <= sizeof(I2c.RxBuffer)) ? Cnt : sizeof(I2c.RxBuffer);//接收Cnt个数据
  340. I2C_Start();//启动I2C模块
  341. if (I2c.State == I2C_BUS_OK) {//通讯成功
  342.   for (i = 0; i < I2c.SubCount; i ++) Data[i] = I2c.RxBuffer[i];//从接收缓冲区取出Cnt个字节
  343. }
  344. return I2c.State;//(读出数据在RxBuffer[0]~RxBuffer[15])
  345. }
  346. /*****************************
  347. ** Name:      I2C_WriteByte
  348. ** Function:  I2C读单字节函数
  349. ** Input:     unsigned int Address, unsigned char &Data
  350. ** OutPut:    I2c.State
  351. ** Data:      2011-04-26
  352. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  353. ****************************/
  354. unsigned char I2C_WriteByte(unsigned int Address, unsigned char Data)
  355. {
  356. I2c.SubAddr &= 0xfe;
  357. I2c.MainCount = 1;//发送1个数据
  358. //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
  359. I2c.SubComm = Address;//写入地址
  360. I2c.TxBuffer[0] = Data;//写入1个数据到发送缓冲区
  361. I2c.SubCount = 0;//接收0个数据
  362. I2C_Start();//启动I2C模块
  363. DrvSYS_Delay(100);
  364. return I2c.State;
  365. }
  366. /*****************************
  367. ** Name:      I2C_WriteBuffer
  368. ** Function:  I2C写多字节函数
  369. ** Input:     unsigned int Address, unsigned char &Data,unsigned int Cnt
  370. ** OutPut:    I2c.State
  371. ** Data:      2011-04-26
  372. ** Note:      拷贝HOT大叔C++例程中IIC的操作
  373. ****************************/
  374. unsigned char I2C_WriteBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
  375. {
  376. int i;
  377. I2c.SubAddr &= 0xfe;
  378. I2c.MainCount = (Cnt <= sizeof(I2c.TxBuffer)) ? Cnt : sizeof(I2c.TxBuffer);//发送Cnt个数据
  379. //本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
  380. I2c.SubComm = Address;//写入地址
  381. for (i = 0; i < I2c.MainCount; i ++) I2c.TxBuffer[i] = Data[i];//写入Cnt个数据到发送缓冲区
  382. I2c.SubCount = 0;//接收0个数据
  383. I2C_Start();//启动I2C模块
  384. DrvSYS_Delay(100);
  385. return I2c.State;
  386. }

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

  393. Init_System();
  394. Init_Uart();
  395. Init_I2C();
  396. DrvGPIO_Open(E_GPA,Run_Led, E_IO_OUTPUT);      //程序运行指示
  397. DrvGPIO_ClrBit(E_GPA,Run_Led);
  398. printf("\n");
  399. printf("/*==========================\n");
  400. printf("======菜农 %d 助学计划======\n",test);
  401. printf("========NUC120助学板========\n");
  402. printf("====程序参考新唐BSP库及HOT大叔例程====\n");
  403. printf("=======2011年04月26日=======\n");
  404. printf("========I2C(中断)实验=======\n");
  405. printf("I2C中断方式完成对AT24C16的读写操作\n");
  406. printf("'r'为读地址0x00单字节指令、'u'为地址0x00单字节加1并存储指令\n");
  407. printf("'d'为地址0x00单字节减1并存储指令\n");
  408. printf("'R'为读地址0x10开始单页指令、'u'为地址0x10开始单页加1并存储指令\n");
  409. printf("'d'为地址0x10开始单页减1并存储指令\n");
  410. printf("===========================/\n");
  411. if(I2C_BUS_OK==(I2C_ReadByte(0x00,&EEPROM_Data)))
  412.   printf("AT24C16地址0的内容为:0x%x!\n",EEPROM_Data);
  413. else
  414.   printf("AT24C16地址0的内容读取失败!\n");
  415. if (I2C_BUS_OK==I2C_ReadBuffer(0x10,I2C_Page_Test,16))
  416. {
  417.   printf("AT24C16地址0x10开始16字节的内容为:\n");
  418.   for (i=0;i<16;i++)
  419.    printf("0x%x ",I2C_Page_Test[i]);
  420. }
  421. else
  422.   printf("AT24C16地址0x10开始16字节的内容读取失败!\n");
  423. printf("\n====请输入字符开始测试!===\n");
  424. printf("==========================*/\n");
  425.     while(1)
  426.     {
  427.         if (IsStart)
  428.         {
  429.          switch (Receive_Data)
  430.          {
  431.           case 'R':
  432.      if (I2C_BUS_OK==I2C_ReadBuffer(0x10,I2C_Page_Test,16))
  433.      {
  434.       printf("\nAT24C16地址0x10开始16字节的内容为:\n");
  435.       for (i=0;i<16;i++)
  436.        printf("0x%x ",I2C_Page_Test[i]);
  437.      }
  438.      else
  439.       printf("\nAT24C16地址0x10开始16字节的内容读取失败!");
  440.      break;
  441.     case 'r':
  442.      if (I2C_BUS_OK==I2C_ReadByte(0x00,&EEPROM_Data))
  443.       printf("\nAT24C16地址0的内容为:0x%x!",EEPROM_Data);
  444.      else
  445.       printf("\nAT24C16地址0的内容读取失败!");
  446.      break;
  447.     case 'U':
  448.      for (i=0;i<16;i++)
  449.       I2C_Page_Test[i]++;
  450.      if (I2C_BUS_OK==I2C_WriteBuffer(0x10,I2C_Page_Test,16))
  451.       printf("\nAT24C16地址0x10开始16字节的内容加1成功!");
  452.      else
  453.      {
  454.       printf("\nAT24C16地址0x10开始16字节的内容加1失败!");
  455.       for (i=0;i<16;i++)
  456.        I2C_Page_Test[i]--;
  457.      }
  458.      break;
  459.     case 'u':
  460.      if (I2C_BUS_OK==I2C_WriteByte(0x00,++EEPROM_Data))
  461.       printf("\nAT24C16地址0的内容加1成功!");
  462.      else
  463.       printf("\nAT24C16地址0的内容加1失败!");
  464.      break;
  465.     case 'D':
  466.      for (i=0;i<16;i++)
  467.       I2C_Page_Test[i]--;
  468.      if (I2C_BUS_OK==I2C_WriteBuffer(0x10,I2C_Page_Test,16))
  469.       printf("\nAT24C16地址0x10开始16字节的内容减1成功!");
  470.      else
  471.      {
  472.       printf("\nAT24C16地址0x10开始16字节的内容减1失败!");
  473.       for (i=0;i<16;i++)
  474.        I2C_Page_Test[i]++;
  475.      }
  476.      break;
  477.     case 'd':
  478.      if (I2C_BUS_OK==I2C_WriteByte(0x00,--EEPROM_Data))
  479.       printf("\nAT24C16地址0的内容减1成功!");
  480.      else
  481.       printf("\nAT24C16地址0的内容减1失败!");
  482.      break;
  483.     default:
  484.      printf("\n请确认您输入的指令是否合法!");
  485.    
  486.          }
  487.          IsStart = FALSE;
  488.         }
  489.     }
  490. }


hotpower 发表于 2011-4-26 17:17 | 显示全部楼层
很好,这个中断方式与你以前的有什么不同?
请谈谈区别和各自的优点。
 楼主| Swallow_0322 发表于 2011-4-26 19:43 | 显示全部楼层
呵呵!恕我菜鸟,理解浅薄,还望大叔多多教诲!
中断方式执行效率高一些,数据处理在中断中完成,而查询方式要一直等待I2C1->CON.SI的状态变化;
查询方式较中断方式感觉操作更直观些;
而大叔的I2C中断方式的不同之处是除了查询中断的状态码之外还增加I2c.State,双重确认,更加可靠!
hotpower 发表于 2011-4-26 23:12 | 显示全部楼层
这个程序套路在很多芯片上应用,从无败绩,效果甚佳。
它实际是一个一主多从的I2C主控模式的程序,可以操作任何I2C芯片。
它基于状态机的控制,每一步都严格遵守状态机的次序,出错立即咔嚓放弃。
特别适于I2C总线通讯,在收到数据处再加一个回调函数,就彻底为零耗时了。
tlb 发表于 2011-4-27 05:58 | 显示全部楼层
跟着大叔学习
hotpower 发表于 2011-4-27 09:37 | 显示全部楼层
大家一起学习,俺也是学了不久。
weshiluwei6 发表于 2011-4-27 19:01 | 显示全部楼层
支持下  学习了
tlb 发表于 2011-4-28 07:22 | 显示全部楼层
M0的学习气氛还是很好的
我要把握好这个机会狠狠的学习下M0
 楼主| Swallow_0322 发表于 2011-4-28 13:40 | 显示全部楼层
共同学习!:handshake
ShaoKn 发表于 2011-8-19 11:52 | 显示全部楼层
标记,找个时间好好学习学习
wang0225 发表于 2011-8-19 21:14 | 显示全部楼层
给力,学习啦:lol
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"
楼主看到的时候,麻烦处理一下啊。谢谢了!
 楼主| Swallow_0322 发表于 2011-11-4 15:59 | 显示全部楼层
本帖最后由 Swallow_0322 于 2011-11-4 16:02 编辑

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


另外楼主位的压缩包我下载后解压没问题啊?如果需要可以QQ留言给我我发给你!
hotpower 发表于 2011-11-4 20:22 | 显示全部楼层
版本不同,即头文件不同,知道思想即可。
zibozhang 发表于 2012-2-28 11:20 | 显示全部楼层
我用这个例程怎么 读写数据不对啊 为什么
 楼主| Swallow_0322 发表于 2012-3-3 14:12 | 显示全部楼层
我用这个例程怎么 读写数据不对啊 为什么
zibozhang 发表于 2012-2-28 11:20


怎么验证的?
贴图!
timeismoney 发表于 2013-10-23 09:24 | 显示全部楼层
十分感谢!
ningtao66 发表于 2015-3-26 11:30 | 显示全部楼层
Swallow_0322 发表于 2011-4-26 19:43
呵呵!恕我菜鸟,理解浅薄,还望大叔多多教诲!
中断方式执行效率高一些,数据处理在中断中完成,而查询方 ...

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

遇到过IIC连续读几个小时后,目标芯片未发送返回数据,程序始终停在这个语句,造成看门狗超时动作的问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

121

主题

1393

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部