你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8L 调试硬件3线SPI 分享

[复制链接]
horsdy 发布时间:2018-6-26 11:19
这次调试SPI, 在网上查了不少资料, 特别是论坛上的, 现在硬件3线SPI已调通, 跟大家分享下.
由于外设是3线spi,MCU不得不也跟着使用3线SPI.

MCU: STM8L051F3
外设: A7139
操作寄存器方式: 官方库函数
SPI: 3线

主要步骤:
1 初始化
  • 主设备的时钟极性, 时钟相位一定要与从设备保持一致,即CPOL CPHA;
  • 设置单线双向;
  • 主从的速率不能相差太多;(本人的读写数据存在错误,一直以为是读写函数逻辑的问题,后来降低速率,读写变得正常了,原来是速率的问题)

/**
  * @brief  Initializes the SPI and CS pins.
  * @param  None
  * @retval None
  */
void SPI_LowLevel_Init(void)
{
  /* Enable SPI clock */
  CLK_PeripheralClockConfig(SPI_CLK, ENABLE);

  /* Set the MOSI,MISO and SCK at high level */
  GPIO_ExternalPullUpConfig(SPI_SCK_GPIO_PORT, SPI_MISO_PIN | SPI_MOSI_PIN | \
                            SPI_SCK_PIN, ENABLE);

  /* SPI Config */
  SPI_Init(SPI, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,
           SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_1Line_Tx /*SPI_Direction_2Lines_FullDuplex*/,
           SPI_NSS_Soft, 0x07);

  /* SPI enable */
  SPI_Cmd(SPI, ENABLE);

  /* Set MSD ChipSelect pin in Output push-pull high level */
  GPIO_Init(CS_GPIO_PORT, CS_PIN, GPIO_Mode_Out_PP_High_Slow);
}

2 读写函数
  • 注意当SPI处于单线双向的RX模式时,CLOCK是一直存在的;
  • 注意在适当时候设置SPI为RX模式或TX模式, 本人的做法是要初始化设为TX, 要接收时先设置为RX,接收完再设置为TX;
  • 注意使用BUSY标志;
  • 写函数注意当数据被赋值给SPI的DR,数据没有立即发送出去,一定要等到BUSY=0;

/**
  * @brief  Write a byte .
  * @param  Data: byte to send.
  * @retval None
  */
uint8_t SPIx_WriteByte(uint8_t Data)
{
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx); //设置单线为发送

  /*!< Wait until SPI is not busy */  
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
  {}

  /*!< Send the byte */
  SPI_SendData(SPI, Data);

  /*!< Wait until SPI is not busy */
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
  {}

  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
  return 1;
}

/**
  * @brief  Read a byte .
  * @param  None
  * @retval The received byte.
  */
uint8_t SPIx_ReadByte(void)
{
  uint8_t Data = 0;
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
  //SPI_Cmd(SPI, ENABLE);

  /* Wait untils SPI is working */
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) == SET);

  /*!< Wait until a data is received */
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_RXNE) == RESET)
  {}
  /*!< Get the received data */
  Data = SPI_ReceiveData(SPI);

  //SPI_Cmd(SPI, DISABLE);
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);
  /*!< Return the shifted data */
  return Data;
}

void A7139_SetCID(Uint32 id)
{
        SPI_CS_LOW(); //SCS=0;
        SPIx_WriteByte(CMD_CID_W);
        SPIx_WriteByte((Uint8)(id>>24));
        SPIx_WriteByte((Uint8)(id>>16));
        SPIx_WriteByte((Uint8)(id>>8));
        SPIx_WriteByte((Uint8)id);
        SPI_CS_HIGH(); //SCS=1;
}

Uint32 A7139_ReadCID(void)
{
        Uint32 data = 0;
        Uint8 i = 0;
        Uint32 byte[4] = {0};

        SPI_CS_LOW();
        SPIx_WriteByte(CMD_CID_R);
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
//        for (i = 0; i < 4; i++)
//        {
//                data = data << 8;
//                data |= SPIx_ReadByte();
//        }
        byte[0] = SPIx_ReadByte();
        byte[1] = SPIx_ReadByte();
        byte[2] = SPIx_ReadByte();
        byte[3] = SPIx_ReadByte();

        data = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);
        SPI_CS_HIGH();

        return data;
}


收藏 评论1 发布时间:2018-6-26 11:19

举报

1个回答
zero99 回答时间:2018-6-29 10:33:56
谢谢分享,楼主可以考虑用下面的工具,代码看起来更舒服
https://www.stmcu.org.cn/module/forum/thread-612887-1-1.html

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版