davidce 发表于 2013-6-18 11:54:40

自制基于arduino的GPS地图导航系统2.0

本帖最后由 davidce 于 2014-3-12 23:01 编辑

这是"自制基于arduino的GPS地图导航系统"(http://www.geek-workshop.com/thread-1846-1-2.html)的升级版,主要算法类似。自制基于arduino的GPS地图导航系统3.0 在这里查看



屏幕采用oled RGB 96*64 ,使用三轴磁阻获取罗盘信息(受周围磁场干扰较大),使用SD卡存储地图数据,使用TinyGPS处理GPS数据。

oled RGB 96*64 使用的是lm095cg-096064

接线方法和代码如下://OLED LM095CG-096064 - UNO
//E/RD#(12) - VCC
//R/W#(13) - GND
//D/C#(14) - A0
//RES#(15) - A1
//CS#(16) - A2
//D7(4) - 7
//D6(5) - 6
//D5(6) - 5
//D4(7) - 4
//D3(8) - 3
//D2(9) - 2
//D1(10) - 9
//D0(11) - 8

/***********************************************************/
//oled pin define
/***********************************************************/
#define CS A2
#define DC A0
#define RES A1
/***********************************************************/
// special defines for the dataport
/***********************************************************/
#define DATAPORT1 PORTD
#define DATAPIN1 PIND
#define DATADDR1 DDRD

#define DATAPORT2 PORTB
#define DATAPIN2 PINB
#define DATADDR2 DDRB

#define DATA1_MASK 0xFC// top 6 bits
#define DATA2_MASK 0x03// bottom 2 bits

函数:/* write by davidce
[email protected]
2013.6.10
v1.0
*/

//********************************************
//low level function
//********************************************
/**********************************************
* // Write Command
**********************************************/
static void write_command(unsigned char Command_value)
{
digitalWrite(CS, LOW);
digitalWrite(DC, LOW);
DATAPORT2 = (DATAPORT2 & DATA1_MASK) |
    (Command_value & DATA2_MASK);
DATAPORT1 = (DATAPORT1 & DATA2_MASK) |
    (Command_value & DATA1_MASK); // top 6 bits
digitalWrite(CS, HIGH);
}
/**********************************************
* // Write Data
**********************************************/
static void write_Data(unsigned char Data_value)
{
digitalWrite(CS, LOW);
digitalWrite(DC, HIGH);
DATAPORT2 = (DATAPORT2 & DATA1_MASK) |
    (Data_value & DATA2_MASK);
DATAPORT1 = (DATAPORT1 & DATA2_MASK) |
    (Data_value & DATA1_MASK); // top 6 bits
digitalWrite(CS, HIGH);
}
/********************************************
* // Draw Picture
********************************************/
static void drawPicFromFlash(uint8_t x0,uint8_t y0,uint8_t w,uint8_t h,const PROGMEM char *c)                                               
{
digitalWrite(DC, LOW);//solve a bug of write_command defore write_data
write_command(0x15); //set column address
write_command(x0); //column address start 00
write_command(x0+w-1); //column address end 95
write_command(0x75); //set row address
write_command(y0); //row address start 00
write_command(y0+h-1); //row address end 63

unsigned char k,i;
for(k=0;k<h;k++)
{
    for(i=0;i<w;i++)
    {       
      write_Data(pgm_read_byte(c++));
      write_Data(pgm_read_byte(c++));
    }
}
}
/********************************************
* // Fill color
********************************************/
static void fill_color (uint8_t startx,uint8_t endx,uint8_t starty,uint8_t endy,unsigned char dat1,unsigned char dat2)                                               
{
digitalWrite(DC, LOW);//solve a bug of write_command defore write_data
write_command(0x15); //set column address
write_command(startx); //column address start 00
write_command(endx-1); //column address end 95
write_command(0x75); //set row address
write_command(starty); //row address start 00
write_command(endy-1); //row address end 63
unsigned char k,i;
for(k=starty;k<endy;k++)
{
    for(i=startx;i<endx;i++)
    {       
      write_Data(dat1);
      write_Data(dat2);
    }
}
}
/********************************************
* // DrawRectangle
********************************************/
static void drawRectangle(unsigned char startx,unsigned char starty,
unsigned char endx,unsigned char endy,
unsigned char BcolorR,unsigned char BcolorB,unsigned char BcolorG,
unsigned char FcolorR,unsigned char FcolorB,unsigned char FcolorG,
boolean isFill)
{
digitalWrite(DC, LOW);//solve a bug of write_command defore write_data
write_command(0x26);
if(isFill)
{
    write_command(0x01);
}
else
{
    write_command(0x00);
}
write_command(0x22);
write_command(startx);
write_command(starty);
write_command(endx);
write_command(endy);
write_command(BcolorR);
write_command(BcolorB);
write_command(BcolorG);
write_command(FcolorR);
write_command(FcolorB);
write_command(FcolorG);
}
/********************************************
* // cover color format from 888 to 565
********************************************/
static uint16_t Color565(uint8_t r, uint8_t g, uint8_t b) {
uint16_t c;
c = r >> 3;
c <<= 6;
c |= g >> 2;
c <<= 5;
c |= b >> 3;
return c;
}
/********************************************
* // DrawLine
********************************************/
static void drawLine(unsigned char startx,unsigned char starty,
unsigned char endx,unsigned char endy,
unsigned char colorR,unsigned char colorB,unsigned char colorG)
{
digitalWrite(DC, LOW);//solve a bug of write_command
write_command(0x21);
write_command(startx);
write_command(starty);
write_command(endx);
write_command(endy);
write_command(colorR);
write_command(colorB);
write_command(colorG);
}
/***************************************************/
//oled Initial
/***************************************************/
static void Initial_SSD1330ZB()
{
write_command(0xfd); // command lock
write_command(0x12);
write_command(0xae); // display off
write_command(0xa4); // Normal Display mode
write_command(0x15); //set column address
write_command(0x00); //column address start 00
write_command(0x5f); //column address end 95
write_command(0x75); //set row address
write_command(0x00); //row address start 00
write_command(0x3f); //row address end 63
write_command(0x87); //master current control
write_command(0x0A);
write_command(0x81); //Set Contrast for Color A
write_command(0x85); //91
write_command(0x82); //Set Contrast for Color B
write_command(0x56); //50
write_command(0x83); //Set Contrast for Color C
write_command(0x7f); //7d
write_command(0x8a);// set scond pre-change speed of Color A
write_command(0x64);
write_command(0x8b);// set scond pre-change speed of Color B
write_command(0x78);
write_command(0x8c);// set scond pre-change speed of Color C
write_command(0x64);
write_command(0xa0); //set re-map & data format
write_command(0x72); //Horizontal address increment
write_command(0xa1); //set display start line
write_command(0x00); //start 00 line
write_command(0xa2); //set display offset
write_command(0x00);
write_command(0xa8); //set multiplex ratio
write_command(0x3f); //64MUX
write_command(0xb0); //set power save
write_command(0x1a);
write_command(0xb1);
write_command(0xf1); // Phase 2 period Phase 1 period
write_command(0xb3); // Set Display Clock Divide Ratio/ Oscillator Frequency
write_command(0xd0);
write_command(0xbb); // set pre-charge
write_command(0x3e);
write_command(0xbe); //set Vcomh
write_command(0x3e);
write_command(0xad); //Select external VCC supply at Display ON
write_command(0x8e); //Select External VP voltage supply
write_command(0xaf); //display on
}
//********************************************
//high level function
//********************************************
/********************************************
* // DrawPixel
********************************************/
static void drawPixel(unsigned char px,unsigned char py,
unsigned char colorR,unsigned char colorB,unsigned char colorG)
{
drawLine(px,py,px,py,colorR,colorB,colorG);
}
/********************************************
* // draw a character
********************************************/
static void drawChar(uint8_t x, uint8_t y, char c,uint8_t colorR,uint8_t colorB,uint8_t colorG,uint8_t size) {
uint8_t tempx,tempy;
uint8_t i,j;
for (i =0; i<5; i++ ) {
    uint8_t line = pgm_read_byte(font+(c*5)+i);
    for (j = 0; j<8; j++) {
      if (line & 0x1) {
      if (size == 1) // default size
          drawPixel(x+i, y+j, colorR,colorB,colorG);
      else {// big size
          tempx= x+i*size;
          tempy= y+j*size;
          drawRectangle(tempx,tempy,tempx + size,tempy + size, colorR,colorB,colorG,colorR,colorB,colorG,true);
      }
      }
      line >>= 1;
    }
}
}
/********************************************
* // DrawString
********************************************/
static void drawString(uint8_t x, uint8_t y, char *c,uint8_t colorR,uint8_t colorB,uint8_t colorG,uint8_t size) {
if(size>0)
{
    while (c != 0) {
      drawChar(x, y, c, colorR,colorB,colorG, size);
      x += size*6;
      c++;
    }
}
}
/********************************************
* // DrawCircleHelper
********************************************/
static void drawCircleHelper(uint8_t x0, uint8_t y0,
uint8_t r, uint8_t cornername,
uint8_t colorR,uint8_t colorB,uint8_t colorG) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
    if (cornername & 0x4) {
      drawPixel(x0 + x, y0 + y,colorR,colorB,colorG);
      drawPixel(x0 + y, y0 + x,colorR,colorB,colorG);
    }
    if (cornername & 0x2) {
      drawPixel(x0 + x, y0 - y,colorR,colorB,colorG);
      drawPixel(x0 + y, y0 - x,colorR,colorB,colorG);
    }
    if (cornername & 0x8) {
      drawPixel(x0 - y, y0 + x,colorR,colorB,colorG);
      drawPixel(x0 - x, y0 + y,colorR,colorB,colorG);
    }
    if (cornername & 0x1) {
      drawPixel(x0 - y, y0 - x,colorR,colorB,colorG);
      drawPixel(x0 - x, y0 - y,colorR,colorB,colorG);
    }
}
}
/********************************************
* // DrawCircle
********************************************/
static void drawCircle(uint8_t x0, uint8_t y0,
uint8_t r,
uint8_t colorR,uint8_t colorB,uint8_t colorG)
{
drawCircleHelper(x0, y0, r, 0xF, colorR,colorB,colorG);
drawPixel(x0, y0+r, colorR,colorB,colorG);
drawPixel(x0, y0-r, colorR,colorB,colorG);
drawPixel(x0+r, y0, colorR,colorB,colorG);
drawPixel(x0-r, y0, colorR,colorB,colorG);
}
/********************************************
* // drawTriangle
********************************************/
static void drawTriangle(uint8_t x0, uint8_t y0,
uint8_t x1, uint8_t y1,
uint8_t x2, uint8_t y2,
unsigned char colorR,unsigned char colorB,unsigned char colorG)
{
drawLine(x0, y0, x1, y1, colorR,colorB,colorG);
drawLine(x1, y1, x2, y2, colorR,colorB,colorG);
drawLine(x2, y2, x0, y0, colorR,colorB,colorG);
}
/********************************************
* // init color OLED
********************************************/
static void initOLED()
{
pinMode(CS, OUTPUT);
pinMode(DC, OUTPUT);
pinMode(RES, OUTPUT);
//set pin output mode
DATADDR2 |= DATA2_MASK;
DATADDR1 |= DATA1_MASK;
//reset oled model
digitalWrite(RES, LOW);
delay(50);
digitalWrite(RES, HIGH);
delay(50);
Initial_SSD1330ZB();

fill_color(0,96,0,64,0x00,0x00);
}

代码仅供参考。
感谢 czad 赠送的atmge328p的贴片板和好人做到底的geek精神!

redtxd 发表于 2013-6-18 12:25:54

真精致,楼主手太巧了

likaci 发表于 2013-6-18 13:56:55

手巧+1 很精致

hyzjshwo 发表于 2013-6-18 19:50:48

LZ 真是手巧

wing 发表于 2013-6-19 21:52:48

显示模块换了,效果比之前的好很多了

fangtaonj 发表于 2013-7-9 20:26:55

楼主太强大了!膜拜!请问TinyGPS库在哪里能找到?对我来说找了好久这东东还只是停在传说中!

duanliangcong 发表于 2013-9-15 00:07:08

为什么看不到代码呢?

lxk7280 发表于 2013-9-28 16:41:22

pgm_read_byte(font+(c*5)+i);    font 没定义啊

FoieDEEEE_仲敬 发表于 2013-9-28 17:00:57

做得很漂亮啊

davidce 发表于 2013-9-28 19:33:42

lxk7280 发表于 2013-9-28 16:41 static/image/common/back.gif
pgm_read_byte(font+(c*5)+i);    font 没定义啊

font 是字库,glcdfont.c 文件定义,可在网上找到

davidce 发表于 2013-9-28 19:47:25

fangtaonj 发表于 2013-7-9 20:26 static/image/common/back.gif
楼主太强大了!膜拜!请问TinyGPS库在哪里能找到?对我来说找了好久这东东还只是停在传说中!

很容易搜到的

心如纸水 发表于 2013-10-10 15:05:22

我最近也想用TFT屏做一个GPS导航仪,希望楼主能不吝赐教!QQ:247843921,加下好友吧!:):)

心如纸水 发表于 2013-10-14 15:47:55

我最近也想做一个这个    :)楼主可以留个邮箱讨论下吗?

davidce 发表于 2013-10-14 15:50:30

在这就可以一起讨论,坛里的高手不少

Dragon 发表于 2013-10-22 23:32:42

楼主可以写一点你制作过程的资料吗
页: [1] 2
查看完整版本: 自制基于arduino的GPS地图导航系统2.0