-
- /**************************************************
- ** 文件名称:NUC120_HOT_I2C.c
- ** 文件说明:NUC120助学板练习程序
- ** 创建日期:2011-04-11
- ** 修改日期:
- ** 备 注: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;
- /***************
- ** 函数声明 **
- ***************/
- void Init_System (void);
- void Init_Uart (void);
- void UART_INT_HANDLE(uint32_t u32IntStatus);
- void I2C_WriteByte ( uint32_t address,uint8_t data );
- uint8_t I2C_ReadByte ( uint32_t address );
-
- /*****************************
- ** 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: Init_System
- ** Function: 系统初始化函数
- ** Input: None
- ** OutPut: None
- ** Data: 2011-03-17
- ** Note:
- ****************************/
- void Init_System(void)
- {
- /* Unlock the locked registers before access */
- UNLOCKREG(x); //寄存器锁定键地址寄存器(RegLockAddr) :有些系统控制寄存器需要被保护起来,以防止误操作而影响芯片运行,
- //这些寄存器在上电复位到用户解锁定之前是锁定的。用户可以连续依次写入“59h”, “16h” “88h”到0x5000_0100解锁定.
- /* Enable the 12MHz oscillator oscillation */
- DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1); //SYSCLK->PWRCON.XTL12M_EN = 1;
- /* Waiting for 12M Xtal stable */
- //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1); //SYSCLK->CLKSTATUS.XTL12M_STB
- /*eClkSrc - [in] E_SYS_XTL12M / E_SYS_XTL32K / E_SYS_OSC22M / E_SYS_OSC10K / E_SYS_PLL */
- // Note: Only some of NuMicro NUC100 Series support this function.
- DrvSYS_Delay(5000);
- LOCKREG(x);
- //向“0x5000_0100”写入任何值,就可以重锁保护寄存器
- }
- /*****************************
- ** Name: Init_Uart
- ** Function: UART初始化函数
- ** Input: None
- ** OutPut: None
- ** Data: 2011-03-17
- ** Note:
- ****************************/
- void Init_Uart(void)
- {
- STR_UART_T param;
- /*
- 声明 UART设置的结构体 位于DRVUART.H
- 结构体如下
- typedef struct DRVUART_STRUCT
- {
- uint32_t u32BaudRate;
- E_DATABITS_SETTINS u8cDataBits;
- E_STOPBITS_SETTINS u8cStopBits;
- E_PARITY_SETTINS u8cParity;
- E_FIFO_SETTINGS u8cRxTriggerLevel;
- uint8_t u8TimeOut ;
- }STR_UART_T;
- */
- 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功能
- //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0xF<<0));
- 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,¶m) != E_SUCCESS) // 串口开启、结构体整体赋值
- printf("UART0 open failed\n");
- /* u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 /UART_PORT2 */
- /* sParam -[in] the struct parameter to configure UART */
- /* Enable Interrupt and install the call back function */
- DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);
- /*u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 / UART_PORT2 */
- /*u32InterruptFlag -[in] DRVUART_LININT/DRVUART_WAKEUPINT/DRVUART_BUFERRINT/DRVUART_RLSINT */
- /* DRVUART_MOSINT/DRVUART_THREINT/DRVUART_RDAINT/DRVUART_TOUTINT */
- /*pfncallback -[in] A function pointer for callback function */
- }
- int main (void)
- {
- uint8_t test = 250;
- uint8_t EEPROM_Data = 0;
-
- Init_System();
-
- Init_Uart();
- DrvGPIO_InitFunction(E_FUNC_I2C1);
- 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库======\n");
- printf("=======2011年04月11日=======\n");
- printf("========I2C(查询)实验=======\n");
- printf("I2C查询方式完成单字节写及随机地址读操作\n");
- printf("'R/r'为读指令、'U/u'为加1并存储指令、'D/d'为减1并存储指令\n");
- printf("===========================/\n");
- EEPROM_Data = I2C_ReadByte(0x00);
- printf("AT24C16地址0的内容为:0x%x!\n",EEPROM_Data);
- printf("====请输入字符开始测试!===\n");
- printf("==========================*/\n");
- while(1)
- {
- if (IsStart)
- {
- switch (Receive_Data)
- {
- case 'R':
- case 'r':
- EEPROM_Data = I2C_ReadByte(0x00);
- printf("AT24C16地址0的内容为:0x%x!\n",EEPROM_Data);
- break;
- case 'U':
- case 'u':
- I2C_WriteByte(0x00,++EEPROM_Data);
- printf("AT24C16地址0的内容加1成功!\n");
- break;
- case 'D':
- case 'd':
- I2C_WriteByte(0x00,--EEPROM_Data);
- printf("AT24C16地址0的内容减1成功!\n");
- break;
- default:
- printf("请确认您输入的指令是否合法!\n");
-
- }
- IsStart = FALSE;
- }
- }
- }
- /*****************************
- ** Name: I2C_WriteByte
- ** Function: I2C向写单字节函数
- ** Input: uint32_t address,uint8_t data
- ** OutPut: None
- ** Data: 2011-04-11
- ** Note:
- ****************************/
- void I2C_WriteByte ( uint32_t address,uint8_t data )
- {
- /*
- 在字节写模式下,主器件发送起始命令和从器件地址信息(R/W 位置 0)给从器件,
- 主器件在收到从器件产生应答信号后,主器件发送1个8位字节地址写入AT24C01/
- 02/04/08/16 的地址指针,对于 AT24C31/64/128/256 来说,所不同的是主器件
- 发送两个8位地址字写入AT24C32/64/128/256的地址指针。主器件在收到从器件的
- 另一个应答信号后,再发送数据到被寻址的存储单元。AT24Cxx 再次应答,并在
- 主器件产生停止信号后开始内部数据的擦写,在内部擦写过程中,AT24Cxx 不再
- 应答主器件的任何请求。
- */
- uint32_t i;
-
- DrvI2C_Open(I2C_PORT1, 50000); //打开I2C1功能,并配置 I2C总线时钟为50KHZ
- /* Parameters:port - [in] I2C_PORT0 / I2C_PORT1 */
- /* u32BusClock - [in] I2C bus clock frequency (Hz) */
-
- DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0); //设定I2C控制比特 START
- /* Parameters:port - [in] I2C_PORT0 / I2C_PORT1 */
- /* start - [in] 1:Enable / 0:Disable */
- /* stop - [in] 1:Enable / 0:Disable */
- /* intFlag - [in] Wrtie '1' to clear this flag */
- /* ack - [in] 1:Enable / 0:Disable */
- 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
-
- I2C1->DATA = data; //发送待写内容
- DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //清标志位 SI 并使能应答
- while( I2C1->CON.SI == 0 ); //查询中断标志位 SI
-
- DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //清标志位 SI 并STOP
-
- for(i=0;i<60;i++);
- DrvI2C_Close(I2C_PORT1);
-
- for(i=0;i<6000;i++);
- for(i=0;i<6000;i++);
- }
- /*****************************
- ** Name: I2C_ReadByte
- ** Function: I2C向读单字节函数
- ** Input: uint32_t address,uint8_t data
- ** OutPut: None
- ** Data: 2011-04-11
- ** Note:
- ****************************/
- uint8_t I2C_ReadByte ( uint32_t address )
- {
- /*
- 随机读操作允许主器件对寄存器的任意字节进行读操作,主器件
- 首先通过发送起始信号、从器件地址和它想读取的字节数据的地
- 址执行一个伪写操作。在AT24Cxx 应答之后,主器件重新发送起
- 始信号和从器件地址,此时R/W 位置1,AT24CXX 响应并发送应答
- 信号,然后输出所要求的一个 8位字节数据,主器件不发送应答
- 信号但产生一个停止信号。
- */
- uint8_t TEMP;
-
- DrvI2C_Open(I2C_PORT1, 50000);
-
- 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;
- }
工程结构:
串口调试截图:
工程文件:
一点疑问: