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

分享一个软件模拟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
谢谢分享
toofree 回答时间: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
谢谢分享
12下一页

所属标签

STM32团队

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


最新内容

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