#define PORT_SPI_SE0_CS_ON() {} #define PORT_SPI_SE0_CS_OFF() {}
时间: 2024-08-12 13:01:05 浏览: 45
这两个宏定义看起来像是用于配置某个SPI(Serial Peripheral Interface,串行外设接口)通信中信号线的操作。`#define` 是预处理器指令,在C语言中用于创建常量替换,这里的PORT_SPI_SE0_CS_ON() 和 PORT_SPI_SE0_CS_OFF() 应该分别表示使能(SE0 CS接高电平,即Chip Select ON)和禁用(SE0 CS接低电平,即Chip Select OFF)SPI从设备的选择信号线(CS,Chip Select)。
它们的作用可能是通过设置硬件寄存器或者直接操作IO口,使得程序能够控制SPI总线连接的器件是否可以接收或发送数据。当需要选择某个设备工作时,会调用 `PORT_SPI_SE0_CS_ON()`;相反,如果想要暂时断开通信并暂停该设备的访问,则会调用 `PORT_SPI_SE0_CS_OFF()`。
相关问题
STM32系列(HAL库)——F103C8T6使用SPI方式点亮OLED
好的,下面是使用STM32 HAL库,通过SPI方式驱动OLED的基本步骤:
1. 初始化SPI接口
在使用SPI接口前需要先对其进行初始化,包括SPI引脚配置、时钟配置和SPI参数配置等,具体代码如下:
```c
/*定义SPI句柄*/
SPI_HandleTypeDef hspi1;
/*初始化SPI*/
void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
```
2. 初始化OLED
在使用OLED前需要对其进行初始化,包括GPIO配置、时钟配置和OLED参数配置等,具体代码如下:
```c
/*OLED硬件SPI引脚定义*/
#define OLED_SPI_CS_GPIO_Port GPIOA
#define OLED_SPI_CS_Pin GPIO_PIN_4
#define OLED_SPI_DC_GPIO_Port GPIOA
#define OLED_SPI_DC_Pin GPIO_PIN_3
/*初始化OLED*/
void OLED_Init(void)
{
/*配置OLED SPI接口的片选引脚*/
HAL_GPIO_WritePin(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin, GPIO_PIN_SET);
/*配置OLED SPI接口的DC引脚*/
HAL_GPIO_WritePin(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin, GPIO_PIN_SET);
/*配置OLED SPI接口的RESET引脚*/
OLED_RST_Set();
HAL_Delay(100);
OLED_RST_Clr();
HAL_Delay(100);
OLED_RST_Set();
HAL_Delay(100);
/*初始化OLED*/
OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00,OLED_CMD);//-not offset
OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
OLED_Clear();
}
```
3. 实现SPI传输函数
SPI传输函数是使用SPI接口与OLED进行数据传输的函数,具体代码如下:
```c
/*OLED硬件SPI引脚定义*/
#define OLED_SPI_CS_GPIO_Port GPIOA
#define OLED_SPI_CS_Pin GPIO_PIN_4
#define OLED_SPI_DC_GPIO_Port GPIOA
#define OLED_SPI_DC_Pin GPIO_PIN_3
/*OLED写数据*/
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
if(cmd)
{
HAL_GPIO_WritePin(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin, GPIO_PIN_RESET);
}
/*使能OLED*/
HAL_GPIO_WritePin(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin, GPIO_PIN_RESET);
/*通过SPI发送数据*/
HAL_SPI_Transmit(&hspi1,&dat,1,1000);
/*关闭OLED*/
HAL_GPIO_WritePin(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin, GPIO_PIN_SET);
}
/*OLED写数据*/
void OLED_WR_LByte(uint8_t dat,uint8_t cmd)
{
uint8_t data[2];
data[0] = dat;
data[1] = 0x00;
if(cmd)
{
HAL_GPIO_WritePin(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(OLED_SPI_DC_GPIO_Port, OLED_SPI_DC_Pin, GPIO_PIN_RESET);
}
/*使能OLED*/
HAL_GPIO_WritePin(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin, GPIO_PIN_RESET);
/*通过SPI发送数据*/
HAL_SPI_Transmit(&hspi1,data,2,1000);
/*关闭OLED*/
HAL_GPIO_WritePin(OLED_SPI_CS_GPIO_Port, OLED_SPI_CS_Pin, GPIO_PIN_SET);
}
```
4. 实现OLED显示函数
OLED显示函数是向OLED发送数据实现显示的函数,具体代码如下:
```c
/*OLED写数据*/
void OLED_WR_BP(uint8_t dat)
{
uint8_t i;
for(i=0;i<8;i++)
{
if(dat&0x80)
OLED_WR_Byte(0xff,OLED_DATA);
else
OLED_WR_Byte(0x00,OLED_DATA);
dat<<=1;
}
}
/*清屏*/
void OLED_Clear(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
}
}
```
5. 调用OLED显示函数
初始化完成后,就可以调用OLED显示函数来实现向OLED发送数据实现显示了,具体代码如下:
```c
int main(void)
{
/*初始化*/
HAL_Init();
MX_SPI1_Init();
OLED_Init();
/*显示*/
OLED_Clear();
OLED_ShowString(0,0,"Hello World!",16);
while (1)
{
}
}
```
以上就是通过SPI接口驱动OLED的基本步骤,需要注意的是具体的硬件引脚配置和参数配置需要根据实际情况进行修改。
SSD1309 SPI驱动代码
以下是一个基于STM32的SSD1309 SPI驱动代码示例:
```c
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#define SSD1309_DC_PIN GPIO_Pin_6
#define SSD1309_DC_PORT GPIOB
#define SSD1309_CS_PIN GPIO_Pin_7
#define SSD1309_CS_PORT GPIOB
#define SSD1309_RST_PIN GPIO_Pin_8
#define SSD1309_RST_PORT GPIOB
#define SSD1309_WIDTH 128
#define SSD1309_HEIGHT 64
static uint8_t ssd1309_buffer[SSD1309_WIDTH * SSD1309_HEIGHT / 8];
void ssd1309_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* GPIO clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* SPI clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* Configure SCK, MOSI and NSS pins as Alternate Function Push Pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure DC, CS and RST pins as Output Push Pull */
GPIO_InitStructure.GPIO_Pin = SSD1309_DC_PIN | SSD1309_CS_PIN | SSD1309_RST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SSD1309_DC_PORT, &GPIO_InitStructure);
/* Set RST pin low to reset SSD1309 */
GPIO_ResetBits(SSD1309_RST_PORT, SSD1309_RST_PIN);
Delay(10);
GPIO_SetBits(SSD1309_RST_PORT, SSD1309_RST_PIN);
Delay(10);
/* Configure SPI */
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* Enable SPI */
SPI_Cmd(SPI2, ENABLE);
/* Initialize SSD1309 */
ssd1309_command(0xAE); // Display off
ssd1309_command(0xD5); // Set display clock divide ratio/oscillator frequency
ssd1309_command(0x80); // Set divide ratio
ssd1309_command(0xA8); // Set multiplex ratio
ssd1309_command(0x3F); // Set to 64 COM lines
ssd1309_command(0xD3); // Set display offset
ssd1309_command(0x00); // No offset
ssd1309_command(0x40); // Set display start line
ssd1309_command(0x8D); // Charge pump
ssd1309_command(0x14); // Enable charge pump
ssd1309_command(0x20); // Set memory addressing mode
ssd1309_command(0x00); // Horizontal addressing mode
ssd1309_command(0xA0); // Set segment remap
ssd1309_command(0xC8); // Set COM output scan direction
ssd1309_command(0xDA); // Set COM pins hardware configuration
ssd1309_command(0x12); // Alternative configuration
ssd1309_command(0x81); // Set contrast control
ssd1309_command(0xCF); // Set contrast
ssd1309_command(0xD9); // Set pre-charge period
ssd1309_command(0xF1); // Phase 1 period of 15 DCLKs, Phase 2 period of 1 DCLK
ssd1309_command(0xDB); // Set VCOMH deselect level
ssd1309_command(0x40); // 0.77*VCC
ssd1309_command(0xA4); // Set entire display on/off
ssd1309_command(0xA6); // Set normal display
ssd1309_command(0xAF); // Display on
}
void ssd1309_command(uint8_t cmd)
{
GPIO_ResetBits(SSD1309_DC_PORT, SSD1309_DC_PIN);
GPIO_ResetBits(SSD1309_CS_PORT, SSD1309_CS_PIN);
SPI_I2S_SendData(SPI2, cmd);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
GPIO_SetBits(SSD1309_CS_PORT, SSD1309_CS_PIN);
}
void ssd1309_data(uint8_t *data, uint32_t size)
{
GPIO_SetBits(SSD1309_DC_PORT, SSD1309_DC_PIN);
GPIO_ResetBits(SSD1309_CS_PORT, SSD1309_CS_PIN);
while (size--) {
SPI_I2S_SendData(SPI2, *data++);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
}
GPIO_SetBits(SSD1309_CS_PORT, SSD1309_CS_PIN);
}
void ssd1309_display(void)
{
ssd1309_command(0x21); // Set column address
ssd1309_command(0x00); // Column start address
ssd1309_command(0x7F); // Column end address
ssd1309_command(0x22); // Set page address
ssd1309_command(0x00); // Page start address
ssd1309_command(0x07); // Page end address
ssd1309_data(ssd1309_buffer, sizeof(ssd1309_buffer));
}
void ssd1309_clear(void)
{
memset(ssd1309_buffer, 0, sizeof(ssd1309_buffer));
}
```
这个驱动代码基于STM32F10x系列芯片,使用SPI2控制SSD1309 OLED显示屏。在初始化函数`ssd1309_init()`中,首先配置GPIO和SPI,然后通过I/O口控制SSD1309的复位和初始化。接着,发送一系列命令配置SSD1309的工作模式和显示参数。在`ssd1309_command()`和`ssd1309_data()`函数中,使用SPI接口向SSD1309发送命令和数据。最后,`ssd1309_display()`函数将屏幕缓存中的数据写入SSD1309,`ssd1309_clear()`函数将屏幕缓存清空。
阅读全文