[应用相关] stm32 软件模拟SPI代码

[复制链接]
 楼主| hanzhen654 发表于 2018-8-24 13:51 | 显示全部楼层 |阅读模式
自己画了一块stm32的板子,因为spi没用接到固定的引脚上面不得不用这种方式。
引脚定义:
  1. #define SPI_SCK_PIN                     GPIO_PIN_4
  2. #define SPI_SCK_GPIO_PORT               GPIOC
  3. #define SPI_MOSI_PIN                    GPIO_PIN_7
  4. #define SPI_MOSI_GPIO_PORT              GPIOC
  5. #define SPI_MISO_PIN                    GPIO_PIN_8
  6. #define SPI_MISO_GPIO_PORT              GPIOC
  7. #define SPI_NSS_PIN                     GPIO_PIN_6
  8. #define SPI_NSS_GPIO_PORT               GPIOC
  9. #define SPI_RESET_PIN                   GPIO_PIN_5
  10. #define SPI_RESET_GPIO_PORT             GPIOC


 楼主| hanzhen654 发表于 2018-8-24 13:53 | 显示全部楼层
定义时钟使能
  1. #define SPI_SCK_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOC_CLK_ENABLE()
  2. #define SPI_MISO_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
  3. #define SPI_MOSI_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
  4. #define SPI_NSS_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOC_CLK_ENABLE()
  5. #define SPI_RESET_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOC_CLK_ENABLE()


 楼主| hanzhen654 发表于 2018-8-24 13:55 | 显示全部楼层
定义片选高低信号,类似sys.h
  1. #define MOSI_H  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_SET)  
  2. #define MOSI_L  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_RESET)  
  3. #define SCK_H   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET)  
  4. #define SCK_L   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_RESET)  
  5. #define MISO    HAL_GPIO_ReadPin(SPI_MISO_GPIO_PORT, SPI_MISO_PIN)
  6. #define NSS_H   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_SET)  
  7. #define NSS_L   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_RESET)


 楼主| hanzhen654 发表于 2018-8-24 13:56 | 显示全部楼层
定义相关EEPROM地址
  1. #define EEPROM_DAC_START_ADDR   DATA_EEPROM_BASE+6             /* Start [url=home.php?mod=space&uid=72445]@[/url] of user EEPROM area */
  2. #define EEPROM_DAC_END_ADDR     (EEPROM_BIAS_START_ADDR + 16)   /* End @ of user EEPROM area */
  3. #define IS_DAC_DATA_ADDRESS(__ADDRESS__)          (((__ADDRESS__) >= EEPROM_DAC_START_ADDR) && ((__ADDRESS__) <= EEPROM_DAC_END_ADDR))
  4. #define IS_DAC_CH_ADDRESS(__ADDRESS__)          (((__ADDRESS__) >= 1) && ((__ADDRESS__) <= 4))


 楼主| hanzhen654 发表于 2018-8-24 13:57 | 显示全部楼层
函数声明,包括SPI初始化,SPI读写函数
  1. void SPI_Init(void);
  2. uint16_t SPI_ReadWrite_Byte(uint8_t cmd_addr, uint16_t data);


 楼主| hanzhen654 发表于 2018-8-24 14:01 | 显示全部楼层
SPI初始化
  1. void SPI_Init(void)
  2. {  
  3.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
  4.   /* Enable GPIO TX/RX clock */
  5.   SPI_SCK_GPIO_CLK_ENABLE();
  6.   SPI_MISO_GPIO_CLK_ENABLE();
  7.   SPI_MOSI_GPIO_CLK_ENABLE();
  8.   SPI_NSS_GPIO_CLK_ENABLE();
  9.   SPI_RESET_GPIO_CLK_ENABLE();

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

  20.   /* SPI MISO GPIO pin configuration  */
  21.   GPIO_InitStruct.Pin = SPI_MISO_PIN;
  22.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  23.   HAL_GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStruct);

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


 楼主| hanzhen654 发表于 2018-8-24 14:02 | 显示全部楼层
SPI读写函数
  1. uint16_t SPI_ReadWrite_Byte(uint8_t cmd_addr, uint16_t data)
  2. {  
  3.   uint16_t temp=0;
  4.   SPI_Init();
  5.   NSS_L;  
  6.   SCK_H;   
  7.   __NOP();             /*读取第一bit数据 等待数据稳定 根据实际时钟调整*/
  8.   for(uint8_t i=0;i<8;i++)
  9.   {   
  10.     if(cmd_addr&0x80)
  11.     {
  12.       MOSI_H;          /*若最高位为高,则输出高*/
  13.     }
  14.     else
  15.     {
  16.       MOSI_L;          /*若最高位为低,则输出低*/   
  17.     }   
  18.     __NOP();
  19.     cmd_addr <<= 1;
  20.     SCK_L;
  21.     temp <<= 1;        /*数据左移*/
  22.     if(MISO)
  23.     {
  24.       temp++;          /*若从从机接收到高电平,数据自加一*/
  25.     }
  26.     SCK_H;
  27.   }
  28.    
  29.   data <<= 6;
  30.   
  31.   for(uint8_t i=0;i<16;i++)
  32.   {   
  33.     if(data&0x8000)
  34.     {
  35.       MOSI_H;          /*若最高位为高,则输出高*/
  36.     }
  37.     else
  38.     {
  39.       MOSI_L;          /*若最高位为低,则输出低*/   
  40.     }   
  41.     __NOP();
  42.     data <<= 1;
  43.     SCK_L;
  44.     temp <<= 1;        /*数据左移*/
  45.     if(MISO)
  46.     {
  47.       temp++;          /*若从从机接收到高电平,数据自加一*/
  48.     }
  49.     SCK_H;
  50.   }
  51.   NSS_H;
  52.   MOSI_H;
  53.   return temp;
  54. }


 楼主| hanzhen654 发表于 2018-8-24 14:03 | 显示全部楼层
大家可以通过基于SPI的传感器来测试,例如nrf24l01等。

评论

data <<= 6; data为什么要左移6位呢?  发表于 2020-5-19 23:26
zhuotuzi 发表于 2018-8-24 16:34 | 显示全部楼层
SPI是最好用IO模拟的串行通信协议。
stm32jy 发表于 2018-8-24 18:25 | 显示全部楼层
我一般用的是硬件SPI ,模拟的没怎么写过,
mintspring 发表于 2018-8-24 23:54 | 显示全部楼层
IO模拟的其实用的很多的。
guanjiaer 发表于 2018-9-7 09:53 | 显示全部楼层
hanzhen654 发表于 2018-8-24 13:56
定义相关EEPROM地址

这个跟eeprom有什么关系呢
guanjiaer 发表于 2018-9-7 10:04 | 显示全部楼层
hanzhen654 发表于 2018-8-24 13:56
定义相关EEPROM地址

这个跟eeprom有什么关系呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

1766

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部

73

主题

1766

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部