Advertisement

[国产MCU]-W801开发实例-I2C控制器

阅读量:

I2C控制器

文章目录

  • I2C控制器
    • 1、I2C控制器介绍
    • 2、I2C驱动API
    • 2、I2C简单使用示例

1、I2C控制器介绍

I2C总线是一种简洁、双向通信的双线同步串口总线。I2C总线设备之间仅需使用两条通信线路即可实现高效的数据传输。

根据数据传输方向的不同,I2C总线上的设备被划分为两类:主机与从机。在I2C总线上,当主机设备向从设备发送数据时,首先需要完成寻址操作;随后立即发送待传数据至目标方,最后完成断开连接操作。当I2C总线上接收来自从机的数据时,首先要执行寻址步骤;随后立即接收来自目标方的待传信息,最后完成断开连接操作。同时负责生成固定频率的时钟信号以及管理结束信息的发送。

W801的I2C控制器有如下主要特性:

APB总线协议标准接口
仅限于作为主设备控制器使用
支持多路GPIO信号复用以实现I2C通信接口
通过配置CR_SR寄存器指定总线START、STOP、ACK及NACK信号的状态切换,在主机模式下启动数据传输并生成同步时钟信号
支持中断与启动/停止功能控制:使用CTR位和Bit6端口启用/禁用中断功能,并可通过Bit7端口实时切换控制器运行状态

I2C控制器的寄存器列表如下:

序号 寄存器名称 名称缩写 访问 描述 偏移地址 复位值
1 时钟分频寄存器_1 PRERlo RW 储存低8位分频值,用于对APB总线时钟进行分步 0x0000 0x0000_00FF
2 时钟分频寄存器_2 PRERhi RW 储存高8位分频值,用于对APB总线时钟进行分步 0x0004 0x0000_00FF
3 控制控制器 CTR RW 用以控制中断的使能以及I2S控制器的使能 0x0008 0x0000_0040
4 数据寄存器 TXR_RXR RW 用于存放待发送的数据或者接收到的数据 0x000C 0x0000_0000
5 收发控制器 CR_SR RW 用于控制一些数据读写相关的操作 0x0010 0x0000_0000
6 TXR读出寄存器 TXR RO 读取I2C发送时的TXR寄存器值 0x0014 0x0000_0000
7 CR读取寄存器 CR RO 读取I2C控制器的设定值CR 0x0018 0x0000_0000

2、I2C驱动API

W801SDK对I2C的访问控制,提供了如下API:

  • void tls_i2c_init (u32 freq):完成I2C初始化过程。其中freq参数表示总线通信的工作频率。
    • void tls_i2c_stop (void):向设备发送停止操作指示。
    • int tls_i2c_wait_ack (void):等待ACK确认信号...返回值包括WM_FAILED或WM_SUCCESS。
    • void tls_i2c_write_byte (u8 data, u8 ifstart):传输数据信息
      • data变量存储待传输的数据内容
      • ifstart标志位决定操作流程...当其值为1时,先执行启动操作再传输数据内容;当其值为0时,则直接进行数据传输

该函数用于完成特定的数据通信操作。
其中ifack参数决定了在完成数据传输后的后续行为:

  • 当其值设为1时系统会自动发送ACK确认;
  • 若设置为0则直接执行传输操作而不产生额外确认信号。
    此外该函数还包括另一个控制位ifstop:
  • 当该位设为1表示已接收到位并应终止后续操作;
  • 若设置为0则传输过程结束后不会触发终止指令。
  • void register_i2c_transfer_done(void (*done_func)()):注册I2C数据传输完成回调函数
    • int initiate_i2c_write(int dev_addr, int word_addr, unsigned short data_len):采用中断方式发送数据。返回值为:失败(WM_FAILED)或成功(成功)。
      • dev_addr:设备地址
      • 当word_addr为1时,在读取完成后会触发停止信号;否则不会触发停止信号
      • data缓冲区用于存储即将发送的数据块
      • data_len表示每块数据的字节数量

函数功能描述

参数说明

功能细节

2、I2C简单使用示例

下面将演示如何对AT24C01 EEPROM进行数据存取操作。

1)导入依赖头文件

复制代码
    #include "wm_include.h"
    #include "wm_i2c.h"
    #include <string.h>
    #include "wm_gpio_afsel.h"

2)I2C基本配置

复制代码
    #define I2C_FREQ		(200000) // I2C通信频率

3)AT24C01读取数据

复制代码
    u8 AT24CXX_ReadOneByte(u16 addr)
    {				  
    	u8 temp=0;		  	    																 
    	//printf("\nread addr=%x\n",ReadAddr);
    	tls_i2c_write_byte(0xA0,1);   
    	tls_i2c_wait_ack(); 
    	tls_i2c_write_byte(addr,0);   
    	tls_i2c_wait_ack();	    
    
    	tls_i2c_write_byte(0xA1,1);
    	tls_i2c_wait_ack();	 
    	temp=tls_i2c_read_byte(0,1);
    	//printf("\nread byte=%x\n",temp);
    	return temp;
    }
    
    void AT24CXX_ReadLenByte(u16 addr,u8 *buf,u16 len)
    {				  
    	//printf("\nread len addr=%x\n",ReadAddr);
    	tls_i2c_write_byte(0xA0,1);   
    	tls_i2c_wait_ack(); 
    	tls_i2c_write_byte(addr,0);   
    	tls_i2c_wait_ack();	    
    	tls_i2c_write_byte(0xA1,1);
    	tls_i2c_wait_ack();	
    	while(len > 1)
    	{
    		*buf++ = tls_i2c_read_byte(1,0);
    		//printf("\nread byte=%x\n",*(pBuffer - 1));
    		len --;
    	}
       	*buf = tls_i2c_read_byte(0,1);
    }
    
    void AT24CXX_Read(u16 addr, u8 *buf, u16 len)
    {
    	while(len)
    	{
    		*buf++=AT24CXX_ReadOneByte(addr++);	
    		len--;
    	}
    }

4)AT24C01写数据

复制代码
    void AT24CXX_WriteOneByte(u16 addr, u8 data)
    {				   	  	    																 
    	tls_i2c_write_byte(0XA0, 1); 
    	tls_i2c_wait_ack();	   
    	tls_i2c_write_byte(addr, 0);
    	tls_i2c_wait_ack(); 	 										  		   
    	tls_i2c_write_byte(data, 0); 				   
    	tls_i2c_wait_ack();  	   
     	tls_i2c_stop();
    	tls_os_time_delay(1);
    }
    
    void AT24CXX_Write(u16 addr, u8 *buf, u16 len)
    {
    	while(len--)
    	{
    		AT24CXX_WriteOneByte(addr,*buf);
    		addr++;
    		buf++;
    	}
    }

5)AT24C01状态检测

复制代码
    u8 AT24CXX_Check(void)
    {
    	u8 temp;
    	temp=AT24CXX_ReadOneByte(255);
    	if (temp==0x55)return 0;		   
    	else
    	{
    		AT24CXX_WriteOneByte(255, 0x55);
    		tls_os_time_delay(1);
    		temp=AT24CXX_ReadOneByte(255);	  
    		if (temp==0x55)return 0;
    	}
    
    	return 1;											  
    }

6)AT24C01驱动测试

复制代码
    int i2c_demo(char *buf)
    {
    	u8 testbuf[] = {"AT24CXX I2C TEST OK"};
    	u8 datatmp[32];
    
    wm_i2c_scl_config(WM_IO_PA_01);
    wm_i2c_sda_config(WM_IO_PA_04);
    
    	tls_i2c_init(I2C_FREQ);
    
    	while(AT24CXX_Check())
    	{
    		printf("\nAT24CXX check faild\n");
    	}
    	tls_os_time_delay(1);
    	printf("\nAT24CXX check success\n");
    
    	AT24CXX_Write(0,(u8 *)testbuf,sizeof(testbuf));
    	tls_os_time_delay(1);
    	memset(datatmp,0,sizeof(datatmp));
    	//AT24CXX_Read(0,datatmp,sizeof(testbuf));
    	AT24CXX_ReadLenByte(0,(u8 *)datatmp,sizeof(testbuf));
    	printf("\nread data is:%s\n",datatmp);
    	
    	return WM_SUCCESS;
    }

全部评论 (0)

还没有任何评论哟~