SPIポートが不足しているため、アナログSPIを使用し、プログラムは比較的単純です。SPIモード0を使用します。処理中、ポートは通信できません。ロジックアナライザを使用した後、クロックラインが見つかりました。時計が間違っているので問題ありません。
#define SSD1306_SOFT_SPI_MOSI_PORT OLED_DATA_GPIO_Port
#define SSD1306_SOFT_SPI_MOSI_PIN OLED_DATA_Pin
#define SSD1306_SOFT_SPI_MISO_PORT OLED_DATA_GPIO_Port
#define SSD1306_SOFT_SPI_MISO_PIN OLED_DATA_Pin
#define SSD1306_SOFT_SPI_CLK_PORT OLED_CLK_GPIO_Port
#define SSD1306_SOFT_SPI_CLK_PIN OLED_CLK_Pin
#define SSD1306_CLK_RESET HAL_GPIO_WritePin(SSD1306_SOFT_SPI_CLK_PORT, SSD1306_SOFT_SPI_CLK_PIN, GPIO_PIN_RESET)
#define SSD1306_CLK_SET HAL_GPIO_WritePin(SSD1306_SOFT_SPI_CLK_PORT, SSD1306_SOFT_SPI_CLK_PIN, GPIO_PIN_SET)
#define SSD1306_MOSI_RESET HAL_GPIO_WritePin(SSD1306_SOFT_SPI_MOSI_PORT, SSD1306_SOFT_SPI_MOSI_PIN, GPIO_PIN_RESET)
#define SSD1306_MOSI_SET HAL_GPIO_WritePin(SSD1306_SOFT_SPI_MOSI_PORT, SSD1306_SOFT_SPI_MOSI_PIN, GPIO_PIN_SET)
#define SSD1306_MOSI_IN HAL_GPIO_ReadPin(SSD1306_SOFT_SPI_MISO_PORT, SSD1306_SOFT_SPI_MISO_PIN)
uint8_t software_spi_wr(uint8_t data){
//模式0
uint8_t i, temp = 0;
//CLK = 0
SSD1306_CLK_RESET;
for(i=0;i<8;i++){
SSD1306_CLK_RESET;
if(data&0x80) SSD1306_MOSI_SET;
else SSD1306_MOSI_RESET;
data<<=1;
SSD1306_CLK_SET;
//如果不用读的功能,添加这句话,进行几个时钟周期的延时
SSD1306_CLK_SET;
//如果要读,取下下面注释,并注释上面的延时
//temp <<=1;
//temp += SSD1306_MOSI_IN;
}
SSD1306_CLK_RESET;
return temp;
}