NodeMCU 使用Arduino SPI点亮OLED12864

来源:互联网 发布:亚马逊windows 编辑:程序博客网 时间:2024/06/15 12:28

主要针对比较流行的0.96 OLED12864,网上购买的一般会附带源代码和简单的字库,这里主要简单修改一下针对NodeMCU啦

  • 硬件SPI方式
  • 软件模拟SPI方式

#include <SPI.h>#define LCD_CLK SCK  //GPIO14 HSCLK#define LCD_SDA MOSI //GPIO13 HMOSI//LCD RES是LCD的复位引脚#define LCD_RES 3    //GPIO3//LCD DC高电平是输入数据,低电平是输入命令#define LCD_DC 1     //GPIO1#define LCD_WIDTH 128 //LCD横向宽度//软件SPI驱动LCD12864//#define LCD_SOFTSPIinline void SPI_Write(uint8_t data){#ifdef LCD_SOFTSPI    uint8_t i = 8;    digitalWrite(LCD_CLK, 0);    while (i--)    {        if (data & 0x80)            digitalWrite(LCD_SDA, 1);        else            digitalWrite(LCD_SDA, 0);        digitalWrite(LCD_CLK, 1);        digitalWrite(LCD_CLK, 0);        data <<= 1;    }#else     SPI.transfer(data);#endif}void LCD_WrDat(uint8_t data){    digitalWrite(LCD_DC, 1);    SPI_Write(data);}void LCD_WrCmd(uint8_t data){    digitalWrite(LCD_DC, 0);    SPI_Write(data);}void LCD_SetPos(uint8_t x, uint8_t y){    LCD_WrCmd(0xb0 + y);    LCD_WrCmd(((x & 0xf0) >> 4) | 0x10);    LCD_WrCmd((x & 0x0f) | 0x01);}void LCD_Fill(uint8_t bmp_data){    uint8_t y, x;    for (y = 0; y < 8; y++)    {        LCD_WrCmd(0xb0 + y);        LCD_WrCmd(0x01);        LCD_WrCmd(0x10);        for (x = 0; x < LCD_WIDTH; x++)            LCD_WrDat(bmp_data);    }}void LCD_Init(){#ifdef LCD_SOFTSPI    pinMode(LCD_SDA, OUTPUT);    pinMode(LCD_CLK, OUTPUT);#else    SPI.begin();    SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE0));#endif    pinMode(LCD_DC, OUTPUT);    pinMode(LCD_RES, OUTPUT);    digitalWrite(LCD_CLK, 1);    digitalWrite(LCD_RES, 0);    delay(50);    digitalWrite(LCD_RES, 1);    LCD_WrCmd(0xae); //--turn off oled panel    LCD_WrCmd(0x00); //---set low column address    LCD_WrCmd(0x10); //---set high column address    LCD_WrCmd(0x40); //--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)    LCD_WrCmd(0x81); //--set contrast control register    LCD_WrCmd(0xcf); // Set SEG Output Current Brightness    LCD_WrCmd(0xa1); //--Set SEG/Column Mapping     0xa0左右反置 0xa1正常    LCD_WrCmd(0xc8); //Set COM/Row Scan Direction   0xc0上下反置 0xc8正常    LCD_WrCmd(0xa6); //--set normal display    LCD_WrCmd(0xa8); //--set multiplex ratio(1 to 64)    LCD_WrCmd(0x3f); //--1/64 duty    LCD_WrCmd(0xd3); //-set display offset  Shift Mapping RAM Counter (0x00~0x3F)    LCD_WrCmd(0x00); //-not offset    LCD_WrCmd(0xd5); //--set display clock divide ratio/oscillator frequency    LCD_WrCmd(0x80); //--set divide ratio, Set Clock as 100 Frames/Sec    LCD_WrCmd(0xd9); //--set pre-charge period    LCD_WrCmd(0xf1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock    LCD_WrCmd(0xda); //--set com pins hardware configuration    LCD_WrCmd(0x12);    LCD_WrCmd(0xdb); //--set vcomh    LCD_WrCmd(0x40); //Set VCOM Deselect Level    LCD_WrCmd(0x20); //-Set Page Addressing Mode (0x00/0x01/0x02)    LCD_WrCmd(0x02); //    LCD_WrCmd(0x8d); //--set Charge Pump enable/disable    LCD_WrCmd(0x14); //--set(0x10) disable    LCD_WrCmd(0xa4); // Disable Entire Display On (0xa4/0xa5)    LCD_WrCmd(0xa6); // Disable Inverse Display On (0xa6/a7)    LCD_WrCmd(0xaf); //--turn on oled panel    LCD_Fill(0x00);  //初始清屏    LCD_SetPos(0, 0);}void LCD_PutPixel(uint8_t x, uint8_t y){    uint8_t data1; //data1当前点的数据    LCD_SetPos(x, (uint8_t)(y >> 3));    data1 = (uint8_t)(0x01 << (y % 8));    LCD_WrCmd((uint8_t)(0xb0 + (y >> 3)));    LCD_WrCmd((uint8_t)(((x & 0xf0) >> 4) | 0x10));    LCD_WrCmd((uint8_t)((x & 0x0f) | 0x00));    LCD_WrDat(data1);}void setup(){    LCD_Init();    // 绘制一条直线    for (uint8_t i = 0; i < LCD_WIDTH; ++i)        LCD_PutPixel(i, 5);}void loop(){}

只是绘制了一条直线,额外的功能可以自己扩展

原创粉丝点击