树莓派OLED 源码
本文地址:http://dsyn.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;
	
	
}上一篇:钱箱控制电路
下一篇:电脑和打印机并口空闲时电平