- /*---------------------------------------------------------------------------------------------------------*/
- /* */
- /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
- /* */
- /*---------------------------------------------------------------------------------------------------------*/
- #include "includes.h" //包含所需的头文件
- /*************************************************************************************
- ** Function name: main
- ** Descriptions: 本函数实现:I2C功能,向AT24C16的0x00地址写入0x03 然后读出来 并用数码管显示出来
- 注:本例程的I2C读写部分移植了论坛三心前辈的例子 特此声明并感谢三心前辈
- ** input parameters: 无
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- int main (void)
- {
- Set_System(); //封装一些初始化模块
- I2C_WriteByte (0x00,0x03 );
- delay_ms(1000);
- value = I2C_ReadByte(0x00);
- while(1)
- {}
- }
hw_config函数- #include "includes.h" //包含所需的头文件
- /*************************************************************************************
- ** Function name: Set_System
- ** Descriptions: 封装一些初始化模块
- ** input parameters: count
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- void Set_System(void)
- {
- RCC_Configuration(); //配置系统时钟
- GPIO_Configuration(); //配置GPIO
- TIMER_Configuration(); //配置TIMER
- I2C_Configuration(); //配置I2C
- }
- /*************************************************************************************
- ** Function name: RCC_Configuration
- ** Descriptions: 系统时钟源设置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void RCC_Configuration(void)
- {
- UNLOCKREG(); // 对写保护位操作时 需要一次向0x50000 0100写入 0x59,0x16,0x88,
- DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);// 与其 SYSCLK->PWRCON.XTL12M_EN = 1; 等同
- // PWRCON寄存器(这些寄存器在上电复位到用户解锁定之前是锁定的)除了 BIT[6]位其他位都受写保护
- // 解除这些需要向 0x50000 0100写入 0x59,0x16,0x88,
- // 令PWRCON寄存器的BITP[0]为1(即设定12M外部晶振)
- delay_ms(100); // while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);//等待外部12MHZ晶振就绪
- LOCKREG(); // 向“0x5000_0100”写入任何值,就可以重锁保护寄存器
- }
- /*************************************************************************************
- ** Function name: GPIO_Configuration
- ** Descriptions: GPIO配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void GPIO_Configuration()
- {
- DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT );//数码管段选
- DrvGPIO_Open( E_GPA, 3, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 4, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 5, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 6, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 7, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 8, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 9, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 14, E_IO_OUTPUT );//数码管位选
- DrvGPIO_Open( E_GPC, 15, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 6, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 7, E_IO_OUTPUT );
- }
- /*************************************************************************************
- ** Function name: TIMER_Configuration
- ** Descriptions: TIMER配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void TIMER_Configuration()
- {
- DrvTIMER_Init(); //初始化定时器
- DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0); //使用外设时注意必须设置该外设的时钟 设置TIMER0的时钟源为外部12MHZ
- DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE); //设定定时器timer0的tick周期,并且启动定时器:定时器通道 TMR0 每秒1000次 周期模式
- DrvTIMER_SetTimerEvent(E_TMR0,5,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个定时处理事件到 timer0通道
- DrvTIMER_EnableInt(E_TMR0); //使能定时器中断 //TIMER0->TCSR.IE = 1
- DrvTIMER_Start(E_TMR0); //定时器timer0开始计数 //TIMER0->TCSR.CEN = 1;
- }
- /*************************************************************************************
- ** Function name: Timer0_Callback
- ** Descriptions: 定时处理事件,LED动态扫描
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Timer0_Callback (void)
- {
- static uint8_t count= 0;
- static uint8_t i,xx[4];
- uint32_t data;
- uint16_t ValueBuff ;
- ValueBuff = value;
- count++;
- if(count >= 5)
- count = 1;
- for(i=0;i<4;i++)
- {
- xx[i] = ValueBuff%10;
- ValueBuff = ValueBuff/10;
- }
- switch(count)
- {
- case 1:
- DrvGPIO_SetBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[0]]<<2;
- GPIOA->DOUT = data;
- break;
- case 2:
- DrvGPIO_SetBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[1]]<<2;
- GPIOA->DOUT = data;
- break;
- case 3:
- DrvGPIO_SetBit(E_GPC,7);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,6);
- data = Table[xx[2]]<<2;
- GPIOA->DOUT = data;
- break;
- case 4:
- DrvGPIO_SetBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[3]]<<2;
- GPIOA->DOUT = data;
- //DrvGPIO_ClrBit(E_GPA,9); //显示小数点
- break;
- default:break;
- }
- }
- /*************************************************************************************
- ** Function name: I2C_Configuration
- ** Descriptions: I2C配置(注:一些配置都在 读写I2C的子程序里了)
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void I2C_Configuration()
- {
- DrvGPIO_InitFunction(E_FUNC_I2C1);//注意:在使用引脚特殊功能时 必须进行复用功能引脚设置(此时I2C1引脚为开漏输出)
- DrvGPIO_SetBit(E_GPA,10); //在使用之前需将 I2C1_SDA 置高
- DrvGPIO_SetBit(E_GPA,11); //在使用之前需将 I2C1_SCL 置高
- }
- /*************************************************************************************
- ** Function name: I2C_WriteByte
- ** Descriptions: I2C向写单字节函数(注:此函数是将论坛三心前辈的例子移植过来的 在此声明并表示感谢)
- ** input parameters: 地址:address 数据:data
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- 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, 100000); //打开I2C1功能,并配置 I2C总线时钟为100KHZ (该函数进行了四舍五入操作)
- /* 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 I2C开始 进入主机模式 */
- /* stop - [in] 1:Enable / 0:Disable I2C停止 */
- /* intFlag - [in] Wrtie '1' to clear this flag (I2C_SI) */
- /* ack - [in] 1:Enable / 0:Disable 应答位 */
- while (I2C1->CON.SI == 0); //查询中断标志位 SI 如果忙则一直等待
- //I2C1->DATA = ;
- DrvI2C_WriteData (I2C_PORT1, 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_WriteData (I2C_PORT1, 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); //关闭I2C1功能
- for(i=0;i<6000;i++);
- for(i=0;i<6000;i++);
- }
- /*************************************************************************************
- ** Function name: I2C_ReadByte
- ** Descriptions: I2C向读单字节函数(注:此函数是将论坛三心前辈的例子移植过来的 在此声明并表示感谢)
- ** input parameters: 地址:address
- ** output parameters: DATA
- ** Returned value: none
- *************************************************************************************/
- uint8_t I2C_ReadByte ( uint32_t address )
- {
- /*
- 随机读操作允许主器件对寄存器的任意字节进行读操作,主器件
- 首先通过发送起始信号、从器件地址和它想读取的字节数据的地
- 址执行一个伪写操作。在AT24Cxx 应答之后,主器件重新发送起
- 始信号和从器件地址,此时R/W 位置1,AT24CXX 响应并发送应答
- 信号,然后输出所要求的一个 8位字节数据,主器件不发送应答
- 信号但产生一个停止信号。
- */
- uint8_t DATA;
- DrvI2C_Open(I2C_PORT1, 100000); //打开I2C1功能,并配置 I2C总线时钟为100KHZ
- DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0); //设定I2C控制比位 START并清中断标志
- while (I2C1->CON.SI == 0); //查询中断标志位 SI 如果忙则一直等待
- DrvI2C_WriteData (I2C_PORT1, 0xA0); //发送写命令 即从器件地址
- DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //清标志位 SI
- while( I2C1->CON.SI == 0 ); //查询中断标志位 SI 如果忙则一直等待
- DrvI2C_WriteData (I2C_PORT1, 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 如果忙则一直等待
- DrvI2C_WriteData (I2C_PORT1, 0xA1); //发送写命令 即从器件地址的最低位 R/W 位设置为 1
- 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 如果忙则一直等待
- DATA= DrvI2C_ReadData(I2C_PORT1); //读数据
- DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //清标志位 SI 并STOP
- DrvI2C_Close(I2C_PORT1); //关闭I2C1功能
- return DATA;
- }
- /*************************************************************************************
- ** Function name: delay_ms
- ** Descriptions: 1ms(晶振为12MHZ)延时子程序
- ** input parameters: count
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- void delay_ms(uint32_t count)
- {
- uint32_t i,j;
- for(i=count;i>0;i--)
- for(j=2395;j>0;j--);
- }
hw_config头文件- #ifndef __HW_CONFIG_H__
- #define __HW_CONFIG_H__
- void Set_System(void);
- void RCC_Configuration(void);
- void GPIO_Configuration(void);
- void TIMER_Configuration(void);
- void Timer0_Callback (void);
- void I2C_Configuration(void);
- void I2C_WriteByte ( uint32_t address,uint8_t data );
- uint8_t I2C_ReadByte ( uint32_t address );
- void delay_ms(uint32_t count);
- #endif
已测试通过 OK
工程