树莓派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;
    	
    	
    }


    上一篇:钱箱控制电路
    下一篇:电脑和打印机并口空闲时电平