SSD1306 OLED屏幕驅動


淘寶隔壁老王家的OLED運動手環,非常的便宜2RMB一個。

Part0:可用器件列表

0x00: OLDE屏幕:0.91 inch,分辨率:128*32,主控:SSD1306,接口:SPI,顏色:亮白



0x01: CP2104 USB轉串口芯片,I/O電壓:3V ~ 3.6V,功能:橋,USB 至 UART,數據速率:2Mbps
這個芯片,JLC單賣9元左右,可以說2元買來只要USB2UART芯片是好的就能回本的。




0x02: 24C256 EEPROM存儲芯片,32KB,品牌未知,數據手冊可以參考ISSI24C256,I2C接口。




0x03: 其他元件,8M晶振,三線震動開關(計步用?),LTH7 4.2V單節鋰電充電芯片,單片機型號抹了絲印無從查起:(...


Part1:0.91inch OLED驅動

先上效果圖,5*7 ASCII字體顯示溫濕度信息。



屏幕引腳定義:


飛線進行連接,需要連接的引腳有(VDDB、VDD接3.3V)、(VSS接地)、(CS#片選)、(RES#復位)、(D/C#數據/命令控制線)、(SCLK SPI時鍾)、(SDIN SPI的MOSI)
C2P-C2N、C1P-C1N接1000nF無極性電容,IREF 串接400K歐姆電阻接地,VCOMH、VCC串接2uF無極性電容接地,屏幕驅動測試這些都可以用板子上的,參數僅作為后期制作轉接板參考用。

驅動程序見我的github:https://github.com/Yanye0xFF/ESP8266-SSD1306


SSD1306驅動解析
上電時序:

第一步:給屏幕VDD腳加電,這里同時也給VDDB腳加電。

第二步:拉低RES#腳至少3微秒,然后再拉高,產生一個上升沿復位脈沖。
第三步:執行初始化步驟,設置顯示時鍾,內置buffer偏移地址,屏幕亮度等,具體可以參考上方git代碼與SSD1306手冊。

/**
 * @brief 屏幕復位,拉低RES#至少3us后拉高。
 * */
void ICACHE_FLASH_ATTR ssd1306Reset() {
	GPIO_OUTPUT_SET(RESET_PIN_NUM, GPIO_PIN_LOW);
	os_delay_us(10);
	GPIO_OUTPUT_SET(RESET_PIN_NUM, GPIO_PIN_HIGH);
}
#define CMD_CONTRAST       (0x81u)
#define CMD_DISPLAY_ON     (0xAFu)
#define CMD_DISPLAY_OFF    (0xAEu)
#define CMD_DISPLAY_OFFSET    (0xD3u)
#define CMD_DISPLAY_CLK_DIV   (0xD5u)

static const uint32_t INIT_CMD_LEN = 22;
static const uint8_t INIT_COMMANDS[] = {CMD_DISPLAY_OFF, CMD_DISPLAY_CLK_DIV, 0x80, 0xA8, 0x1F, CMD_DISPLAY_OFFSET,
		0x00, 0x40, 0x8D, 0x14, 0xA0, 0xC0, 0xDA, 0x02, CMD_CONTRAST, 0x00, 0xD9, 0xF1, 0xDB, 0x64, 0xA4, 0xA6};
/**
 * @brief SSD1306初始化,先發送0xAE關閉顯示,再則放初始化數據,然后填充數據清屏,最后發送0xAF打開顯示。
 * */
void ICACHE_FLASH_ATTR ssd1306Init() {
	uint32_t i = 0, j = 0;
	// send init commands
	for(; i < INIT_CMD_LEN; i++) {
		ssd1306SendCmd(*(INIT_COMMANDS + i));
	}
	// clear oled display data;
	for(i = 0; i < 4; i++) {
		ssd1306SendCmd(0xB0 + i);
		for(j = 0; j < 128; j++) {
			ssd1306SendData(0x00);
		}
	}
	// turn on display
	ssd1306SendCmd(0xAF);
}

SSD1306 內置顯存組織:

由於該屏幕物理分辨率為128*32,因此片內顯存只使用了Page0~Page3,掃描方式最小區域是一個Page,由於SSD1306支持顯存地址重映射(方便實現鏡像功能),在本文的驅動代碼中使用的是默認地址,即上圖黑色字體部分。
掃描方式:

MCU內存刷新到顯存方式:
monochrom模式 1bit顏色,一個字節表示8像素。

#define DISPLAY_WIDTH    128
#define DISPLAY_HEIGHT   32
#define DISPLAY_PAGE     4
static uint8_t *DISPLAY_BUFFER;
DISPLAY_BUFFER = (uint8_t *)os_malloc(sizeof(uint8_t) * (DISPLAY_WIDTH >> 3) * DISPLAY_HEIGHT);

/**
 * @brief Page0的地址為B0,一個page為128*8像素,單個page內縱向掃描,一次發送一字節;由此依次進行Page1,Page2...
 * */
void ssd1306Flush() {
	uint32_t page, column, i;
	uint8_t data, byte;
	for(page = 0; page < DISPLAY_PAGE; page++) {
		ssd1306SendCmd(0xB0 + page);
		for(column = 0; column < DISPLAY_WIDTH; column++) {
			// cat data
			for(i = 0, data = 0x00; i < 8; i++) {
				byte = *(DISPLAY_BUFFER + (page * 128) + (i << 4) + (column >> 3));
				data |= (((byte >> (column % 8)) & 0x1) << i);
			}
			ssd1306SendData(data);
		}
	}
}

Part2:制作USB2UART轉接小板

這一步非常簡單,按照CP2104原理圖飛線即可,這里我僅接出了TXD、RXD和必要的電源與地,需要流控信號的還可以從芯片引腳上飛出DTR、DSR、RTS...

Part3:SSD1306、CP2104技術手冊下載


https://files.cnblogs.com/files/yanye0xff/doc.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM