wiba 发表于 2021-6-6 10:56

关于HC32L136k8硬件SPI调试

关于HC32L136k8硬件SPI与RC520调试

调试环境说明

1、使用keil5 优化级别最低
2、MCU HC32L136K8TA
3、SDK版本 hc32l13x_ddl_Rev1.9.2 Lite
4、调试器 jlink
5、开发板HC32Lx3x-stk-v2.0
6、芯片配置:32M外部晶振 HCLK32M PCLK32M ,SPI的CLK是PCLK/4 ,SPI配置 时钟相位0 极性0

问题

我用了HC32L136开发板调试RC522芯片,使用软件SPI可以的,一旦使用硬件SPI就莫名的出错,可以说读不出来,调试了好久,好累啊,希望各位使用此单片机硬件SPI避免坑,本人才疏学浅,有些不详细或出错描述,请见谅,欢迎指正,拒绝差评哦


wiba 发表于 2021-6-6 10:57

样列代码分析

这处的代码是 实例 SPI MASTER

   ///< 片选,开始通讯
    Spi_SetCS(M0P_SPI0, FALSE);
    ///< 主机向从机发送数据
    while(tx_cnt<10)                                        //主机发送数据给从机
    {
      while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE);    //等待发送缓冲器空
      Spi_SendData(M0P_SPI0, tx_buf);
    }

    ///< 主机接收从机数据
    while(rx_cnt<10)                                        //接收从机的数据
    {
      while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE);    //等待发送缓冲器空
      Spi_SendData(M0P_SPI0, 0);                        //发送空数据
      delay10us(20);
      while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);
      rx_buf = Spi_ReceiveData(M0P_SPI0);
    }

    ///< 结束通信
    Spi_SetCS(M0P_SPI0, TRUE);



他所给的代码是两个单片机互相SPI通信 一个为master,一个为slave。我没有实测。
1、可以得出关键点接收数据必须延时,实测延时delay10us(1);可以,不过偶尔不行,我设的delay10us(2);
2、以下分析RC520通信SPI
2.1得到RC520寄存器数据步骤:
///< 片选,开始通讯
Spi_SetCS(M0P_SPI0, FALSE);
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE); //等待发送缓冲器空
Spi_SendData(M0P_SPI0, 地址);
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE); //等待发送缓冲器空
Spi_SendData(M0P_SPI0, 0); //发送空数据
delay10us(20);
while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);
数据 = Spi_ReceiveData(M0P_SPI0);
///< 结束通信
Spi_SetCS(M0P_SPI0, TRUE);
2.2写数据到RC520寄存器
///< 片选,开始通讯
Spi_SetCS(M0P_SPI0, FALSE);
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE); //等待发送缓冲器空
Spi_SendData(M0P_SPI0, 地址);
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE); //等待发送缓冲器空
Spi_SendData(M0P_SPI0, 数据); //
///< 结束通信
Spi_SetCS(M0P_SPI0, TRUE);


wiba 发表于 2021-6-6 10:58

实验成功的代码----读数据到RC520

        uint8_t ucResult=0,temp;
        uint8_t ucAddr;
        ///< 片选,开始通讯
        Spi_SetCS(M0P_SPI0, FALSE);
        ucAddr = ((ucRegAddr<<1)&0x7E)|0x80;
        //发送地址
        while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE){};    //等待发送缓冲器空
    Spi_SendData(M0P_SPI0, ucAddr);
    while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);                       
        temp =Spi_ReceiveData(M0P_SPI0);
        temp = temp +1;
    while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE);    //等待发送缓冲器空
    Spi_SendData(M0P_SPI0, 0x00);                        //发送空数据
    delay10us(2);
    while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);
    ucResult = Spi_ReceiveData(M0P_SPI0);
        ///< 结束通信
        Spi_SetCS(M0P_SPI0, TRUE);


wiba 发表于 2021-6-6 10:59

实验成功的代码----写数据到RC520

uint8_t ucAddr,temp=0;
///< 片选,开始通讯
Spi_SetCS(M0P_SPI0, FALSE);
ucAddr = ((ucRegAddr<<1)&0x7E);
//发送地址
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE){};    //等待发送缓冲器空
Spi_SendData(M0P_SPI0, ucAddr);
delay10us(2);
while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);
temp =         Spi_ReceiveData(M0P_SPI0);
while(Spi_GetStatus(M0P_SPI0, SpiTxe) == FALSE);    //等待发送缓冲器空
Spi_SendData(M0P_SPI0, ucRegVal);                        //
while(Spi_GetStatus(M0P_SPI0, SpiRxne) == FALSE);
temp =         Spi_ReceiveData(M0P_SPI0);
temp = temp+1;
///< 结束通信
Spi_SetCS(M0P_SPI0, TRUE);



总结
操作时必须把数据读出才行,不可以忽略



guijial511 发表于 2021-6-7 20:56

感谢楼主的分享经验
页: [1]
查看完整版本: 关于HC32L136k8硬件SPI调试