树莓派OLED 源码
本文地址:http://tongxinmao.com/Article/Detail/id/286
/*
* ssd1306.c:
* Copyright (c) 2013 Michael Kleiber
*
* Based upon Python SSD1306 code from:
* http://guy.carpenter.id.au/gaugette/about/
* by Guy Guy Carpenter
*
* Based upon Adafruit's Arduino library:
* https://github.com/adafruit/Adafruit_SSD1306
* by Limor Fried/Ladyada for Adafruit Industries.
*
*
* libssd1306 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libssd1306 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with libssd1306.
* If not, see <http://www.gnu.org/licenses/>.
*/
typedef unsigned char UCHAR8;
const unsigned char F6x8[][6] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //sp0
{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !1
{ 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // "2
{ 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #3
{ 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $4
{ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // %5
{ 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // &6
{ 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // '7
{ 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (8
{ 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )9
{ 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *10
{ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +11
{ 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // ,12
{ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // -13
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // .14
{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /15
{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 016
{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 117
{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 218
{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 319
{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 420
{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 521
{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 622
{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 723
{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 824
{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 925
{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :26
{ 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;27
{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // <28
{ 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // =29
{ 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // >30
{ 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?31
{ 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @32
{ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A33
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B34
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C35
{ 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D36
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E37
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F38
{ 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G39
{ 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H40
{ 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I41
{ 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J42
{ 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K43
{ 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L44
{ 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M45
{ 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N46
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O47
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P48
{ 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q49
{ 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R50
{ 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S51
{ 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T52
{ 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U53
{ 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V54
{ 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W55
{ 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X56
{ 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y57
{ 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z58
{ 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [59
{ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20 }, // \60
{ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]61
{ 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^62
{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _63
{ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // '64
{ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a65
{ 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b66
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c67
{ 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d68
{ 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e69
{ 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f70
{ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g71
{ 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h72
{ 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i73
{ 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j74
{ 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k75
{ 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l76
{ 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m77
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n78
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o79
{ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p80
{ 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q81
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r82
{ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s83
{ 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t84
{ 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u85
{ 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v86
{ 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w87
{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x88
{ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y89
{ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z90
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } // horiz lines91
};
//#include "ssd1306/ssd1306.h"
/*
* opaque handle
* details defined in implementation file
*/
typedef struct _SSD1306 SSD1306;
/*
* library works for 32 and 64 row displays
*/
typedef enum _SSD1306_ROWS {
SSD1306_ROWS_NONE = 0,
SSD1306_ROWS_32 = 32,
SSD1306_ROWS_64 = 64
} SSD1306_ROWS;
typedef enum _SSD1306_VCCSTATE {
SSD1306_VCCSATE_NONE = 0,
SSD1306_VCCSATE_EXTERNAL = 1,
SSD1306_VCCSATE_SWITCHCAP = 2
} SSD1306_VCCSTATE;
SSD1306* ssd1306_create();
/*
* destroy object and close SPI connection
*/
void ssd1306_destroy(SSD1306 * p);
/*
* setup connection for display
*/
void ssd1306_init(SSD1306 * p, SSD1306_ROWS rowtype, SSD1306_VCCSTATE vccstate);
/*
* reset display
*/
void ssd1306_reset(SSD1306 * p);
/*
* start scrolling to the left
*/
void ssd1306_startScrollLeft(SSD1306 * p, int start, int stop);
/*
* start scrolling to the right
*/
void ssd1306_startScrollRight(SSD1306 * p, int start, int stop);
/*
* stop scrolling
*/
void ssd1306_stopScroll(SSD1306 * p);
/*
* set (a part of) the memory of the display
* by using the internal memory
*/
void ssd1306_displayBlock(SSD1306 * p, int row, int col, int col_count, int col_offset /* = 0 */);
/*
* aquire the pointer to the memory that is
* used for drawing and when displaying
* this memory block is (width * height / 8) Bytes
* the data is stored in column major order
*/
unsigned char * ssd1306_getDisplayMemory(SSD1306 * p);
/*
* send command to display
* attributes of setup commands are also commands
* only the actual display data is sent as data
*/
void ssd1306_command(SSD1306 * p, unsigned char c);
/*
* send data to display
*/
void ssd1306_data(SSD1306 * p, unsigned char * c, int len);
/*
* Convenience functions
* Drawing should actually be handled by another library
*/
/*
* set whole display memory to either black or white
*/
void ssd1306_clear(SSD1306 * p, int color);
/*
* set one pixel of the display
* this is just a test function
* the actual drawing should be handled
* by a different library
* col = 0 = black, col != 0 = white
*/
void ssd1306_setPixel(SSD1306 * p, int x, int y, int col);
/*
* draw a line
* col = 0 = black, col != 0 = white
*/
void ssd1306_drawLine(SSD1306 * p, int x0, int y0, int x1, int y1, int color);
/*
* update the display to reflect the libraries internal buffer
*/
void ssd1306_display(SSD1306 * p);
/*
* forward the delay function of wiringPi
* Convenience
*/
void ssd1306_delay(unsigned int ms);
//gcc ssd1306.c -lwiringPi -lwiringPiDev -lrt -lm -o ssd1306
//#include "rpiIO.h"
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <wiringPi.h>
typedef unsigned char u8;
typedef unsigned short u16;
#define GPIO_PIN_CS 25 //GPIO26
#define GPIO_PIN_DC 24 //GPIO19
#define GPIO_PIN_RST 23 //GPIO13
#define GPIO_PIN_MOSI 22 //GPIO6
#define GPIO_PIN_SCK 21 //GPIO5
#define GPIO_PIN_LED1 0 //PIN17 不变
#define GPIO_PIN_LED2 2 //PIN27 不变
#define GPIO_PIN_SPK 3 //PIN22 不变
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLADDRESS 0x21
#define SSD1306_PAGEADDRESS 0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
#define SSD1306_MEMORY_MODE_HORIZ 0x00
#define SSD1306_MEMORY_MODE_VERT 0x01
#define SSD1306_MEMORY_MODE_PAGE 0x02
/* Scrolling #defines */
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
typedef struct _SSD1306 {
int spiChannel;
int maxClockSpeed;
int resetPin;
int dcPin;
SSD1306_ROWS rowtype;
SSD1306_VCCSTATE vccstate;
unsigned char * bitmap;
int width;
int height;
} SSD1306;
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
int
rpiIO_spiDataRW (unsigned char * tx, unsigned char * rx, int len)
{
unsigned char bitcnt;
int bytecnt;
digitalWrite(GPIO_PIN_CS, LOW) ;
digitalWrite(GPIO_PIN_SCK, LOW) ;
printf("rpiIO_spiDataRW %d \n",len);
for(bytecnt=0;bytecnt<len;bytecnt++)
{
unsigned char WrPara=tx[bytecnt];
// printf("spiDataRW %d/%d 0x%02x \n",bytecnt,len,WrPara);
for(bitcnt = 8; bitcnt != 0; bitcnt--)
{
digitalWrite(GPIO_PIN_SCK, LOW) ;
delayMicroseconds(1);
if(WrPara&0x80)
{
digitalWrite(GPIO_PIN_MOSI, HIGH) ;
}
else
{
digitalWrite(GPIO_PIN_MOSI, LOW) ;
}
delayMicroseconds(1);
digitalWrite(GPIO_PIN_SCK, HIGH) ;
WrPara <<= 1;
delayMicroseconds(1);
}
}
digitalWrite(GPIO_PIN_SCK, LOW) ;
digitalWrite(GPIO_PIN_MOSI, HIGH) ;
digitalWrite(GPIO_PIN_CS, HIGH) ; //*此处不关闭nCS,使用连续模式*
return len;
}
SSD1306 *
ssd1306_create()
{
SSD1306 * p = malloc(sizeof(SSD1306));
// p->spiChannel = spiChannel;
// p->resetPin = resetPin;
// p->dcPin = dcPin;
p->maxClockSpeed =20000;// maxClockSpeed;
p->rowtype = SSD1306_ROWS_NONE;
p->vccstate = SSD1306_VCCSATE_NONE;
p->bitmap = NULL;
p->width = 0;
p->height = 0;
// p->spi = NULL;
return p;
}
void
ssd1306_destroy(SSD1306 * p)
{
if (!p) return;
free(p);
}
static void
begin(SSD1306 * p)
{
ssd1306_delay(1);
ssd1306_reset(p);
ssd1306_command(p, SSD1306_DISPLAYOFF);
ssd1306_command(p, SSD1306_SETDISPLAYCLOCKDIV);
ssd1306_command(p, 0x80);
ssd1306_command(p, SSD1306_SETMULTIPLEX);
if (p->rowtype == SSD1306_ROWS_32) {
ssd1306_command(p, 0x1F);
}
else if (p->rowtype == SSD1306_ROWS_64) {
ssd1306_command(p, 0x3F);
}
ssd1306_command(p, SSD1306_SETDISPLAYOFFSET);
ssd1306_command(p, 0x00);
ssd1306_command(p, SSD1306_SETSTARTLINE | 0x00);
ssd1306_command(p, SSD1306_CHARGEPUMP);
if (p->vccstate == SSD1306_VCCSATE_EXTERNAL) {
ssd1306_command(p, 0x10);
}
else {
ssd1306_command(p, 0x14);
}
ssd1306_command(p, SSD1306_MEMORYMODE);
ssd1306_command(p, 0x00);
ssd1306_command(p, SSD1306_SEGREMAP | 0x01);
ssd1306_command(p, SSD1306_COMSCANDEC);
if (p->rowtype == SSD1306_ROWS_32) {
ssd1306_command(p, SSD1306_SETCOMPINS);
ssd1306_command(p, 0x02);
ssd1306_command(p, SSD1306_SETCONTRAST);
ssd1306_command(p, 0x8F);
}
else if (p->rowtype == SSD1306_ROWS_64) {
ssd1306_command(p, SSD1306_SETCOMPINS);
ssd1306_command(p, 0x12);
ssd1306_command(p, SSD1306_SETCONTRAST);
if (p->vccstate == SSD1306_VCCSATE_EXTERNAL) {
ssd1306_command(p, 0x9F);
}
else {
ssd1306_command(p, 0xCF);
}
}
ssd1306_command(p, SSD1306_SETPRECHARGE);
if (p->vccstate == SSD1306_VCCSATE_EXTERNAL) {
ssd1306_command(p, 0x22);
}
else {
ssd1306_command(p, 0xF1);
}
ssd1306_command(p, SSD1306_SETVCOMDETECT);
ssd1306_command(p, 0x40);
ssd1306_command(p, SSD1306_DISPLAYALLON_RESUME);
ssd1306_command(p, SSD1306_NORMALDISPLAY);
ssd1306_command(p, SSD1306_DISPLAYON);
}
void
ssd1306_init(SSD1306 * p, SSD1306_ROWS rowtype, SSD1306_VCCSTATE vccstate)
{
if (!p) return;
p->rowtype = rowtype;
p->vccstate = vccstate;
if (rowtype == SSD1306_ROWS_32) {
p->width = 128;
p->height = 32;
}
if (rowtype == SSD1306_ROWS_64) {
p->width = 128;
p->height = 64;
}
p->bitmap = (unsigned char *)(calloc(p->width * p->height / 8, sizeof(unsigned char)));
//const char * devName = (p->spiChannel==0?"/dev/spidev0.0":"/dev/spidev0.1");
//p->spi = rpiIO_spiCreate(devName, p->maxClockSpeed);
begin(p);
}
void
ssd1306_reset(SSD1306 * p)
{
if (!p) return;
// rpiIO_digitalWrite(p->resetPin, 0);
digitalWrite(GPIO_PIN_RST, LOW) ;
ssd1306_delay(100);
//rpiIO_digitalWrite(p->resetPin, 1);
digitalWrite(GPIO_PIN_RST, HIGH) ;
ssd1306_delay(10);
}
void
ssd1306_startScrollLeft(SSD1306 * p, int start, int stop)
{
if (!p) return;
ssd1306_command(p, SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(p, 0X00);
ssd1306_command(p, (unsigned char)start);
ssd1306_command(p, 0X00);
ssd1306_command(p, (unsigned char)stop);
ssd1306_command(p, 0X01);
ssd1306_command(p, 0XFF);
ssd1306_command(p, SSD1306_ACTIVATE_SCROLL);
}
void
ssd1306_startScrollRight(SSD1306 * p, int start, int stop)
{
if (!p) return;
ssd1306_command(p, SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(p, 0X00);
ssd1306_command(p, (unsigned char)start);
ssd1306_command(p, 0X00);
ssd1306_command(p, (unsigned char)stop);
ssd1306_command(p, 0X01);
ssd1306_command(p, 0XFF);
ssd1306_command(p, SSD1306_ACTIVATE_SCROLL);
}
void ssd1306_stopScroll(SSD1306 * p)
{
if (!p) return;
ssd1306_command(p, SSD1306_DEACTIVATE_SCROLL);
}
void
ssd1306_displayBlock(SSD1306 * p, int row, int col, int col_count, int col_offset /* = 0 */)
{
if (!p) return;
/* for now always transmit whole image */
uint8_t rows = p->height;
uint8_t cols = p->width;
/* devide by 8 -- black/white display 8 Bits = 1 Byte = 8 Pixels */
uint8_t pagecount = rows >> 3;
uint8_t pagestart = row >> 3;
uint8_t pageend = pagestart + pagecount -1;
uint8_t colstart = col;
uint8_t colend = col + col_count -1;
ssd1306_command(p, SSD1306_MEMORYMODE);
ssd1306_command(p, SSD1306_MEMORY_MODE_VERT);
ssd1306_command(p, SSD1306_PAGEADDRESS);
ssd1306_command(p, pagestart);
ssd1306_command(p, pageend);
ssd1306_command(p, SSD1306_COLADDRESS);
ssd1306_command(p, colstart);
ssd1306_command(p, colend);
int length = col_count * pagecount;
ssd1306_data(p, p->bitmap, length);
}
unsigned char *
ssd1306_getDisplayMemory(SSD1306 * p)
{
if (!p) return NULL;
return p->bitmap;
}
void
ssd1306_command(SSD1306 * p, unsigned char c)
{
if (!p) return;
// rpiIO_digitalWrite(p->dcPin, 0);
digitalWrite(GPIO_PIN_DC, LOW) ;
rpiIO_spiDataRW( &c, NULL, 1);
}
void
ssd1306_data(SSD1306 * p, unsigned char * c, int len)
{
if (!p) return;
//rpiIO_digitalWrite(p->dcPin, 1);
digitalWrite(GPIO_PIN_DC, HIGH) ;
rpiIO_spiDataRW( c, NULL, len);
// rpiIO_digitalWrite(p->dcPin, 0);
digitalWrite(GPIO_PIN_DC, LOW) ;
}
void
ssd1306_clear(SSD1306 * p, int color)
{
unsigned char c = (color==0?0x00:0xFF);
memset(p->bitmap, c, p->width * p->height / 8);
}
void
ssd1306_setPixel(SSD1306 * p, int x, int y, int color)
{
if (!p) return;
int col = x;
int row = y >> 3;
int mask = 1 << (y % 8);
int ix = row + (p->height >> 3) * col;
if (color == 0) {
p->bitmap[ix] &= ~mask;
}
else {
p->bitmap[ix] |= mask;
}
}
static void swap(int * x0, int * y0)
{
int tmp = *x0;
*x0 = *y0;
*y0 = tmp;
}
void
ssd1306_drawLine(SSD1306 * p, int x0, int y0, int x1, int y1, int color)
{
/*
* bresenham's algorithm - thx wikpedia
* taken from Adafruit gfx library
*/
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap(&x0, &y0);
swap(&x1, &y1);
}
if (x0 > x1) {
swap(&x0, &x1);
swap(&y0, &y1);
}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
for (; x0<=x1; x0++) {
if (steep) {
ssd1306_setPixel(p, y0, x0, color);
} else {
ssd1306_setPixel(p, x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
void
ssd1306_display(SSD1306 * p)
{
if (!p) return;
ssd1306_displayBlock(p, 0, 0, 128, 0);
}
void
ssd1306_delay(unsigned int ms)
{
delay(ms);
}
void LED_SetPos(SSD1306 * p,UCHAR8 ucIdxX, UCHAR8 ucIdxY)
{
ssd1306_command(p,0xb0 + ucIdxY);
ssd1306_command(p,((ucIdxX & 0xf0) >> 4) | 0x10);
ssd1306_command(p,(ucIdxX & 0x0f) | 0x00);
}
void LED_P6x8Str(SSD1306 * p,UCHAR8 ucIdxX, UCHAR8 ucIdxY, UCHAR8 ucDataStr[])
{
UCHAR8 i, j, ucDataTmp;
//LED_SetPos(p,ucIdxX,ucIdxY);
for (j = 0; ucDataStr[j] != '\0'; j++)
{
ucDataTmp = ucDataStr[j] - 32;
if(ucIdxX > 122)
{
ucIdxX = 0;
ucIdxY++;
}
ssd1306_data(p,&F6x8[ucDataTmp][0],6);
ucIdxX += 6;
}
return;
}
int main()
{
if (-1 == wiringPiSetup()) {
printf("Setup wiringPi failed!\n");
return -1 ;
}
pinMode (GPIO_PIN_SPK, OUTPUT) ;
pinMode (GPIO_PIN_LED1, OUTPUT) ;
pinMode (GPIO_PIN_LED2, OUTPUT) ;
digitalWrite(GPIO_PIN_LED1, HIGH) ;
digitalWrite(GPIO_PIN_LED2, HIGH) ;
digitalWrite(GPIO_PIN_SPK, HIGH) ;
delay(110);
digitalWrite(GPIO_PIN_SPK, LOW) ;
pinMode (GPIO_PIN_CS, OUTPUT) ;
pinMode (GPIO_PIN_RST, OUTPUT) ;
pinMode (GPIO_PIN_SCK, OUTPUT) ;
pinMode (GPIO_PIN_MOSI, OUTPUT) ;
pinMode (GPIO_PIN_DC, OUTPUT) ;
digitalWrite(GPIO_PIN_RST, HIGH) ;
digitalWrite(GPIO_PIN_DC, LOW) ;
//delayMicroseconds(1);
delay(110);
SSD1306 * disp = ssd1306_create();
printf("ssd1306_init\n");
ssd1306_init(disp, SSD1306_ROWS_64, SSD1306_VCCSATE_SWITCHCAP);
LED_P6x8Str(disp,0,0,"hello,world!");
ssd1306_delay(2000);
ssd1306_clear(disp, 0); //0 全黑 0XFF 全白
ssd1306_display(disp);
int y = 0;
int x = 0;
y = 0;
x = 0;
for (; x < 100; x += 1) {
for (y = 0; y < 10; ++y) {
ssd1306_setPixel(disp, x, y, 1);
}
}
for (x = 0; x < 100; x += 10) {
for (y = 0; y < 10; ++y) {
ssd1306_setPixel(disp, x, y, 0);
}
}
printf("Display 10 white Boxes\n");
ssd1306_display(disp);
ssd1306_delay(2000);
printf("Clear\n");
ssd1306_clear(disp, 0);
printf("Draw Lines\n");
int i;
for (i=0; i < 128; i+=4) {
ssd1306_drawLine(disp, 0, 0, i, 64-1, 1);
ssd1306_display(disp);
}
for (i=0; i < 64; i+=4) {
ssd1306_drawLine(disp, 0, 0, 128-1, i, 1);
ssd1306_display(disp);
}
ssd1306_delay(2000);
printf("Start Scrool Right\n");
ssd1306_startScrollRight(disp, 0x00, 0x0F);
ssd1306_delay(2000);
ssd1306_stopScroll(disp);
ssd1306_delay(1000);
printf("Start Scrool Left\n");
ssd1306_startScrollLeft(disp, 0x00, 0x0F);
ssd1306_delay(2000);
ssd1306_stopScroll(disp);
ssd1306_delay(1000);
ssd1306_destroy(disp);
return 0;
}上一篇:钱箱控制电路
下一篇:电脑和打印机并口空闲时电平