你好,
我找不到任何文档讨论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宏#define send_i2c_command(x)setword16(i2c_data_cmd_reg,(x))定义WAIT_WHILE_I2C_FIFO_IS_FULL() while(!(GetWord16(I2C_STATUS_REG) & TFNF))#define WAIT_UNTIL_I2C_FIFO_IS_EMPTY() while(!(GetWord16(I2C_STATUS_REG) & TFE)))#define wait_until_no_master_actity()(getword16(i2c_status_reg)&mst_actity)#定义WAIT_FOR_RECEIVED_BYTE(),而(! GetWord16 (I2C_RXFLR_REG))
/ * ---------------------------------------------------------------------------| @brief使用提供从地址初始化I2C接口||@param [in] slave_address,i2c从地址与之通信||@return 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);//禁用SlavesetBits16(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控制器而(getword16(i2c_status_reg)&0x20);//等待I2C主FSM闲置}//
/ * ---------------------------------------------------------------------------|@brief扫描从设备的I2C总线进行奴隶设备|| @param[in] extended,如果为true:响应将包括潜在的I2C从设备id@param[in] remote,扫描命令的发起者||@return void.---------------------------------------------------------------------------------------*/void i2c_scan(bool扩展,bool remote){Char temp_str[255] = {0};char response_str [255] = {0};uint8_t response_idx = 0;//运行所有I2C地址(仅7位地址!)For (uint8_t I = 0x01;我< 0 x7f;我+ +){//设置下一个从地址i2c_init(我);SEND_I2C_COMMAND (0 x00 & 0 x3ff);//在总线上传输地址WAIT_WHILE_I2C_FIFO_IS_FULL ();//等待i2c tx fifo已满SEND_I2C_COMMAND (0 x0100 & 0 x3ff);//发送读取寄存器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 \ rok”);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时钟}//
/ * ---------------------------------------------------------------------------| @brief发送I2C从内存地址|| @param[in] I2C从内存地址---------------------------------------------------------------------------------------*/void i2c_send_address(uint8_t地址_to_send){send_i2c_command(地址_to_send&0xff);//设置地址LSB,写访问}//
/ * ---------------------------------------------------------------------------| @brief从I2C从读取单个字节。|| @param[in] address,读取字节的内存地址。|| @return读取字节。---------------------------------------------------------------------------------------*/int8_t i2c_read_byte (uint8_t地址){i2c_send_address(地址& 0 x3ff);WAIT_WHILE_I2C_FIFO_IS_FULL ();//如果Tx FIFO是满的,等待SEND_I2C_COMMAND (0 x0100 & 0 x3ff);//设置R/W位为1(读访问)WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待直到I2C Tx FIFO空WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保大师已完成返回(0xff&getword16(i2c_data_cmd_reg));//获得收到的字节}//
/ * ---------------------------------------------------------------------------|@brief将单个字节写入i2c从属。|| @param[in] address,要写入字节的内存地址。|@param [in] wr_data,编写的数据。||@return 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 & 0 xff);//发送写数据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]远程,read命令的始发者||@return 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,“,0x%02x”,数据);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]数据,数据写入|@param [in]远程,read命令的始发者||@return 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设备,每个I2C设备都有自己的结构和协议。
谢谢你!
你好,我在哪里找到这些函数sprintf (temp_str“% s \ n \韩国”,temp_str);回应(temp_str strlen (temp_str),远程);
不好意思,我是说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 & 0 xff);//发送写数据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设备的地址。data_cmd_reg中包含要与设备进行通信的数据。
当我写入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中存储bond数据。在向EEPROM中写入字节时,我遇到了i2c_wait_until_eeprom_ready()函数的问题,它影响了调试。if((getword16(sys_stat_reg)&dbg_is_up)== dbg_is_up)__asm(“bkpt#0 \ n”);
我的代码如下所示,************************************************************************************/ *************************************************************为键数据存储选择内存介质:** - spi flash(#define 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
静态内联void bond_db_load_ext(void){#f定义(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)
静态void 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;}
//检查要从a(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 =大小;}
i2c_wait_until_eeprom_ready() != I2C_NO_ERROR{返回I2C_7B_ADDR_NOACK_ERROR;}
//一次读取32个字节While (tmp_size >= 32){read_data_single(&rd_data_ptr,地址,32);
地址+ = 32;// Update base address for readtmp_size - = 32;// Update tmp_size for remaining to read}
if(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 {send_i2c_command(0x08);//制作假人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_abt_source & abt_7b_addr_noack) == 0) / /输出{返回I2C_NO_ERROR;}}返回I2C_7B_ADDR_NOACK_ERROR;}
注意:如果我在Sysram中加载了键数据,则它正常工作。即,#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宏
#define send_i2c_command(x)setword16(i2c_data_cmd_reg,(x))
定义WAIT_WHILE_I2C_FIFO_IS_FULL() while(!(GetWord16(I2C_STATUS_REG) & TFNF))
#define WAIT_UNTIL_I2C_FIFO_IS_EMPTY() while(!(GetWord16(I2C_STATUS_REG) & TFE)))
#define wait_until_no_master_actity()(getword16(i2c_status_reg)&mst_actity)
#定义WAIT_FOR_RECEIVED_BYTE(),而(! GetWord16 (I2C_RXFLR_REG))
/ * ---------------------------------------------------------------------------
| @brief使用提供从地址初始化I2C接口
|
|@param [in] slave_address,i2c从地址与之通信
|
|@return 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控制器
而(getword16(i2c_status_reg)&0x20);//等待I2C主FSM闲置
}
//
/ * ---------------------------------------------------------------------------
|@brief扫描从设备的I2C总线进行奴隶设备
|
| @param[in] extended,如果为true:响应将包括潜在的I2C从设备id
@param[in] remote,扫描命令的发起者
|
|@return void.
---------------------------------------------------------------------------------------*/
void i2c_scan(bool扩展,bool remote)
{
Char temp_str[255] = {0};
char response_str [255] = {0};
uint8_t response_idx = 0;
//运行所有I2C地址(仅7位地址!)
For (uint8_t I = 0x01;我< 0 x7f;我+ +)
{
//设置下一个从地址
i2c_init(我);
SEND_I2C_COMMAND (0 x00 & 0 x3ff);//在总线上传输地址
WAIT_WHILE_I2C_FIFO_IS_FULL ();//等待i2c tx fifo已满
SEND_I2C_COMMAND (0 x0100 & 0 x3ff);//发送读取寄存器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 \ rok”);
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时钟
}
//
/ * ---------------------------------------------------------------------------
| @brief发送I2C从内存地址
|
| @param[in] I2C从内存地址
---------------------------------------------------------------------------------------*/
void i2c_send_address(uint8_t地址_to_send)
{
send_i2c_command(地址_to_send&0xff);//设置地址LSB,写访问
}
//
/ * ---------------------------------------------------------------------------
| @brief从I2C从读取单个字节。
|
| @param[in] address,读取字节的内存地址。
|
| @return读取字节。
---------------------------------------------------------------------------------------*/
int8_t i2c_read_byte (uint8_t地址)
{
i2c_send_address(地址& 0 x3ff);
WAIT_WHILE_I2C_FIFO_IS_FULL ();//如果Tx FIFO是满的,等待
SEND_I2C_COMMAND (0 x0100 & 0 x3ff);//设置R/W位为1(读访问)
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();//等待直到I2C Tx FIFO空
WAIT_UNTIL_NO_MASTER_ACTIVITY ();//确保大师已完成
返回(0xff&getword16(i2c_data_cmd_reg));//获得收到的字节
}
//
/ * ---------------------------------------------------------------------------
|@brief将单个字节写入i2c从属。
|
| @param[in] address,要写入字节的内存地址。
|@param [in] wr_data,编写的数据。
|
|@return 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 & 0 xff);//发送写数据
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]远程,read命令的始发者
|
|@return 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,“,0x%02x”,数据);
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]数据,数据写入
|@param [in]远程,read命令的始发者
|
|@return 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设备,每个I2C设备都有自己的结构和协议。
谢谢你!
你好,我在哪里找到这些函数
sprintf (temp_str“% s \ n \韩国”,temp_str);
回应(temp_str strlen (temp_str),远程);
不好意思,我是说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 & 0 xff);//发送写数据
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设备的地址。
data_cmd_reg中包含要与设备进行通信的数据。
当我写入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中存储bond数据。在向EEPROM中写入字节时,我遇到了i2c_wait_until_eeprom_ready()函数的问题,它影响了调试。
if((getword16(sys_stat_reg)&dbg_is_up)== dbg_is_up)
__asm(“bkpt#0 \ n”);
我的代码如下所示,
************************************************************************************
/ ************************************************************
*为键数据存储选择内存介质:
*
* - spi flash(#define 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
静态内联void bond_db_load_ext(void)
{
#f定义(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)
静态void 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;
}
//检查要从a(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 =大小;
}
i2c_wait_until_eeprom_ready() != I2C_NO_ERROR
{
返回I2C_7B_ADDR_NOACK_ERROR;
}
//一次读取32个字节
While (tmp_size >= 32)
{
read_data_single(&rd_data_ptr,地址,32);
地址+ = 32;// Update base address for read
tmp_size - = 32;// Update tmp_size for remaining to read
}
if(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
send_i2c_command(0x08);//制作假人
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_abt_source & abt_7b_addr_noack) == 0) / /输出
{
返回I2C_NO_ERROR;
}
}
返回I2C_7B_ADDR_NOACK_ERROR;
}
注意:如果我在Sysram中加载了键数据,则它正常工作。即,
#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