電子工作メモランダム

マイコンみたいなパソコンRaspberry Piの設定とかいじった手順とかの備忘録を淡々と記述するブログです。プログラムなど実行するときは自己責任でお願いします。

RaspberryPiからaitendoのLCD[C128X64SPI-12P]への画像表示

 文字はうまくいったので今回は「あの」方法を使って4階調の画像を表示します。それは、白と黒を目に見えない速さで高速で切り替える、という方法です。

用意するもの

  • RaspberryPi
  • 液晶モジュール
  • ソフトウェア
  • 1ms、1μsを縮ようとする気概

プログラム

lcd_pict.c

#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <iconv.h>
#include <string.h>
#include <stdlib.h>

#define LCD_SDA 12  // GPIO 10
#define LCD_SCL 14  // GPIO 11
#define LCD_A0   6  // GPIO 25
#define LCD_CS  10  // GPIO  8

#define PAGE_SEL 0xB0			// (3)
#define COL_SEL  0x10			// (4)

unsigned char imagedata[8192] = {0}; // 128*64

void glcd_write_data(unsigned char dat)
{
	digitalWrite(LCD_A0, 1);		// 1ならデータ。0ならコマンド。
	// unsigned char datr = ~dat; // 白黒反転
	wiringPiSPIDataRW(0, &dat, 1);
}

// コマンドを出力する
void glcd_write_cmd(unsigned char cmd)
{
	digitalWrite(LCD_A0, 0);		// 1ならデータ。0ならコマンド。
	wiringPiSPIDataRW(0, &cmd, 1);
}

void glcd_init(void)
{
	//RST = 0;
	delay(10);
	//RST = 1;

	glcd_write_cmd(0xE2);			// (14) S/W RESWT
	glcd_write_cmd(0xA3);			// (11) LCD bias(1/7)
	//glcd_write_cmd(0xAF);			// (1)  Display ON
	glcd_write_cmd(0xA0);			// (8)  segment direction.(normal direction)
	glcd_write_cmd(0xC8);			// (15) Common Direction.(normal direction)
	glcd_write_cmd(0x22);			// (17) Regultion resistor select(0x010)  //25
	glcd_write_cmd(0x81);			// (18) EV Select.
	glcd_write_cmd(0x2f);			// (18) Select EV value.(0x101111)
	glcd_write_cmd(0x2f);			// (16) Power control(VB,VR,VF全部1)

	glcd_write_cmd(0x40);			// (2)  Initial display line(0に設定, MAX63)
	glcd_write_cmd(0xB0);			// (3)  Set page address(Y=0に設定, MAX15)
	glcd_write_cmd(0x10);			// (4)  Set coloumn addr MSB
	glcd_write_cmd(0x00);			// (4)  Set coloumn addr LSB(X=0に設定, MAX255)
	//glcd_write_cmd(0xAF);			// (1)  Display ON
	glcd_write_cmd(0xA4);			// (10) all pixel ON(normal display)
	glcd_write_cmd(0xA6);			// (9)  Inverse Display(normal display)

	glcd_write_cmd(0xAF);			// (1)  Display ON
}



// 座標のセット
void glcd_set_axis(int x, int page)
{
	int col;
	
	// Selecting Page (3)
	glcd_write_cmd(PAGE_SEL | page);

	// Selecting Column
	col = (x & 0xF0) >> 4; 			// 上位ビット
	glcd_write_cmd(COL_SEL | col);	// 
	glcd_write_cmd(x & 0x0f);		// 下位ビット
}

void glcd_clear()
{	
	int i,j;
	for (j = 0; j < 8; j++) {
		glcd_set_axis(0, j);
		for (i = 0; i < 128; i++)
			glcd_write_data(0x00);
	}
}

int init_picture()
{
	// ▼画像ファイルオープン
	FILE *fp;

	fp = fopen( "mono.dat", "rb" );
	if( fp == NULL ) {
		printf( "mono.dat が開けません\n" );
		return -1;
	}
	fread( imagedata, sizeof( unsigned char ), 128*64, fp );
	fclose(fp);
}

void show_picture(int time)
{
	int colmun, page, dot;
	unsigned char buf;
	for (page = 0; page < 8; page++)
	{
		glcd_set_axis(0, page);
		for (colmun = 0; colmun < 128; colmun++)
		{
			buf = 0;
			for (dot = 0; dot < 8; dot++)
			{
				if (imagedata[page*128*8+colmun*8+dot] <= time) buf++;
				if (dot != 7) buf = buf << 1;
			}
			glcd_write_data(buf);
		}
	}
}

int main()
{
	// 初期化
	if (wiringPiSetup() == -1)
	{
		printf("wiringPiのセットアップに失敗しました。\n");
		return 1;
	}
	int initv = wiringPiSPISetup(0, 10000000);
	printf("initv=%d\n", initv);
	if (initv < 0)
	{
		printf("wiringPiSPIのセットアップに失敗しました。\n");
		return 1;
	}
	pinMode(LCD_A0, OUTPUT);
	
	glcd_init();
	printf("init ok\n");
	
	// ▼ここからメイン
	glcd_clear();
	init_picture();
	
	int i=0;
	while(1)
	{
		show_picture(i);
		i++; if (i>2) i=0;
		// delay(1000);
	}
	return 0;
}

必要ファイル

 画像のデータです。結果に表示されているような4階調のデータです。普通にプログラムの中で階調数を指定できるようにしておけば良かったです。
mono.dat

実行・出力例

gcc lcd_pict.c -o lcd_pict -I/usr/local/include -L/usr/local/lib -lwiringPi
./lcd_pict

f:id:mas-home:20130119010044j:plain
 静止画だとそれなりに見えてるんですけど、実際にはちらつきがひどくて実用的ではありません。4分の1の面積くらいですとちゃんと見えるので、Raspberry Piの速度の問題のようです。
 とりあえず-O3くらいは入れてみますかね・・・。