首先先須先熟悉如何使用Raspberry Pi的GPIO腳位,並確認映射關係
圖片引用自:http://blog.mcmelectronics.com/post/Raspberry-Pi-3-GPIO-Pin-Layout#.WDAR9HE2u00
接著開始編寫操作GPIO的主要函式,這裡的程式是改寫自
elinux.org/RPi_GPIO_Code_Samples,其主要功能為,初始化GPIO、設定選定的GPIO腳位為
輸出或輸入、若是該腳位為輸出時,則可設定輸出為1或是0。需要注意的是你使用的
Raspberry Pi不是3 model B的話,可能需要更改GPIO_BASE。
程式碼如下:
gpio.h
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #define GPIO_BASE 0x3f200000 #define PAGE_SIZE (4 * 1024) #define BLOCK_SIZE (4 * 1024) int mem_fd; void *gpio_map; /* I/O access */ volatile unsigned *gpio; /* GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) */ #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) #define GPIO_SET *(gpio+7) /* sets bits which are 1 ignores bits which are 0 */ #define GPIO_CLR *(gpio+10) /* clears bits which are 1 ignores bits which are 0 */ /** * Set up a memory regions to access GPIO * */ void ini_gpio(); void set_gpio(int num,int in_out);//0 for in, 1 for out void gpio_val(int num,int val);gpio.c
#include "gpio.h"
void ini_gpio()
{
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap GPIO */
gpio_map = mmap(
NULL, /* Any adddress in our space will do */
BLOCK_SIZE, /* Map length */
PROT_READ|PROT_WRITE, /* Enable reading & writting to mapped memory */
MAP_SHARED, /* Shared with other processes */
mem_fd, /* File to map */
GPIO_BASE /* Offset to GPIO peripheral */
);
close(mem_fd); /* No need to keep mem_fd open after mmap */
if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map); /* errno also set! */
exit(-1);
}
/* Always use volatile pointer! */
gpio = (volatile unsigned *)gpio_map;
}
void set_gpio(int num,int in_out)//0 for in, 1 for out
{
INP_GPIO(num);
if(in_out==1)
{
OUT_GPIO(num);
}
return;
}
void gpio_val(int num,int val)
{
if(val==1)
{
GPIO_SET = 1 << num;
}
else
{
GPIO_CLR = 1 << num;
}
return;
}
寫完GPIO的函式後,可以先寫簡單的程式測試是否可以使用,如此範例為將led燈接上GPIO腳位的編號4:#include "gpio.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "gpio.h"
int main(int argc, char **argv)
{
/* Set up gpi pointer for direct register access */
ini_gpio();
set_gpio(4,1);
gpio_val(4,1);
sleep(1);
gpio_val(4,0);
sleep(1);
return 0;
}
開始編寫驅動tft螢幕的程式,參考http://forum.arduino.cc/index.php?topic=125034.0裡二樓
Arduino版本的實作st7735r的code並改寫。這裡需要注意的地方是reset, cs, scl, sda, rs對應到的GPIO標號,在這裡分別設定為GPIO編號2, 3, 4, 5, 6,
與GPIO編號對應到Raspberry Pi板子上的腳位,和Raspberry Pi的腳位對應到st7735r的腳位。
st7735r.h:
#include "gpio.h" extern unsigned char reset; extern unsigned char cs; extern unsigned char scl; extern unsigned char sda; extern unsigned char rs; int bitSet(unsigned char num,int pos); void write_command(unsigned char c); void write_data(unsigned char d); void write_data_2(unsigned char LCD_DataH,unsigned char LCD_DataL); void write_data_3(unsigned char LCD_DataH,unsigned char LCD_DataM,unsigned char LCD_DataL); void Reset(); void lcd_initial(); void RamAdressSet(); void dsp_single_colour(unsigned char DH,unsigned char DL); void PutPixel(unsigned int x_start,unsigned int y_start,unsigned int color);st7735r.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include "st7735r.h"
unsigned char reset=2;
unsigned char cs=3;
unsigned char scl=4;
unsigned char sda=5;
unsigned char rs=6;
int bitSet(unsigned char num,int pos)
{
if((num & (int)(pow(2,pos)))>0)
{
return 1;
}
return 0;
}
void write_command(unsigned char c){
gpio_val(cs,0);
gpio_val(rs,0);
gpio_val(sda,bitSet(c,7));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,6));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,5));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,4));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,3));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,2));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,1));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(c,0));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(cs,1);
}
void write_data(unsigned char d) {
gpio_val(cs,0);
gpio_val(rs,1);
gpio_val(sda,bitSet(d,7));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,6));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,5));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,4));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,3));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,2));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,1));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(sda,bitSet(d,0));
gpio_val(scl,0);
gpio_val(scl,1);
gpio_val(cs,1);
}
void write_data_2(unsigned char LCD_DataH,unsigned char LCD_DataL)
{
write_data(LCD_DataH);
write_data(LCD_DataL);
}
void write_data_3(unsigned char LCD_DataH,unsigned char LCD_DataM,unsigned char LCD_DataL)
{
write_data(LCD_DataH);
write_data(LCD_DataM);
write_data(LCD_DataL);
}
void Reset()
{
gpio_val(reset,0);
usleep(100000);
gpio_val(reset,1);
usleep(100000);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void lcd_initial(){
ini_gpio();
set_gpio(reset,1);
set_gpio(cs,1);
set_gpio(scl,1);
set_gpio(sda,1);
set_gpio(rs,1);
printf("start reset\n");
Reset();
printf("start soft reset\n");
//------------------------------------------------------------------//
//-------------------Software Reset-------------------------------//
//------------------------------------------------------------------//
write_command(0x11);//Sleep exit
usleep(120000);
//ST7735R Frame Rate
write_command(0xB1);
write_data(0x01);
write_data(0x2C);
write_data(0x2D);
write_command(0xB2);
write_data(0x01);
write_data(0x2C);
write_data(0x2D);
write_command(0xB3);
write_data(0x01);
write_data(0x2C);
write_data(0x2D);
write_data(0x01);
write_data(0x2C);
write_data(0x2D);
write_command(0xB4); //Column inversion
write_data(0x07);
//ST7735R Power Sequence
write_command(0xC0);
write_data(0xA2);
write_data(0x02);
write_data(0x84);
write_command(0xC1);
write_data(0xC5);
write_command(0xC2);
write_data(0x0A);
write_data(0x00);
write_command(0xC3);
write_data(0x8A);
write_data(0x2A);
write_command(0xC4);
write_data(0x8A);
write_data(0xEE);
write_command(0xC5); //VCOM
write_data(0x0E);
write_command(0x36); //MX, MY, RGB mode
write_data(0xC8);
//ST7735R Gamma Sequence
write_command(0xe0);
write_data(0x0f);
write_data(0x1a);
write_data(0x0f);
write_data(0x18);
write_data(0x2f);
write_data(0x28);
write_data(0x20);
write_data(0x22);
write_data(0x1f);
write_data(0x1b);
write_data(0x23);
write_data(0x37);
write_data(0x00);
write_data(0x07);
write_data(0x02);
write_data(0x10);
write_command(0xe1);
write_data(0x0f);
write_data(0x1b);
write_data(0x0f);
write_data(0x17);
write_data(0x33);
write_data(0x2c);
write_data(0x29);
write_data(0x2e);
write_data(0x30);
write_data(0x30);
write_data(0x39);
write_data(0x3f);
write_data(0x00);
write_data(0x07);
write_data(0x03);
write_data(0x10);
write_command(0x2a);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x7f);
write_command(0x2b);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x9f);
write_command(0xF0); //Enable test command
write_data(0x01);
write_command(0xF6); //Disable ram power save mode
write_data(0x00);
write_command(0x3A); //65k mode
write_data(0x05);
write_command(0x29);//Display on
}
void RamAdressSet(){
write_command(0x2A);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x7f);
write_command(0x2B);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x9f);
}
void dsp_single_colour(unsigned char DH,unsigned char DL)
{
unsigned char i,j;
//RamAdressSet();
for (i=0;i<160;i++){
for (j=0;j<128;j++){
write_data_2(DH,DL);
}
}
}
void PutPixel(unsigned int x_start,unsigned int y_start,unsigned int color)
{
write_command(0x2a);
write_data(x_start);
write_data(0x5f);
write_command(0x2b);
write_data(y_start+0x34);
write_data(0x7F);
write_command(0x2c);
write_data(color>>8);
write_data(color&0xff);
}
test_tft.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "st7735r.h"
int main()
{
printf("%d\n",bitSet(10,4));
printf("%d\n",bitSet(10,3));
lcd_initial();
while(1)
{
static unsigned char i = 0;
i += 10;
usleep(100000);
printf("write command\n");
write_command(0x2C);
dsp_single_colour(i,i);
}
return 0;
}

