[国产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表示每块数据的字节数量
- int initiate_i2c_write(int dev_addr, int word_addr, unsigned short data_len):采用中断方式发送数据。返回值为:失败(WM_FAILED)或成功(成功)。
函数功能描述
参数说明
功能细节
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)
还没有任何评论哟~
