nRF52832的SPIM收发1Byte数据时长度出错和解决方法

1.问题描述

        用nRF52832(SDK:Nordic SDK 17.0.2.)的SPIM和w5500通信时,发现网口初始化无法通过,用示波器分别捅了一下片选、时钟、MOSI、MISO,发现时钟居然是1byte和2byte交替出现的,MOSI数据也出错了:

         蓝色是时钟,绿色是片选,黄色是MOSI。每当出现2byte的数据时,MOSI后面凭空跟了个0xff在后面,但是我的SPIM收发函数是1byte的:

/*****************************************************************************
** 描  述:写入、读出一个字节
** 参  数:Dat:待写入的数据
** 返回值:读出的字节
******************************************************************************/
uint8_t Spi_WriteReadOneByte(uint8_t Dat)
{
    uint8_t len = 1;
	
    spi_tx_buf[0] = Dat;
	spi_xfer_done = false;
	APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, spi_tx_buf, len, spi_rx_buf, len));
    while(!spi_xfer_done);
	return (spi_rx_buf[0]);
}

 2.原因查找

        经检查不是函数的问题,于是去翻阅了一下开发指南,找到了这样两段话:

 

        符合我遇见的现象,于是去代码中查看了SPI的配置:

        orc确实是0xff,于是把orc随意改成一个其他的值,再用示波器测量,发现MOSI发出的数据也相应发生了变化。但是我明明只调用了1byte数据收发函数,TXD.MAXCNT和RXD.MAXCNT都是1。

        去Nordic论坛查找,发现有人和我出现了一样的问题,在官网上有一个纠错手册《Errata》,上面有方法解决这个问题(没想到竟是芯片自身的问题):

 文件下载:Nordic Semiconductor Infocenter

 3.问题解决

        根据纠错手册提供的解决方法是:使用52832的PPI,将SPIM的CLK电平翻转作为事件端点,将SPIM关闭作为任务端点。每当CLK发生电平变化时,便会关闭SPIM。但是52832的SPIM无法在1byte数据没有传输完成时关闭,SPIM会等到1byte数据传输完成之后再关闭,进而解决了多余字节的问题。手册提供的函数如下:

/**
 * @brief Work-around for transmitting 1 byte with SPIM.
 *
 * @param spim: The SPIM instance that is in use.
 * @param ppi_channel: An unused PPI channel that will be used by the workaround.
 * @param gpiote_channel: An unused GPIOTE channel that will be used by the workaround.
 * 
 * @warning Must not be used when transmitting multiple bytes.
 * @warning After this workaround is used, the user must reset the PPI channel and the
 GPIOTE channel before attempting to transmit multiple bytes.
 */
void setup_workaround_for_ftpan_58(NRF_SPIM_Type * spim, uint32_t ppi_channel, uint32_t gpiote_channel)
{
	 // Create an event when SCK toggles.
	 NRF_GPIOTE->CONFIG[gpiote_channel] = (
	 GPIOTE_CONFIG_MODE_Event <<
	 GPIOTE_CONFIG_MODE_Pos
	 ) | (
	 spim->PSEL.SCK <<
	 GPIOTE_CONFIG_PSEL_Pos
	 ) | (
	 GPIOTE_CONFIG_POLARITY_Toggle <<
	 GPIOTE_CONFIG_POLARITY_Pos
	 );
	 // Stop the spim instance when SCK toggles.
	 NRF_PPI->CH[ppi_channel].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_channel];
	 NRF_PPI->CH[ppi_channel].TEP = (uint32_t)&spim->TASKS_STOP;
	 NRF_PPI->CHENSET = 1U << ppi_channel;
	 // The spim instance cannot be stopped mid-byte, so it will finish
	 // transmitting the first byte and then stop. Effectively ensuring
	 // that only 1 byte is transmitted.
}

        这样调用即可:

void spi_ppi_set(void)
{
	setup_workaround_for_ftpan_58(NRF_SPIM0, 6, 0);
}

        注意点:1.一旦建立起这个PPI通道,就只能单字节地收发数据了,若是想要多字节收发,需要关闭该通道;

                        2.需要使用硬件控制CS电平;

                        3.需要将orc改成0x00,不然数据还是会出错。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
nRF52832 是一款蓝牙低功耗系统级芯片(SoC),用于物联网(IoT)设备和其他低功耗应用。nRF52832是挪威纳恩索蓝牙公司(Nordic Semiconductor)推出的系列产品之一,其数据手册提供了关于该芯片的详细技术规格和功能描述。 nRF52832 数据手册包含了如下内容: 1. 芯片架构和引脚分布:介绍了nRF52832的内部架构和芯片上引脚的功能,包括GPIO、UART、SPI、I2C、ADC等外设的分配和配置。 2. 功耗和性能:详细说明了nRF52832在不同工作模式下的功耗消耗情况,包括睡眠模式、活动模式和射频发送/接收模式的功耗指标。还介绍了芯片的钟和定器功能,以及处理器内核的性能参数。 3. 射频特性:描述了nRF52832的射频发射和接收性能,包括频率范围、功率级别、调制方式、接收灵敏度等参数。同说明了射频天线的接口和匹配电路设计。 4. 内存和存储器:详细介绍了nRF52832的闪存、RAM和永久存储器(EEPROM)的容量和地址分布,以及存储器映射和访问控制。 5. 外设和接口:列出了nRF52832支持的各种外设和接口,包括GPIO、UART、SPI、I2C、ADC、PWM、NFC、USB等,以及它们的功能和配置选项。 6. 软件开发工具和编程接口:介绍了nRF52832相关的软件开发工具和编程接口,包括开发环境(如Keil、IAR、GCC)和软件库(如nRF5 SDK)。 通过研读nRF52832 数据手册,开发者和工程师可以深入了解该芯片的各项功能和性能,为使用该芯片开发可靠的低功耗蓝牙应用提供技术支持和指导。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值