#include "stm32f4xx_hal.h"
#include "main.h"
#include "OLED.h"
#include "SPI.h"
#define OLED_CS_Set() //OLED_CS_GPIO_Port->ODR |= OLED_CS_Pin
#define OLED_CS_Clr() //OLED_CS_GPIO_Port->ODR &=~OLED_CS_Pin
void Delay_ms(uint32_t ms) {
ms+=HAL_GetTick();
while (HAL_GetTick()<=ms);
}
void OLED_WR_Dat(uint8_t da) {
//spi1发送
LL_SPI_TransmitData8(SPI1,da);
while (!LL_SPI_IsActiveFlag_TXE(SPI1));
while (LL_SPI_IsActiveFlag_BSY(SPI1));
}
void OLED_WR_Cmd(uint8_t da) {
OLED_DC_GPIO_Port->ODR &= ~OLED_DC_Pin;
OLED_WR_Dat(da);
OLED_DC_GPIO_Port->ODR |= OLED_DC_Pin;
}
//设置行列地址
void OLED_Set_Pos(unsigned char x, unsigned char y) {
OLED_WR_Cmd(0xb0+y);
OLED_WR_Cmd(((x&0xf0)>>4)|0x10);
OLED_WR_Cmd((x&0x0f)|0x01);
}
//开启OLED显示
void OLED_Display_On(void) {
OLED_WR_Cmd(0X8D ); //SET DCDC命令
OLED_WR_Cmd(0X14 ); //DCDC ON
OLED_WR_Cmd(0XAF ); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void) {
OLED_WR_Cmd(0X8D ); //SET DCDC命令
OLED_WR_Cmd(0X10 ); //DCDC OFF
OLED_WR_Cmd(0XAE ); //DISPLAY OFF
}
//清屏函数!
/**/void OLED_Clear(uint8_t da) {
uint16_t n;
for(n=0;n<128*8;n++) OLED_WR_Dat(da);
//数据低位在上!!
}
/**************************/
//1k刷屏缓冲区
uint8_t OLED_Buffer[OLEDBUFFER_SIZE];
uint32_t OLED_BufBitAddr;
static volatile uint16_t OLED_Refresh_Cnt=0;
void clsbuf(void) {
uint32_t i;
for (i=0;i<1024;i++)
OLED_Buffer[i]=0x0;
}
//初始化SSD1306
void Oled_Init(void) {
LL_SPI_Enable(SPI1);
OLED_CS_Clr();
OLED_DC_GPIO_Port->ODR |= OLED_DC_Pin;//默认数据状态
OLED_WR_Cmd(0xAE );//--turn off oled panel
OLED_WR_Cmd(0x00 );//---set low column address
OLED_WR_Cmd(0x10 );//---set high column address
OLED_WR_Cmd(0x40 );//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Cmd(0x81 );//--set contrast control register
OLED_WR_Cmd(0xCF ); // Set SEG Output Current Brightness
/****修改为左下起向上后右填充****/
OLED_WR_Cmd(0xA1 );//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Cmd(0xC0 );//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Cmd(0xA6 );//--set normal display
OLED_WR_Cmd(0xA8 );//--set multiplex ratio(1 to 64)
OLED_WR_Cmd(0x3f );//--1/64 duty
OLED_WR_Cmd(0xD3 );//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Cmd(0x00 );//-not offset
OLED_WR_Cmd(0xd5 );//--set display clock divide ratio/oscillator frequency
OLED_WR_Cmd(0x80 );//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Cmd(0xD9 );//--set pre-charge period
OLED_WR_Cmd(0xF1 );//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Cmd(0xDA );//--set com pins hardware configuration
OLED_WR_Cmd(0x12 );
OLED_WR_Cmd(0xDB );//--set vcomh
OLED_WR_Cmd(0x40 );//Set VCOM Deselect Level
OLED_WR_Cmd(0x20 );//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Cmd(0x01 );//00水平地址模式//01垂直地址模式
OLED_WR_Cmd(0x8D );//--set Charge Pump enable/disable
OLED_WR_Cmd(0x14 );//--set(0x10) disable
OLED_WR_Cmd(0xA4 );// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Cmd(0xA6 );// Disable Inverse Display On (0xa6/a7)
OLED_WR_Cmd(0xAF );//--turn on oled panel
OLED_Display_On();
OLED_BufBitAddr=0x22000000+((uint32_t)OLED_Buffer-0x20000000)*32;
clsbuf();
OLED_Refresh();
}
void SPI1_IRQHandler(void) {
// OLED_Refresh_Cnt++;
if (SPI1->SR & LL_SPI_SR_TXE) {
if (OLED_Refresh_Cnt<OLEDBUFFER_SIZE) {
//没完成
LL_SPI_TransmitData8(SPI1,OLED_Buffer[OLED_Refresh_Cnt&1023]);
OLED_Refresh_Cnt++;
//提前结束
if (OLED_Refresh_Cnt==OLEDBUFFER_SIZE) {
OLED_Refresh_Cnt=0;
LL_SPI_DisableIT_TXE(SPI1);
}
}
}}
void OLED_Refresh(void) {
LL_SPI_TransmitData8(SPI1,OLED_Buffer[0]);
OLED_Refresh_Cnt++;
LL_SPI_EnableIT_TXE(SPI1);
}
|