大家好,欢迎来到IT知识分享网。
一、前言
TWI(Two wire Serial Interface):twi接口是对I2C总线接口的继承和发展,完全兼容I2C总线
Nordic的TWI外设主要分成两类,TWIM
(基于EasyDMA的主设备Master) TWIS
(基于EasyDMA的从设备Slave)
ps:如有错误,请留言指正,谢谢
二、工作原理
功能特点
- 兼容I2C总线
- 可选速率 100kbps/250kbps/400kbps
- EasyDMA进行RAM数据与寄存器的传输
- 可映射到任意的GPIO引脚
原理框图
一主多从应用案例
TWI主机可同时挂载多个从机,主机通过从机唯一分配的地址进行寻址访问,总线需加上拉电阻以保证其驱动能力
数据通信过程
写数据
- TWI主机写数据通过
STARTTX
任务进行触发,最终通过STOP
结束任务- 从机的地址寻址成功后,通过
TXD.PTR
寄存器指向的RAM地址,调制发送数据- 发送时可被
SUSPEND
任务挂起,挂起期间总线会保持,在生效RESUME
任务后可继续通信- 当发送最后一个字节时,TWIM会产生一个
LASTTX
事件,必须发出STOP
任务结束一次通信(不会自动停止总线通信)- 仅通信
RESUME
释放后才能发送STOP
任务
读数据
- TWI主机读数据通过
STARTRX
任务触发,通过STOP
借结束任务- 读取到的数据将储存到
RXD.PTR
寄存器指向的RAM地址中,数据接收完成后主机产生一个NACK- 挂起任务
SUSPEND
触发后,将会产生一个SUSPENDED
事件,此事件可用于同步软件- 当TWI主机准备接收最后一个字节时,会产生一个
LASTRX
事件- TWI master在被挂起时无法停止,因此必须在TWI master恢复后发出STOP任务
三、寄存器
- SHORTS:循环模式控制,写1使能发送/接收最后字节的
LASTTX
/LASTRX
事件后,自动触发如开启/挂起/结束任务 - INTEN:中断控制寄存器,写1使能中断,写0禁用中断(按位配置中断
STOPPED/ERROR/SUSPENDED/RXSTARTED/TXSTARTED/LASTRX/LASTTX
) - INTENSET:中断使能寄存器,写1有效
- INTENCLR:中断禁用寄存器,写1有效
- ERRORSRC:错误状态寄存器,写1清状态
- ENABLE:TWIM外设使能寄存器
- PLSEL.SCL:关联SCL时钟引脚,低4位有效
- PLSEL.SDA:关联SDA数据引脚,低4位有效
- FREQUENCY:TWI通信速率选择
100k
250k
400k
- RXD.PTR:接收数据寄存器,指向RXD接收缓存
- RXD.MAXCNT:接收数据缓存区最大长度
- RXD.AMOUNT:最近一次数据通信的接收传输字节长度
- RXD.LIST:EasyDMA列表类型,写1使用arraylist接收缓存,触发
START
任务时无需更新PTR数据指针寄存器,类似DMA串口中双缓存循环读取 - TXD.PTR:发送数据寄存器,指向TXD发送缓存
- TXD.MAXCNT:需要发送数据缓存的最大长度
- TXD.AMOUNT:最近一次数据通信的发送传输字节长度
- TXD.LIST:EasyDMA列表类型,写1使用arraylist发送缓存,触发
START
任务时无需更新PTR数据指针寄存器,类似DMA串口中双缓存循环发送 - ADDRESS:TWI总线的寻址地址,最低位为读写位
四、相关接口
SPIM的驱动目录在modules\nrfx\drivers\src\nrfx_twim.c中
- nrfx_twim_init:初始化twim,形参
nrfx_twim_config_t p_config
传入引脚的映射关系与TWI的参数(通信速率、中断优先级);函数指针nrfx_twim_evt_handler_t handler
用于定义事件回调(数据的发送与接收)
nrfx_err_t nrfx_twim_init(nrfx_twim_t const * p_instance, nrfx_twim_config_t const * p_config, nrfx_twim_evt_handler_t event_handler, void * p_context)
- nrfx_twim_uninit:禁用twim外设,系统进入低功耗的时候可以调用
void nrfx_twim_uninit(nrfx_twim_t const * p_instance)
- nrfx_twim_xfer:数据传输接口,形参
nrfx_twim_xfer_desc_t const * p_xfer_desc
定义了发送TX与接收RX的缓存与长度
nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance, nrfx_twim_xfer_desc_t const * p_xfer_desc, uint32_t flags)
五、代码实例
打开工程目录 examples\peripheral\twi_master_with_twis_slave.eww,选择pca10040
贴上例程代码
/* * 初始化TWI master */ static ret_code_t twi_master_init(void) { ret_code_t ret; const nrf_drv_twi_config_t config = { .scl = TWI_SCL_M,//选择pin脚 .sda = TWI_SDA_M, .frequency = NRF_DRV_TWI_FREQ_400K,//通信速率 .interrupt_priority = APP_IRQ_PRIORITY_HIGH,//优先级 .clear_bus_init = false }; ret = nrf_drv_twi_init(&m_twi_master, &config, NULL, NULL);//调用配置驱动 if (NRF_SUCCESS == ret) { nrf_drv_twi_enable(&m_twi_master);//使能总线 } return ret; } /* * main接口,程序主要是通过软件模拟了从机与主机的通信 */ int main(void) { ret_code_t err_code; bool epprom_error = 0; /* Initialization of UART */ bsp_board_init(BSP_INIT_LEDS); APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); /* Initializing simulated EEPROM */ err_code = eeprom_simulator_init();//模拟eeprom twis从机总线初始化 APP_ERROR_CHECK(err_code); /* Initializing TWI master interface for EEPROM */ err_code = twi_master_init();//主机twim总线初始化 APP_ERROR_CHECK(err_code); err_code = nrf_drv_clock_init();//时钟初始化 APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); err_code = app_timer_init();//定时器初始化 APP_ERROR_CHECK(err_code); nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;//串口配置,可以使用串口命令行控制 uart_config.pseltxd = TX_PIN_NUMBER; uart_config.pselrxd = RX_PIN_NUMBER; uart_config.hwfc = NRF_UART_HWFC_DISABLED; err_code = nrf_cli_init(&m_cli_uart, &uart_config, true, true, NRF_LOG_SEVERITY_INFO); APP_ERROR_CHECK(err_code); err_code = nrf_cli_start(&m_cli_uart);//开启命令行cli控制 APP_ERROR_CHECK(err_code); /* Welcome message */ NRF_LOG_RAW_INFO( "TWIS and TWI usage example started.\r\n" "You can access simulated EEPROM memory using <eeprom> command.\r\n" "Execute: <eeprom -h> for more information or press the Tab button " "to see all available commands.\r\n" ); /* Main loop */ while (1) { UNUSED_RETURN_VALUE(NRF_LOG_PROCESS()); nrf_cli_process(&m_cli_uart);//处理串口命令 if (epprom_error != eeprom_simulator_error_check())//错误状态查询 { epprom_error = eeprom_simulator_error_check(); if (epprom_error != 0) { NRF_LOG_RAW_INFO( "WARNING: EEPROM transmission error detected.\r\n" "Use 'x' command to read error word.\r\n" ); } } } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/131046.html