【完美体育·(中国)手机网页版MYD-Y6ULX-V2开发板】驱动OLED SSD1306
文章来源: 发布日期:2023.2.21 浏览次数:732 次 |
由评测者“华仔stm32”提供。
开发板的外设I2C是常用的外设之一,温湿度传感器、OLED等都是经过i2c的总线驱动,今天驱动常用的OLED ssd1306。
1、硬件接线如下图,J14的19脚为SDA,20脚为SCL:
(备注)手册上有误,手册上写的是i2c2,但是在设备管理器里面是i2c1。
2、在ubuntu上创建ssd1306.c、ssd1306.h、main.c,以及字库。
ssd1306.c:
#include "ssd1306.h" void SSD1306_init(void) { m_font_offset = 2; //I2C init ssd1306_i2c_devfd = open(SSD1306_I2C_DEVFILE, O_RDWR); if(ioctl(ssd1306_i2c_devfd, I2C_SLAVE, SSD1306_I2C_ADDR)<0 ) { printf("SSD1306 ioctl error : %s\r\n", strerror(errno)); } SSD1306_sendCommand(0xAE); //display off SSD1306_sendCommand(0xA6); //Set Normal Display (default) SSD1306_sendCommand(0xAE); //DISPLAYOFF SSD1306_sendCommand(0xD5); //SETDISPLAYCLOCKDIV SSD1306_sendCommand(0x80); // the suggested ratio 0x80 SSD1306_sendCommand(0xA8); //SSD1306_SETMULTIPLEX SSD1306_sendCommand(0x3F); SSD1306_sendCommand(0xD3); //SETDISPLAYOFFSET SSD1306_sendCommand(0x0); //no offset SSD1306_sendCommand(0x40|0x0); //SETSTARTLINE SSD1306_sendCommand(0x8D); //CHARGEPUMP SSD1306_sendCommand(0x14); SSD1306_sendCommand(0x20); //MEMORYMODE SSD1306_sendCommand(0x00); //0x0 act like ks0108 SSD1306_sendCommand(0xA1); //SEGREMAP Mirror screen horizontally (A0) SSD1306_sendCommand(0xC8); //COMSCANDEC Rotate screen vertically (C0) SSD1306_sendCommand(0xDA); //0xDA SSD1306_sendCommand(0x12); //COMSCANDEC SSD1306_sendCommand(0x81); //SETCONTRAST SSD1306_sendCommand(0xCF); // SSD1306_sendCommand(0xd9); //SETPRECHARGE SSD1306_sendCommand(0xF1); SSD1306_sendCommand(0xDB); //SETVCOMDETECT SSD1306_sendCommand(0x40); SSD1306_sendCommand(0xA4); //DISPLAYALLON_RESUME SSD1306_sendCommand(0xA6); //NORMALDISPLAY SSD1306_clearDisplay(); SSD1306_sendCommand(0x2E); //Stop scroll SSD1306_sendCommand(0x20); //Set Memory Addressing Mode SSD1306_sendCommand(0x00); //Set Memory Addressing Mode ab Horizontal addressing mode SSD1306_setFont(font8x8); } void SSD1306_setFont(const uint8_t* font) { m_font = font; m_font_width = pgm_read_byte(&m_font[0]); } void SSD1306_sendCommand(unsigned char command) { uint8_t val[2]; val[0] = SSD1306_Command_Mode; val[1] = command; if( write(ssd1306_i2c_devfd, &val, 2) < 0 ) { printf("I2C write error\n"); } } void SSD1306_setBrightness(unsigned char Brightness) { SSD1306_sendCommand(SSD1306_Set_Brightness_Cmd); SSD1306_sendCommand(Brightness); } void SSD1306_setHorizontalMode() { addressingMode = HORIZONTAL_MODE; SSD1306_sendCommand(0x20); //set addressing mode SSD1306_sendCommand(0x00); //set horizontal addressing mode } void SSD1306_setPageMode() { addressingMode = PAGE_MODE; SSD1306_sendCommand(0x20); //set addressing mode SSD1306_sendCommand(0x02); //set page addressing mode } void SSD1306_setTextXY(unsigned char row, unsigned char col) { SSD1306_sendCommand(0xB0 + row); //set page address SSD1306_sendCommand(0x00 + (m_font_width*col & 0x0F)); //set column lower addr SSD1306_sendCommand(0x10 + ((m_font_width*col>>4)&0x0F)); //set column higher addr } void SSD1306_clearDisplay() { unsigned char i,j; SSD1306_sendCommand(SSD1306_Display_Off_Cmd); //display off for(j=0;j<8;j++) { SSD1306_setTextXY(j,0); { for(i=0;i<16;i++) //clear all columns { SSD1306_putChar(' '); } } } SSD1306_sendCommand(SSD1306_Display_On_Cmd); //display on SSD1306_setTextXY(0,0); } void SSD1306_sendData(unsigned char Data) { uint8_t val[2]; val[0] = SSD1306_Data_Mode; val[1] = Data; if( write(ssd1306_i2c_devfd, &val, 2) < 0 ) { printf("I2C write error\n"); } } int SSD1306_putChar(unsigned char ch) { if (!m_font) return 0; //Ignore non-printable ASCII characters. This can be modified for //multilingual font. if(ch < 32 || ch > 127) { ch = ' '; } unsigned char i = 0; for(i=0;i0) { char_buffer[i++] = long_num % 10; long_num /= 10; } f=f+i; for(; i > 0; i--) { SSD1306_putChar('0'+ char_buffer[i - 1]); } return f; } unsigned char SSD1306_putFloat(float floatNumber,unsigned char decimal) { unsigned int temp=0; float decy=0.0; float rounding = 0.5; unsigned char f=0; if(floatNumber<0.0) { SSD1306_putString("-"); floatNumber = -floatNumber; f +=1; } unsigned char i=0; for (i=0; i 0) { SSD1306_putChar('.'); f +=1; } decy = floatNumber-temp;//decimal part, for(i=0;i
ssd1306.h:
#ifndef SSD1306_H #define SSD1306_H #define pgm_read_byte(addr) (*(unsigned char *)(addr)) #define OLEDFONT(name) static const uint8_t name[] #include#include #include #include #include #include #include "font8x8.h" #include "font5x7.h" #define SSD1306_Max_X 127 //128 Pixels #define SSD1306_Max_Y 63 //64 Pixels #define PAGE_MODE 01 #define HORIZONTAL_MODE 02 #define SSD1306_Address 0x3C #define SSD1306_Command_Mode 0x00//0x80 #define SSD1306_Data_Mode 0x40 #define SSD1306_Display_Off_Cmd 0xAE #define SSD1306_Display_On_Cmd 0xAF #define SSD1306_Normal_Display_Cmd 0xA6 #define SSD1306_Inverse_Display_Cmd 0xA7 #define SSD1306_Activate_Scroll_Cmd 0x2F #define SSD1306_Dectivate_Scroll_Cmd 0x2E #define SSD1306_Set_Brightness_Cmd 0x81 #define Scroll_Left 0x00 #define Scroll_Right 0x01 #define Scroll_2Frames 0x7 #define Scroll_3Frames 0x4 #define Scroll_4Frames 0x5 #define Scroll_5Frames 0x0 #define Scroll_25Frames 0x6 #define Scroll_64Frames 0x1 #define Scroll_128Frames 0x2 #define Scroll_256Frames 0x3 /////////////////////////////////////////// // modify this for platform-compatibility // I2C device args /////////////////////////////////////////// #define SSD1306_I2C_DEVFILE "/dev/i2c-1" // Raspberry Pi (Pin 3 5) //#define SSD1306_I2C_DEVFILE "/dev/i2c-0" // Galileo Gen1 #define SSD1306_I2C_ADDR 0x3c // ==(SSD1306_Address) static int ssd1306_i2c_devfd = 0; const uint8_t* m_font; // Current font. static uint8_t m_font_offset = 2; // Font bytes for meta data. static uint8_t m_font_width; // Font witdth. static uint8_t m_col; // Cursor column. static uint8_t m_row; // Cursor row (RAM). static char addressingMode; void SSD1306_init(void); void SSD1306_setNormalDisplay(); void SSD1306_setInverseDisplay(); // modified void SSD1306_sendCommand(unsigned char command); void SSD1306_sendData(unsigned char Data); void SSD1306_setPageMode(); void SSD1306_setHorizontalMode(); void SSD1306_setTextXY(unsigned char Row, unsigned char Column); void SSD1306_clearDisplay(); void SSD1306_setBrightness(unsigned char Brightness); int SSD1306_putChar(unsigned char c); void SSD1306_putString(const char *string); unsigned char SSD1306_putNumber(long n); unsigned char SSD1306_putFloat(float floatNumber,unsigned char decimal); void SSD1306_drawBitmap(unsigned char *bitmaparray,int bytes); void SSD1306_setHorizontalScrollProperties( int direction, unsigned char startPage, unsigned char endPage, unsigned char scrollSpeed); void SSD1306_activateScroll(); void SSD1306_deactivateScroll(); void SSD1306_setFont(const uint8_t* font); #endif
字库:
#ifndef FONT8x8_H
#define FONT8x8_H // 8x8 Font ASCII 32 - 127 Implemented // Users can modify this to support more characters (glyphs) OLEDFONT(font8x8) = { 0x08, // width 0x08, // height 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00, // ! 0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00, // " 0x00,0x24,0x7E,0x24,0x24,0x7E,0x24,0x00, // # 0x00,0x2E,0x2A,0x7F,0x2A,0x3A,0x00,0x00, // $ 0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00, // % 0x00,0x20,0x54,0x4A,0x54,0x20,0x50,0x00, // & 0x00,0x00,0x00,0x04,0x02,0x00,0x00,0x00, // ' 0x00,0x00,0x00,0x3C,0x42,0x00,0x00,0x00, // ( 0x00,0x00,0x00,0x42,0x3C,0x00,0x00,0x00, // ) 0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00, // * 0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00, // + 0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00, // , 0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // - 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // . 0x00,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // / 0x3C,0x62,0x52,0x4A,0x46,0x3C,0x00,0x00, // 0 0x44,0x42,0x7E,0x40,0x40,0x00,0x00,0x00, // 1 0x64,0x52,0x52,0x52,0x52,0x4C,0x00,0x00, // 2 0x24,0x42,0x42,0x4A,0x4A,0x34,0x00,0x00, // 3 0x30,0x28,0x24,0x7E,0x20,0x20,0x00,0x00, // 4 0x2E,0x4A,0x4A,0x4A,0x4A,0x32,0x00,0x00, // 5 0x3C,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // 6 0x02,0x02,0x62,0x12,0x0A,0x06,0x00,0x00, // 7 0x34,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // 8 0x0C,0x52,0x52,0x52,0x52,0x3C,0x00,0x00, // 9 0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00, // : 0x00,0x00,0x80,0x64,0x00,0x00,0x00,0x00, // ; 0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00, // < 0x00,0x28,0x28,0x28,0x28,0x28,0x00,0x00, // = 0x00,0x00,0x44,0x28,0x10,0x00,0x00,0x00, // > 0x00,0x04,0x02,0x02,0x52,0x0A,0x04,0x00, // ? 0x00,0x3C,0x42,0x5A,0x56,0x5A,0x1C,0x00, // @ 0x7C,0x12,0x12,0x12,0x12,0x7C,0x00,0x00, // A 0x7E,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // B 0x3C,0x42,0x42,0x42,0x42,0x24,0x00,0x00, // C 0x7E,0x42,0x42,0x42,0x24,0x18,0x00,0x00, // D 0x7E,0x4A,0x4A,0x4A,0x4A,0x42,0x00,0x00, // E 0x7E,0x0A,0x0A,0x0A,0x0A,0x02,0x00,0x00, // F 0x3C,0x42,0x42,0x52,0x52,0x34,0x00,0x00, // G 0x7E,0x08,0x08,0x08,0x08,0x7E,0x00,0x00, // H 0x00,0x42,0x42,0x7E,0x42,0x42,0x00,0x00, // I 0x30,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // J 0x7E,0x08,0x08,0x14,0x22,0x40,0x00,0x00, // K 0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00, // L 0x7E,0x04,0x08,0x08,0x04,0x7E,0x00,0x00, // M 0x7E,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // N 0x3C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // O 0x7E,0x12,0x12,0x12,0x12,0x0C,0x00,0x00, // P 0x3C,0x42,0x52,0x62,0x42,0x3C,0x00,0x00, // Q 0x7E,0x12,0x12,0x12,0x32,0x4C,0x00,0x00, // R 0x24,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // S 0x02,0x02,0x02,0x7E,0x02,0x02,0x02,0x00, // T 0x3E,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // U 0x1E,0x20,0x40,0x40,0x20,0x1E,0x00,0x00, // V 0x3E,0x40,0x20,0x20,0x40,0x3E,0x00,0x00, // W 0x42,0x24,0x18,0x18,0x24,0x42,0x00,0x00, // X 0x02,0x04,0x08,0x70,0x08,0x04,0x02,0x00, // Y 0x42,0x62,0x52,0x4A,0x46,0x42,0x00,0x00, // Z 0x00,0x00,0x7E,0x42,0x42,0x00,0x00,0x00, // [ 0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // 0x00,0x00,0x42,0x42,0x7E,0x00,0x00,0x00, // ] 0x00,0x08,0x04,0x7E,0x04,0x08,0x00,0x00, // ^ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, // _ 0x3C,0x42,0x99,0xA5,0xA5,0x81,0x42,0x3C, // ` 0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00, // a 0x00,0x7E,0x48,0x48,0x48,0x30,0x00,0x00, // b 0x00,0x00,0x38,0x44,0x44,0x44,0x00,0x00, // c 0x00,0x30,0x48,0x48,0x48,0x7E,0x00,0x00, // d 0x00,0x38,0x54,0x54,0x54,0x48,0x00,0x00, // e 0x00,0x00,0x00,0x7C,0x0A,0x02,0x00,0x00, // f 0x00,0x18,0xA4,0xA4,0xA4,0xA4,0x7C,0x00, // g 0x00,0x7E,0x08,0x08,0x08,0x70,0x00,0x00, // h 0x00,0x00,0x00,0x48,0x7A,0x40,0x00,0x00, // i 0x00,0x00,0x40,0x80,0x80,0x7A,0x00,0x00, // j 0x00,0x7E,0x18,0x24,0x40,0x00,0x00,0x00, // k 0x00,0x00,0x00,0x3E,0x40,0x40,0x00,0x00, // l 0x00,0x7C,0x04,0x78,0x04,0x78,0x00,0x00, // m 0x00,0x7C,0x04,0x04,0x04,0x78,0x00,0x00, // n 0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, // o 0x00,0xFC,0x24,0x24,0x24,0x18,0x00,0x00, // p 0x00,0x18,0x24,0x24,0x24,0xFC,0x80,0x00, // q 0x00,0x00,0x78,0x04,0x04,0x04,0x00,0x00, // r 0x00,0x48,0x54,0x54,0x54,0x20,0x00,0x00, // s 0x00,0x00,0x04,0x3E,0x44,0x40,0x00,0x00, // t 0x00,0x3C,0x40,0x40,0x40,0x3C,0x00,0x00, // u 0x00,0x0C,0x30,0x40,0x30,0x0C,0x00,0x00, // v 0x00,0x3C,0x40,0x38,0x40,0x3C,0x00,0x00, // w 0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00, // x 0x00,0x1C,0xA0,0xA0,0xA0,0x7C,0x00,0x00, // y 0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00, // z 0x00,0x08,0x08,0x76,0x42,0x42,0x00,0x00, // { 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // | 0x00,0x42,0x42,0x76,0x08,0x08,0x00,0x00, // } 0x00,0x00,0x04,0x02,0x04,0x02,0x00,0x00, // ~ }; #endif
main.c:
#include "ssd1306.h"
int main() { SSD1306_init(); SSD1306_clearDisplay(); SSD1306_setBrightness(255); SSD1306_setPageMode(); SSD1306_setTextXY(0,0); SSD1306_putString("HELLO MYD-Y6ULX!"); SSD1306_setTextXY(1,0); SSD1306_putString("SSD1306 DEMO"); SSD1306_setTextXY(2,0); SSD1306_putString("2022-11-07"); close(ssd1306_i2c_devfd); return 0; }
makefile:
vpath %.c src #查找依赖时如果遇到%.c,则自动到src目录下寻找
D_SRC = src CC=arm-linux-gnueabihf-gcc D_INC = -I./inc D_OBJ = obj D_MK = build TATGET = ssd1306test SRC_C = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c)) OBJ_C = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C)))) $(TATGET):$(OBJ_C) $(CC) -o $(D_MK)/$@ $^ $(D_OBJ)/%.o:%.c #自动去src目录下找.c结尾的文件。 $(CC) -c -Wall $(D_INC) $< -o $@ .PHONY: clean clean: rm -f $(D_OBJ)/* $(TATGET) $(D_MK)/*
编译后上传给开发板,执行后就顺利驱动了OLED ssd1306了。