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

分享一个软件模拟SPI代码

[复制链接]
ctang 发布时间:2017-9-28 16:12
STM32电机培训online,大佬带你玩电机


因为硬件上连接到了普通的GPIO脚,不得不写软件模拟SPI,代码经过验证。如下:
  1. #ifndef __SPI_H
  2. #define __SPI_H

  3. /* Includes ------------------------------------------------------------------*/
  4. #include "stm32l0xx_hal.h"

  5. #define SPI_SCK_PIN                     GPIO_PIN_4
  6. #define SPI_SCK_GPIO_PORT               GPIOC
  7. #define SPI_MOSI_PIN                    GPIO_PIN_7
  8. #define SPI_MOSI_GPIO_PORT              GPIOC
  9. #define SPI_MISO_PIN                    GPIO_PIN_8
  10. #define SPI_MISO_GPIO_PORT              GPIOC
  11. #define SPI_NSS_PIN                     GPIO_PIN_6
  12. #define SPI_NSS_GPIO_PORT               GPIOC
  13. #define SPI_RESET_PIN                   GPIO_PIN_5
  14. #define SPI_RESET_GPIO_PORT             GPIOC

  15. #define SPI_SCK_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOC_CLK_ENABLE()
  16. #define SPI_MISO_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
  17. #define SPI_MOSI_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
  18. #define SPI_NSS_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOC_CLK_ENABLE()
  19. #define SPI_RESET_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOC_CLK_ENABLE()

  20. #define MOSI_H  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_SET)  
  21. #define MOSI_L  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_RESET)  
  22. #define SCK_H   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET)  
  23. #define SCK_L   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_RESET)  
  24. #define MISO    HAL_GPIO_ReadPin(SPI_MISO_GPIO_PORT, SPI_MISO_PIN)
  25. #define NSS_H   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_SET)  
  26. #define NSS_L   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_RESET)


  27. #define EEPROM_DAC_START_ADDR   DATA_EEPROM_BASE+6             /* Start @ of user EEPROM area */
  28. #define EEPROM_DAC_END_ADDR     (EEPROM_BIAS_START_ADDR + 16)   /* End @ of user EEPROM area */
  29. #define IS_DAC_DATA_ADDRESS(__ADDRESS__)          (((__ADDRESS__) >= EEPROM_DAC_START_ADDR) && ((__ADDRESS__) <= EEPROM_DAC_END_ADDR))
  30. #define IS_DAC_CH_ADDRESS(__ADDRESS__)          (((__ADDRESS__) >= 1) && ((__ADDRESS__) <= 4))

  31. void SPI_Init(void);
  32. uint16_t SPI_ReadWrite_Byte(uint8_t cmd_addr, uint16_t data);
  33. #endif
复制代码



  1. #include "spi.h"
  2. #include "main.h"
  3. #include "stm32l0xx_hal.h"

  4. void SPI_Init(void)
  5. {  
  6.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
  7.   /* Enable GPIO TX/RX clock */
  8.   SPI_SCK_GPIO_CLK_ENABLE();
  9.   SPI_MISO_GPIO_CLK_ENABLE();
  10.   SPI_MOSI_GPIO_CLK_ENABLE();
  11.   SPI_NSS_GPIO_CLK_ENABLE();
  12.   SPI_RESET_GPIO_CLK_ENABLE();

  13.   /*##-2- Configure peripheral GPIO ##########################################*/
  14.   /* SPI SCK GPIO pin configuration  */
  15.   GPIO_InitTypeDef GPIO_InitStruct;
  16.   
  17.   GPIO_InitStruct.Pin       = SPI_SCK_PIN;
  18.   GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
  19.   //GPIO_InitStruct.Pull      = GPIO_PULLDOWN;
  20.   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  21.   HAL_GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStruct);
  22.   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET);

  23.   /* SPI MISO GPIO pin configuration  */
  24.   GPIO_InitStruct.Pin = SPI_MISO_PIN;
  25.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  26.   HAL_GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStruct);

  27.   /* SPI MOSI GPIO pin configuration  */
  28.   GPIO_InitStruct.Pin = SPI_MOSI_PIN;
  29.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  30.   HAL_GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStruct);
  31.   HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_SET);
  32.   
  33.   GPIO_InitStruct.Pin = SPI_NSS_PIN;
  34.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  35.   HAL_GPIO_Init(SPI_NSS_GPIO_PORT, &GPIO_InitStruct);
  36.   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_SET);
  37.   
  38.   GPIO_InitStruct.Pin = SPI_RESET_PIN;
  39.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  40.   HAL_GPIO_Init(SPI_RESET_GPIO_PORT, &GPIO_InitStruct);
  41.   HAL_GPIO_WritePin(SPI_RESET_GPIO_PORT, SPI_RESET_PIN, GPIO_PIN_SET);
  42. }

  43. uint16_t SPI_ReadWrite_Byte(uint8_t cmd_addr, uint16_t data)
  44. {  
  45.   uint16_t temp=0;
  46.   SPI_Init();
  47.   NSS_L;  
  48.   SCK_H;   
  49.   __NOP();             /*读取第一bit数据 等待数据稳定 根据实际时钟调整*/
  50.   for(uint8_t i=0;i<8;i++)
  51.   {   
  52.     if(cmd_addr&0x80)
  53.     {
  54.       MOSI_H;          /*若最高位为高,则输出高*/
  55.     }
  56.     else
  57.     {
  58.       MOSI_L;          /*若最高位为低,则输出低*/   
  59.     }   
  60.     __NOP();
  61.     cmd_addr <<= 1;
  62.     SCK_L;
  63.     temp <<= 1;        /*数据左移*/
  64.     if(MISO)
  65.     {
  66.       temp++;          /*若从从机接收到高电平,数据自加一*/
  67.     }
  68.     SCK_H;
  69.   }
  70.    
  71.   data <<= 6;
  72.   
  73.   for(uint8_t i=0;i<16;i++)
  74.   {   
  75.     if(data&0x8000)
  76.     {
  77.       MOSI_H;          /*若最高位为高,则输出高*/
  78.     }
  79.     else
  80.     {
  81.       MOSI_L;          /*若最高位为低,则输出低*/   
  82.     }   
  83.     __NOP();
  84.     data <<= 1;
  85.     SCK_L;
  86.     temp <<= 1;        /*数据左移*/
  87.     if(MISO)
  88.     {
  89.       temp++;          /*若从从机接收到高电平,数据自加一*/
  90.     }
  91.     SCK_H;
  92.   }
  93.   NSS_H;
  94.   MOSI_H;
  95.   return temp;
  96. }
复制代码


收藏 7 评论10 发布时间:2017-9-28 16:12

举报

10个回答
Inc_brza 回答时间:2017-9-28 16:25:16
谢谢分享
斜阳 回答时间:2017-9-28 16:38:23
谢谢分享
七哥 回答时间:2017-9-28 17:39:58
有个有用,谢谢分享
左岸右岸 回答时间:2017-9-28 18:57:27
谢谢分享
Paderboy 回答时间:2017-9-28 19:41:23
多谢分享。。。
epochal 回答时间:2017-9-28 21:47:23
谢谢分享!
五哥1 回答时间:2017-10-1 08:35:54
先谢谢楼主分享,楼主这个在神马芯片上测试成功过,可以移植到L系列吗?
ctang 回答时间:2017-10-9 09:21:22
本帖最后由 ctang 于 2017-10-9 09:25 编辑
五哥1 发表于 2017-10-1 08:35
先谢谢楼主分享,楼主这个在神马芯片上测试成功过,可以移植到L系列吗?

在MCU STM32L073RZ上。移植的话,需要简单修改下SPI_ReadWrite_Byte函数,例子里面是按32bit为一个数据包发送的。
oceane 回答时间:2018-3-17 10:52:17
谢谢分享
jianzhirao 回答时间:2018-3-17 13:38:52
谢谢分享

所属标签

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