你好,
我找不到任何关于14580(或其他)外围设备的功能以及如何为不同的选项设置它们的文档。
I2C, SPI, A/D, PWM,....等。
有人能给我指一下这样的文件吗?
嗨sjabir2004,
请在外设示例应用部分(7)查看文档UM-B-050,也可以在外设驱动部分(10)查看文档UM-B-051,了解外设驱动程序。亚博国际官网平台网址
由于MT_dialog
我已经看过这些文件了。没有描述外设的硬件结构以及如何设置外设。这些示例无法涵盖所有可能的组合和功能。
请确认这份文件丢失了
没有关于da外设和开发的api的其他文档,有关任何其他功能的更多信息,可以在da的数据表中找到。此外,您可能还想查看UM-B-005和UM-B-004文件,以检查这些文件是否包含任何其他功能。
例如:我想命令一个I2C传感器。我需要发送命令写,然后最终读取。Read最多可以有N个字节。
我不知道如何设置I2C寄存器中的位和字节来发送和接收,因为它没有写在任何地方!
i2c_eeprom示例中的哪些函数在本例中可用?
谢谢你!
我不认为i2c_eeprom示例中的I2C函数是传感器驱动程序的一个很好的起点。我一直在使用下面的例子,它更好地解释了如何攻击I2C:
/*****************************************************************************************宏****************************************************************************************/// I2C helper宏SetWord16(I2C_DATA_CMD_REG, (X))#定义WAIT_WHILE_I2C_FIFO_IS_FULL() while(!#定义WAIT_UNTIL_I2C_FIFO_IS_EMPTY() while(!# GetWord16(I2C_STATUS_REG) & MST_ACTIVITY# GetWord16(I2C_RXFLR_REG)
/*---------------------------------------------------------------------------------------| @brief使用提供从地址初始化I2C接口|| @param[in] slave_address, I2C从地址|| @返回void---------------------------------------------------------------------------------------*/Void i2c_init(uint8_t slave_address){//初始化I2C地址作为参数// TODO:支持10bit寻址SetBits16(CLK_PER_REG, I2C_ENABLE, 1);//使能I2C时钟SetWord16 (I2C_ENABLE_REG 0 x0);//关闭I2C控制器SetWord16(I2C_CON_REG, I2C_MASTER_MODE | I2C_SLAVE_DISABLE |I2C_RESTART_EN);// Slave被禁用SetBits16(I2C_CON_REG, I2C_SPEED, 1);//设置速度。标准速度= 1,快速= 2SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, 0);//设置寻址模式7bit = 0, 10bit= 1SetWord16(I2C_TAR_REG, slave_address & 0xFF);//设置从设备地址SetWord16 (I2C_ENABLE_REG 0 x1);//开启I2C控制器while(GetWord16(I2C_STATUS_REG) & 0x20);//等待I2C主FSM空闲}//
/*---------------------------------------------------------------------------------------| @brief扫描I2C总线上的从设备|| @param[in] extended,如果为true:响应将包括潜在的I2C从设备id| @param[in] remote,扫描命令的发起者|| @返回void---------------------------------------------------------------------------------------*/Void i2c_scan(bool extended,bool remote){Char temp_str[255] = {0};Char response_str[255] = {0};uint8_t response_idx = 0;//遍历所有I2C地址(仅限7位寻址!)For (uint8_t I = 0x01;i < 0x7F;我+ +){//设置下一个从地址i2c_init(我);SEND_I2C_COMMAND(0x00 & 0x3FF);//在总线上传输地址WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待SEND_I2C_COMMAND(0x0100 & 0x3FF);//发送读寄存器0x00WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保Master已经完成//我们收到任何数据了吗?if(GetWord16(I2C_RXFLR_REG) != 0){//读取接收的数据(device_id)uint8_t device_id =0xFF & GetWord16(I2C_DATA_CMD_REG);//如果这是一个扩展扫描,报告设备ID和地址如果(扩展)//扩展扫描。报告地址和寄存器0x00 (device_id)sprintf (temp_str“0 x % 02 x = > 0 x % 02 x,”,我,device_id);其他的//正常扫描=>报告地址sprintf (temp_str“0 x % 02,”i);memcpy (&response_str [response_idx], temp_str strlen (temp_str));//如果总线上有超过50个I2C设备,将会失败Response_idx += strlen(temp_str);}}//添加回车,换行和OKsprintf (temp_str“\ n \韩国”);memcpy (&response_str [response_idx-1], temp_str strlen (temp_str));//显示响应(远程或本地)回应(response_str strlen (response_str),远程);
//关闭I2CSetWord16 (I2C_ENABLE_REG 0 x0);//关闭I2C控制器SetBits16(CLK_PER_REG, I2C_ENABLE, 0);//关闭I2C时钟}//
/*---------------------------------------------------------------------------------------发送I2C从内存地址|| @param[in] I2C从内存地址---------------------------------------------------------------------------------------*/Void i2c_send_address(uint8_t address_to_send){SEND_I2C_COMMAND(address_to_send & 0xFF);//设置地址LSB,写访问}//
/*---------------------------------------------------------------------------------------| @brief从I2C从端读取单字节。|@param[in] address,用于读取字节的内存地址。|| @return读字节。---------------------------------------------------------------------------------------*/Int8_t地址(uint8_t){i2c_send_address(地址& 0x3FF);WAIT_WHILE_I2C_FIFO_IS_FULL ();// Tx FIFO已满时等待SEND_I2C_COMMAND(0x0100 & 0x3FF);//设置R/W位为1(读访问)WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待I2C Tx FIFO空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保master已经完成return (0xFF & GetWord16(I2C_DATA_CMD_REG));//获取接收字节}//
/*---------------------------------------------------------------------------------------| @brief向I2C从端写入单字节。|| @param[in] address,写入字节的内存地址。| @param[in] wr_data,要写入的数据。|| @返回void。---------------------------------------------------------------------------------------*/Void i2c_write_byte(uint16_t address, uint8_t wr_data){i2c_send_address(地址);WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待SEND_I2C_COMMAND(wr_data & 0xFF);//发送写数据WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动}//
/*---------------------------------------------------------------------------------------| @brief从I2C从端读取数据|| @param[in] hw_address, I2C从机HW地址| @param[in] reg_address,读取的寄存器地址| @param[in] num_bytes,读取的字节数| @param[in] remote,读取命令的发起者|| @返回void---------------------------------------------------------------------------------------*/Void i2c_read(uint16_t hw_address,uint16_t reg_address, uint8_t num_bytes, bool remote){Char temp_str[255] = {0};i2c_init (hw_address);(uint8_t我= 0;< num_bytes;我+ +){Uint8_t data = i2c_read_byte(reg_address+i);char str [10];如果(i = = 0)sprintf (str,“0 x % 02”数据);其他的sprintf (str,”0 x % 02”数据);sprintf (temp_str“% s % s temp_str, str);}sprintf (temp_str“% s \ n \韩国”,temp_str);回应(temp_str strlen (temp_str),远程);}//
/*---------------------------------------------------------------------------------------| @brief向I2C从机的寄存器地址写入数据|| @param[in] hw_address, I2C从机HW地址| @param[in] reg_address,写入的寄存器地址| @param[in] data,要写入的数据| @param[in] remote,读取命令的发起者|| @返回void---------------------------------------------------------------------------------------*/Void i2c_write(uint16_t hw_address,uint16_t reg_address, uint16_t wr_data, bool remote){i2c_init (hw_address);i2c_write_byte (reg_address wr_data);respond_ok(远程);}//
我希望这能有所帮助。
这似乎就是我要找的。我会试试的。
我不知道你为什么不把这个添加到SDK的文档和库中!!,这个论坛的很多人都会很高兴。市场上有很多I2C设备,每一个都有自己的结构和协议。
你好,我在哪里可以找到这些函数sprintf (temp_str“% s \ n \韩国”,temp_str);回应(temp_str strlen (temp_str),远程);
抱歉,我指的是respond_ok()和respond_ok()
Sprintf来自stdlib库(只需#include "stdlib.h")——当您想要将数据转储给用户或在调试期间非常有用。
这两个响应函数只是一组函数,我已经实现转储数据到串口。您可以在代码中使用UART2和arch_printf来实现这一点。
我同意这应该被添加到文档中-一个快速教程的有用材料。
你好,这是清楚的。在上面的代码中,......................Void i2c_write_byte(uint16_t address, uint8_t wr_data){i2c_send_address(地址);WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待SEND_I2C_COMMAND(wr_data & 0xFF);//发送写数据WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动}TAR寄存器包含从机的地址,DATA_CMD寄存器包含要发送的数据。i2c_send_address(address)将把地址写到DATA_CMD寄存器,然后SEND_I2C_COMMAND(wr_data..)将做同样的事情!.
是搞错了还是我遗漏了什么?都应该经过DATA_CMD_REG吗?即目标地址和要发送的数据?如果是,TAR_REG位0:7的范围是什么?
简单的机制是什么:给一个奴隶发一个命令?命令可以读,写,重置,..2-从从设备读取n个字节?一切都没有中断,只是为了简单。谢谢你!
IC_TAR寄存器包含从设备的地址,在i2c驱动中,设备将首先写入模块的寄存器地址,它想要读/写到DATA_CMD,然后,在DATA_CMD寄存器中放置要传输的数据。I2C_TAR是设备本身的地址,设备地址的设置是在i2c初始化过程中设置的。
你好
I2C_TAR包含DA14580要写入的i2c DEVICE的地址。DATA_CMD_REG包含与DEVICE通信的数据。
当我向DATA_CMD_REG写入任何数据时,在i2c总线上,首先有I2C_TAR_REG,然后是I2C_DATA_REG内容。
如果我把从地址写到DATA_CMD_REG,你将在总线上有两次地址!!
如果总线上有一个i2c设备,一个人需要加载TAR_REG一次,然后将数据写入DATA_CMD_REG,然后我得到地址——>数据发送到设备,
这是我在内存示波器上看到的。
我是不是遗漏了什么?
什么意思?如果你在DATA_CMD_REG中写入设备的从地址,模块将发送I2C_TAR_REG(这是模块的地址),然后将发送DATA_CMD_REG中的数据,这也是模块的地址。您只需要初始化您想要通信的设备的I2C,然后每次在DATA_CMD_REG中写入内容时,设备的地址将在总线上与操作(读/写)一起跟随DATA_CMD_REG中的数据。在i2c开始一个新的事务的停止或重新启动条件后,设备的地址将再次在总线上。
你好,我使用的是SDK 5.0.4 .为了检查DA14580设备的安全功能,我必须将绑定数据存储在EEPROM中。当写入一个字节到EEPROM时,我面临i2c_wait_until_eeprom_ready()函数的问题。它影响调试。if (GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)__asm(“BKPT # 0 \ n”);
我的代码如下所示,************************************************************************************/*************************************************************选择绑定数据存储的内存介质:** - SPI FLASH(#定义USER_CFG_APP_BOND_DB_USE_SPI_FLASH)* - I2C EEPROM (#define USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)* -只缓存(什么都不定义)**只选择一个选项。************************************************************* /# undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH#定义USER_CFG_APP_BOND_DB_USE_I2C_EEPROM
静态内联无效bond_db_load_ext{#if defined (USER_CFG_APP_BOND_DB_USE_SPI_FLASH)bond_db_load_flash ();#elif定义(USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)bond_db_load_eeprom ();# endif}
#elif定义(USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)
静态无效bond_db_load_eeprom(void){uint32_t bytes_read;
i2c_eeprom_init(I2C_SLAVE_ADDRESS, I2C_SPEED_MODE, I2C_ADDRESS_MODE, I2C_ADDRESS_SIZE);
i2c_eeprom_read_data((uint8_t *)&bdb, APP_BOND_DB_DATA_OFFSET, sizeof(struct bond_db), &bytes_read);ASSERT_ERROR(bytes_read == sizeof(struct bond_db));
i2c_eeprom_release ();}
I2c_error_code i2c_eeprom_read_data(uint8_t *rd_data_ptr, uint32_t address, uint32_t size, uint32_t *bytes_read){uint32_t tmp_size;
If (size == 0){*bytes_read = 0;返回I2C_NO_ERROR;}
//检查从(MAX_SIZE x 8) I2C EEPROM读取的最大字节数if (size > I2C_EEPROM_SIZE - address){tmp_size = I2C_EEPROM_SIZE -地址;*bytes_read = tmp_size;}其他的{Tmp_size = size;*bytes_read = size;}
if (i2c_wait_until_eeprom_ready() != I2C_NO_ERROR){返回I2C_7B_ADDR_NOACK_ERROR;}
//一次读取32字节While (tmp_size >= 32){Read_data_single (&rd_data_ptr, address, 32);
地址+= 32;//更新读取的基址Tmp_size -= 32;//更新tmp_size的剩余字节}
如果(tmp_size){Read_data_single (&rd_data_ptr,地址,tmp_size);}
返回I2C_NO_ERROR;}
i2c_error_code i2c_wait_until_eeprom_ready(空白){uint16_t tx_abrt_source;
//检查是否收到ACKFor (uint32_t I = 0;i < I2C_MAX_RETRIES;我+ +){SEND_I2C_COMMAND (();//创建虚拟访问WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动tx_abrt_source = GetWord16(I2C_TX_ABRT_SOURCE_REG);//读取I2C_TX_ABRT_SOURCE_REG寄存器GetWord16 (I2C_CLR_TX_ABRT_REG);//清除I2C_TX_ABRT_SOURCE寄存器if ((tx_abrt_source & ABRT_7B_ADDR_NOACK) == 0){返回I2C_NO_ERROR;}}返回I2C_7B_ADDR_NOACK_ERROR;}
注意:如果我在系统中加载了绑定数据,它是正常工作的。也就是说,# undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH# undef USER_CFG_APP_BOND_DB_USE_I2C_EEPROM
为了避免这个问题,请给出宝贵的建议。提前谢谢。
嗨ajay98,
i2c_wait_until_eeprom_ready()通过发送0x08字节轮询设备,直到设备响应ACK。请在调试模式下运行代码,并指出在i2c_wait_until_eeprom_ready()的哪个点代码会卡住?另外,您使用的是哪种SDK示例?这是自定义实现吗?是否可以在SDK的ble_app_security示例中复制它?
我也会建议你用你的问题创建一个新的论坛线程,因为这个非常老了。
谢谢,PM_Dialog
嗨sjabir2004,
请在外设示例应用部分(7)查看文档UM-B-050,也可以在外设驱动部分(10)查看文档UM-B-051,了解外设驱动程序。亚博国际官网平台网址
由于MT_dialog
你好,
我已经看过这些文件了。
没有描述外设的硬件结构以及如何设置外设。这些示例无法涵盖所有可能的组合和功能。
请确认这份文件丢失了
嗨sjabir2004,
没有关于da外设和开发的api的其他文档,有关任何其他功能的更多信息,可以在da的数据表中找到。此外,您可能还想查看UM-B-005和UM-B-004文件,以检查这些文件是否包含任何其他功能。
由于MT_dialog
例如:我想命令一个I2C传感器。我需要发送命令写,然后最终读取。Read最多可以有N个字节。
我不知道如何设置I2C寄存器中的位和字节来发送和接收,因为它没有写在任何地方!
i2c_eeprom示例中的哪些函数在本例中可用?
谢谢你!
你好,
我不认为i2c_eeprom示例中的I2C函数是传感器驱动程序的一个很好的起点。我一直在使用下面的例子,它更好地解释了如何攻击I2C:
/****************************************************************************************
*宏
****************************************************************************************/
// I2C helper宏
SetWord16(I2C_DATA_CMD_REG, (X))
#定义WAIT_WHILE_I2C_FIFO_IS_FULL() while(!
#定义WAIT_UNTIL_I2C_FIFO_IS_EMPTY() while(!
# GetWord16(I2C_STATUS_REG) & MST_ACTIVITY
# GetWord16(I2C_RXFLR_REG)
/*---------------------------------------------------------------------------------------
| @brief使用提供从地址初始化I2C接口
|
| @param[in] slave_address, I2C从地址
|
| @返回void
---------------------------------------------------------------------------------------*/
Void i2c_init(uint8_t slave_address)
{
//初始化I2C地址作为参数
// TODO:支持10bit寻址
SetBits16(CLK_PER_REG, I2C_ENABLE, 1);//使能I2C时钟
SetWord16 (I2C_ENABLE_REG 0 x0);//关闭I2C控制器
SetWord16(I2C_CON_REG, I2C_MASTER_MODE | I2C_SLAVE_DISABLE |I2C_RESTART_EN);// Slave被禁用
SetBits16(I2C_CON_REG, I2C_SPEED, 1);//设置速度。标准速度= 1,快速= 2
SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, 0);//设置寻址模式7bit = 0, 10bit= 1
SetWord16(I2C_TAR_REG, slave_address & 0xFF);//设置从设备地址
SetWord16 (I2C_ENABLE_REG 0 x1);//开启I2C控制器
while(GetWord16(I2C_STATUS_REG) & 0x20);//等待I2C主FSM空闲
}
//
/*---------------------------------------------------------------------------------------
| @brief扫描I2C总线上的从设备
|
| @param[in] extended,如果为true:响应将包括潜在的I2C从设备id
| @param[in] remote,扫描命令的发起者
|
| @返回void
---------------------------------------------------------------------------------------*/
Void i2c_scan(bool extended,bool remote)
{
Char temp_str[255] = {0};
Char response_str[255] = {0};
uint8_t response_idx = 0;
//遍历所有I2C地址(仅限7位寻址!)
For (uint8_t I = 0x01;i < 0x7F;我+ +)
{
//设置下一个从地址
i2c_init(我);
SEND_I2C_COMMAND(0x00 & 0x3FF);//在总线上传输地址
WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待
SEND_I2C_COMMAND(0x0100 & 0x3FF);//发送读寄存器0x00
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保Master已经完成
//我们收到任何数据了吗?
if(GetWord16(I2C_RXFLR_REG) != 0)
{
//读取接收的数据(device_id)
uint8_t device_id =0xFF & GetWord16(I2C_DATA_CMD_REG);
//如果这是一个扩展扫描,报告设备ID和地址
如果(扩展)
//扩展扫描。报告地址和寄存器0x00 (device_id)
sprintf (temp_str“0 x % 02 x = > 0 x % 02 x,”,我,device_id);
其他的
//正常扫描=>报告地址
sprintf (temp_str“0 x % 02,”i);
memcpy (&response_str [response_idx], temp_str strlen (temp_str));
//如果总线上有超过50个I2C设备,将会失败
Response_idx += strlen(temp_str);
}
}
//添加回车,换行和OK
sprintf (temp_str“\ n \韩国”);
memcpy (&response_str [response_idx-1], temp_str strlen (temp_str));
//显示响应(远程或本地)
回应(response_str strlen (response_str),远程);
//关闭I2C
SetWord16 (I2C_ENABLE_REG 0 x0);//关闭I2C控制器
SetBits16(CLK_PER_REG, I2C_ENABLE, 0);//关闭I2C时钟
}
//
/*---------------------------------------------------------------------------------------
发送I2C从内存地址
|
| @param[in] I2C从内存地址
---------------------------------------------------------------------------------------*/
Void i2c_send_address(uint8_t address_to_send)
{
SEND_I2C_COMMAND(address_to_send & 0xFF);//设置地址LSB,写访问
}
//
/*---------------------------------------------------------------------------------------
| @brief从I2C从端读取单字节。
|
@param[in] address,用于读取字节的内存地址。
|
| @return读字节。
---------------------------------------------------------------------------------------*/
Int8_t地址(uint8_t)
{
i2c_send_address(地址& 0x3FF);
WAIT_WHILE_I2C_FIFO_IS_FULL ();// Tx FIFO已满时等待
SEND_I2C_COMMAND(0x0100 & 0x3FF);//设置R/W位为1(读访问)
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待I2C Tx FIFO空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保master已经完成
return (0xFF & GetWord16(I2C_DATA_CMD_REG));//获取接收字节
}
//
/*---------------------------------------------------------------------------------------
| @brief向I2C从端写入单字节。
|
| @param[in] address,写入字节的内存地址。
| @param[in] wr_data,要写入的数据。
|
| @返回void。
---------------------------------------------------------------------------------------*/
Void i2c_write_byte(uint16_t address, uint8_t wr_data)
{
i2c_send_address(地址);
WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待
SEND_I2C_COMMAND(wr_data & 0xFF);//发送写数据
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动
}
//
/*---------------------------------------------------------------------------------------
| @brief从I2C从端读取数据
|
| @param[in] hw_address, I2C从机HW地址
| @param[in] reg_address,读取的寄存器地址
| @param[in] num_bytes,读取的字节数
| @param[in] remote,读取命令的发起者
|
| @返回void
---------------------------------------------------------------------------------------*/
Void i2c_read(uint16_t hw_address,uint16_t reg_address, uint8_t num_bytes, bool remote)
{
Char temp_str[255] = {0};
i2c_init (hw_address);
(uint8_t我= 0;< num_bytes;我+ +)
{
Uint8_t data = i2c_read_byte(reg_address+i);
char str [10];
如果(i = = 0)
sprintf (str,“0 x % 02”数据);
其他的
sprintf (str,”0 x % 02”数据);
sprintf (temp_str“% s % s temp_str, str);
}
sprintf (temp_str“% s \ n \韩国”,temp_str);
回应(temp_str strlen (temp_str),远程);
}
//
/*---------------------------------------------------------------------------------------
| @brief向I2C从机的寄存器地址写入数据
|
| @param[in] hw_address, I2C从机HW地址
| @param[in] reg_address,写入的寄存器地址
| @param[in] data,要写入的数据
| @param[in] remote,读取命令的发起者
|
| @返回void
---------------------------------------------------------------------------------------*/
Void i2c_write(uint16_t hw_address,uint16_t reg_address, uint16_t wr_data, bool remote)
{
i2c_init (hw_address);
i2c_write_byte (reg_address wr_data);
respond_ok(远程);
}
//
我希望这能有所帮助。
这似乎就是我要找的。我会试试的。
我不知道你为什么不把这个添加到SDK的文档和库中!!,这个论坛的很多人都会很高兴。市场上有很多I2C设备,每一个都有自己的结构和协议。
谢谢你!
你好,我在哪里可以找到这些函数
sprintf (temp_str“% s \ n \韩国”,temp_str);
回应(temp_str strlen (temp_str),远程);
抱歉,我指的是respond_ok()和respond_ok()
你好,
Sprintf来自stdlib库(只需#include "stdlib.h")——当您想要将数据转储给用户或在调试期间非常有用。
这两个响应函数只是一组函数,我已经实现转储数据到串口。您可以在代码中使用UART2和arch_printf来实现这一点。
我同意这应该被添加到文档中-一个快速教程的有用材料。
你好,这是清楚的。
在上面的代码中,
......................
Void i2c_write_byte(uint16_t address, uint8_t wr_data)
{
i2c_send_address(地址);
WAIT_WHILE_I2C_FIFO_IS_FULL ();// I2C Tx FIFO已满请等待
SEND_I2C_COMMAND(wr_data & 0xFF);//发送写数据
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动
}
TAR寄存器包含从机的地址,DATA_CMD寄存器包含要发送的数据。i2c_send_address(address)将把地址写到DATA_CMD寄存器,然后SEND_I2C_COMMAND(wr_data..)将做同样的事情!.
是搞错了还是我遗漏了什么?
都应该经过DATA_CMD_REG吗?即目标地址和要发送的数据?
如果是,TAR_REG位0:7的范围是什么?
简单的机制是什么:
给一个奴隶发一个命令?
命令可以读,写,重置,..
2-从从设备读取n个字节?
一切都没有中断,只是为了简单。
谢谢你!
嗨sjabir2004,
IC_TAR寄存器包含从设备的地址,在i2c驱动中,设备将首先写入模块的寄存器地址,它想要读/写到DATA_CMD,然后,在DATA_CMD寄存器中放置要传输的数据。I2C_TAR是设备本身的地址,设备地址的设置是在i2c初始化过程中设置的。
由于MT_dialog
你好
I2C_TAR包含DA14580要写入的i2c DEVICE的地址。
DATA_CMD_REG包含与DEVICE通信的数据。
当我向DATA_CMD_REG写入任何数据时,在i2c总线上,首先有I2C_TAR_REG,然后是I2C_DATA_REG内容。
如果我把从地址写到DATA_CMD_REG,你将在总线上有两次地址!!
如果总线上有一个i2c设备,一个人需要加载TAR_REG一次,然后将数据写入DATA_CMD_REG,然后我得到地址——>数据发送到设备,
这是我在内存示波器上看到的。
我是不是遗漏了什么?
嗨sjabir2004,
什么意思?如果你在DATA_CMD_REG中写入设备的从地址,模块将发送I2C_TAR_REG(这是模块的地址),然后将发送DATA_CMD_REG中的数据,这也是模块的地址。您只需要初始化您想要通信的设备的I2C,然后每次在DATA_CMD_REG中写入内容时,设备的地址将在总线上与操作(读/写)一起跟随DATA_CMD_REG中的数据。在i2c开始一个新的事务的停止或重新启动条件后,设备的地址将再次在总线上。
由于MT_dialog
你好,
我使用的是SDK 5.0.4 .为了检查DA14580设备的安全功能,我必须将绑定数据存储在EEPROM中。当写入一个字节到EEPROM时,我面临i2c_wait_until_eeprom_ready()函数的问题。它影响调试。
if (GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)
__asm(“BKPT # 0 \ n”);
我的代码如下所示,
************************************************************************************
/************************************************************
*选择绑定数据存储的内存介质:
*
* - SPI FLASH(#定义USER_CFG_APP_BOND_DB_USE_SPI_FLASH)
* - I2C EEPROM (#define USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)
* -只缓存(什么都不定义)
*
*只选择一个选项。
************************************************************
* /
# undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH
#定义USER_CFG_APP_BOND_DB_USE_I2C_EEPROM
静态内联无效bond_db_load_ext
{
#if defined (USER_CFG_APP_BOND_DB_USE_SPI_FLASH)
bond_db_load_flash ();
#elif定义(USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)
bond_db_load_eeprom ();
# endif
}
#elif定义(USER_CFG_APP_BOND_DB_USE_I2C_EEPROM)
静态无效bond_db_load_eeprom(void)
{
uint32_t bytes_read;
i2c_eeprom_init(I2C_SLAVE_ADDRESS, I2C_SPEED_MODE, I2C_ADDRESS_MODE, I2C_ADDRESS_SIZE);
i2c_eeprom_read_data((uint8_t *)&bdb, APP_BOND_DB_DATA_OFFSET, sizeof(struct bond_db), &bytes_read);
ASSERT_ERROR(bytes_read == sizeof(struct bond_db));
i2c_eeprom_release ();
}
I2c_error_code i2c_eeprom_read_data(uint8_t *rd_data_ptr, uint32_t address, uint32_t size, uint32_t *bytes_read)
{
uint32_t tmp_size;
If (size == 0)
{
*bytes_read = 0;
返回I2C_NO_ERROR;
}
//检查从(MAX_SIZE x 8) I2C EEPROM读取的最大字节数
if (size > I2C_EEPROM_SIZE - address)
{
tmp_size = I2C_EEPROM_SIZE -地址;
*bytes_read = tmp_size;
}
其他的
{
Tmp_size = size;
*bytes_read = size;
}
if (i2c_wait_until_eeprom_ready() != I2C_NO_ERROR)
{
返回I2C_7B_ADDR_NOACK_ERROR;
}
//一次读取32字节
While (tmp_size >= 32)
{
Read_data_single (&rd_data_ptr, address, 32);
地址+= 32;//更新读取的基址
Tmp_size -= 32;//更新tmp_size的剩余字节
}
如果(tmp_size)
{
Read_data_single (&rd_data_ptr,地址,tmp_size);
}
返回I2C_NO_ERROR;
}
i2c_error_code i2c_wait_until_eeprom_ready(空白)
{
uint16_t tx_abrt_source;
//检查是否收到ACK
For (uint32_t I = 0;i < I2C_MAX_RETRIES;我+ +)
{
SEND_I2C_COMMAND (();//创建虚拟访问
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待Tx FIFO为空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//直到没有主活动
tx_abrt_source = GetWord16(I2C_TX_ABRT_SOURCE_REG);//读取I2C_TX_ABRT_SOURCE_REG寄存器
GetWord16 (I2C_CLR_TX_ABRT_REG);//清除I2C_TX_ABRT_SOURCE寄存器
if ((tx_abrt_source & ABRT_7B_ADDR_NOACK) == 0)
{
返回I2C_NO_ERROR;
}
}
返回I2C_7B_ADDR_NOACK_ERROR;
}
注意:如果我在系统中加载了绑定数据,它是正常工作的。也就是说,
# undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH
# undef USER_CFG_APP_BOND_DB_USE_I2C_EEPROM
为了避免这个问题,请给出宝贵的建议。提前谢谢。
嗨ajay98,
i2c_wait_until_eeprom_ready()通过发送0x08字节轮询设备,直到设备响应ACK。请在调试模式下运行代码,并指出在i2c_wait_until_eeprom_ready()的哪个点代码会卡住?另外,您使用的是哪种SDK示例?这是自定义实现吗?是否可以在SDK的ble_app_security示例中复制它?
我也会建议你用你的问题创建一个新的论坛线程,因为这个非常老了。
谢谢,PM_Dialog