大笨叔 发表于 2012-4-28 15:00:13

NOKIA 5110 LCD画图程序

//找了几天画图的代码,不得要领。今天上午终于花时间移植了一段代码,实现了在LCD上画正弦曲线的功能,其中很多子函数可能有点怪异,无赖我等没有做过程序,不知如何处理,依葫芦画瓢做了,有谁能够把这个做成5110的库么?

unsigned char LcdBuffer;
unsigned char LcdX,LcdY;
int LCD_CE=2;
int LCD_RST=3;
int SCLK=4;
int SDIN=5;
int LCD_DC=6;
int inputPin=8;// 定义超声波信号接收接口
int outputPin=9; // 定义超声波信号发出接口
int pot=0;
void setup()
{
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
pinMode(SCLK,OUTPUT);
pinMode(SDIN,OUTPUT);
pinMode(LCD_DC,OUTPUT);
pinMode(LCD_CE,OUTPUT);
pinMode(LCD_RST,OUTPUT);
}
const unsigned char Font6x8[]=
{
{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00   }
,   // sp
{
    0x00, 0x00, 0x00, 0x2f, 0x00, 0x00   }
,   // !
{
    0x00, 0x00, 0x07, 0x00, 0x07, 0x00   }
,   // "
{
    0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14   }
,   // #
{
    0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12   }
,   // $
{
    0x00, 0x62, 0x64, 0x08, 0x13, 0x23   }
,   // %
{
    0x00, 0x36, 0x49, 0x55, 0x22, 0x50   }
,   // &
{
    0x00, 0x00, 0x05, 0x03, 0x00, 0x00   }
,   // '
{
    0x00, 0x00, 0x1c, 0x22, 0x41, 0x00   }
,   // (
{
    0x00, 0x00, 0x41, 0x22, 0x1c, 0x00   }
,   // )
{
    0x00, 0x14, 0x08, 0x3E, 0x08, 0x14   }
,   // *
{
    0x00, 0x08, 0x08, 0x3E, 0x08, 0x08   }
,   // +
{
    0x00, 0x00, 0x00, 0xA0, 0x60, 0x00   }
,   // ,
{
    0x00, 0x08, 0x08, 0x08, 0x08, 0x08   }
,   // -
{
    0x00, 0x00, 0x60, 0x60, 0x00, 0x00   }
,   // .
{
    0x00, 0x20, 0x10, 0x08, 0x04, 0x02   }
,   // /
{
    0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E   }
,   // 0
{
    0x00, 0x00, 0x42, 0x7F, 0x40, 0x00   }
,   // 1
{
    0x00, 0x42, 0x61, 0x51, 0x49, 0x46   }
,   // 2
{
    0x00, 0x21, 0x41, 0x45, 0x4B, 0x31   }
,   // 3
{
    0x00, 0x18, 0x14, 0x12, 0x7F, 0x10   }
,   // 4
{
    0x00, 0x27, 0x45, 0x45, 0x45, 0x39   }
,   // 5
{
    0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30   }
,   // 6
{
    0x00, 0x01, 0x71, 0x09, 0x05, 0x03   }
,   // 7
{
    0x00, 0x36, 0x49, 0x49, 0x49, 0x36   }
,   // 8
{
    0x00, 0x06, 0x49, 0x49, 0x29, 0x1E   }
,   // 9
{
    0x00, 0x00, 0x36, 0x36, 0x00, 0x00   }
,   // :
{
    0x00, 0x00, 0x56, 0x36, 0x00, 0x00   }
,   // ;
{
    0x00, 0x08, 0x14, 0x22, 0x41, 0x00   }
,   // <
{
    0x00, 0x14, 0x14, 0x14, 0x14, 0x14   }
,   // =
{
    0x00, 0x00, 0x41, 0x22, 0x14, 0x08   }
,   // >
{
    0x00, 0x02, 0x01, 0x51, 0x09, 0x06   }
,   // ?
{
    0x00, 0x32, 0x49, 0x59, 0x51, 0x3E   }
,   // @
{
    0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C   }
,   // A
{
    0x00, 0x7F, 0x49, 0x49, 0x49, 0x36   }
,   // B
{
    0x00, 0x3E, 0x41, 0x41, 0x41, 0x22   }
,   // C
{
    0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C   }
,   // D
{
    0x00, 0x7F, 0x49, 0x49, 0x49, 0x41   }
,   // E
{
    0x00, 0x7F, 0x09, 0x09, 0x09, 0x01   }
,   // F
{
    0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A   }
,   // G
{
    0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F   }
,   // H
{
    0x00, 0x00, 0x41, 0x7F, 0x41, 0x00   }
,   // I
{
    0x00, 0x20, 0x40, 0x41, 0x3F, 0x01   }
,   // J
{
    0x00, 0x7F, 0x08, 0x14, 0x22, 0x41   }
,   // K
{
    0x00, 0x7F, 0x40, 0x40, 0x40, 0x40   }
,   // L
{
    0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F   }
,   // M
{
    0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F   }
,   // N
{
    0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E   }
,   // O
{
    0x00, 0x7F, 0x09, 0x09, 0x09, 0x06   }
,   // P
{
    0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E   }
,   // Q
{
    0x00, 0x7F, 0x09, 0x19, 0x29, 0x46   }
,   // R
{
    0x00, 0x46, 0x49, 0x49, 0x49, 0x31   }
,   // S
{
    0x00, 0x01, 0x01, 0x7F, 0x01, 0x01   }
,   // T
{
    0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F   }
,   // U
{
    0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F   }
,   // V
{
    0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F   }
,   // W
{
    0x00, 0x63, 0x14, 0x08, 0x14, 0x63   }
,   // X
{
    0x00, 0x07, 0x08, 0x70, 0x08, 0x07   }
,   // Y
{
    0x00, 0x61, 0x51, 0x49, 0x45, 0x43   }
,   // Z
{
    0x00, 0x00, 0x7F, 0x41, 0x41, 0x00   }
,   // [
{
    0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55   }
,   // 55
{
    0x00, 0x00, 0x41, 0x41, 0x7F, 0x00   }
,   // ]
{
    0x00, 0x04, 0x02, 0x01, 0x02, 0x04   }
,   // ^
{
    0x00, 0x40, 0x40, 0x40, 0x40, 0x40   }
,   // _
{
    0x00, 0x00, 0x01, 0x02, 0x04, 0x00   }
,   // '
{
    0x00, 0x20, 0x54, 0x54, 0x54, 0x78   }
,   // a
{
    0x00, 0x7F, 0x48, 0x44, 0x44, 0x38   }
,   // b
{
    0x00, 0x38, 0x44, 0x44, 0x44, 0x20   }
,   // c
{
    0x00, 0x38, 0x44, 0x44, 0x48, 0x7F   }
,   // d
{
    0x00, 0x38, 0x54, 0x54, 0x54, 0x18   }
,   // e
{
    0x00, 0x08, 0x7E, 0x09, 0x01, 0x02   }
,   // f
{
    0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C   }
,   // g
{
    0x00, 0x7F, 0x08, 0x04, 0x04, 0x78   }
,   // h
{
    0x00, 0x00, 0x44, 0x7D, 0x40, 0x00   }
,   // i
{
    0x00, 0x40, 0x80, 0x84, 0x7D, 0x00   }
,   // j
{
    0x00, 0x7F, 0x10, 0x28, 0x44, 0x00   }
,   // k
{
    0x00, 0x00, 0x41, 0x7F, 0x40, 0x00   }
,   // l
{
    0x00, 0x7C, 0x04, 0x18, 0x04, 0x78   }
,   // m
{
    0x00, 0x7C, 0x08, 0x04, 0x04, 0x78   }
,   // n
{
    0x00, 0x38, 0x44, 0x44, 0x44, 0x38   }
,   // o
{
    0x00, 0xFC, 0x24, 0x24, 0x24, 0x18   }
,   // p
{
    0x00, 0x18, 0x24, 0x24, 0x18, 0xFC   }
,   // q
{
    0x00, 0x7C, 0x08, 0x04, 0x04, 0x08   }
,   // r
{
    0x00, 0x48, 0x54, 0x54, 0x54, 0x20   }
,   // s
{
    0x00, 0x04, 0x3F, 0x44, 0x40, 0x20   }
,   // t
{
    0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C   }
,   // u
{
    0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C   }
,   // v
{
    0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C   }
,   // w
{
    0x00, 0x44, 0x28, 0x10, 0x28, 0x44   }
,   // x
{
    0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C   }
,   // y
{
    0x00, 0x44, 0x64, 0x54, 0x4C, 0x44   }
,   // z
{
    0x14, 0x14, 0x14, 0x14, 0x14, 0x14   }    // horiz lines
};

/********************************************************************
* 函数功能:LCD复位。
* 入口参数:无。
* 返    回:无。
* 备    注:无。
********************************************************************/

void ClrLcdRes(void)//LCD reset
{
digitalWrite( LCD_RST, LOW);
}

void SetLcdRes(void)
{
digitalWrite( LCD_RST, HIGH);
}
void ClrLcdDc(void)
{
digitalWrite( LCD_DC, LOW);
}
void ClrLcdCe(void)
{
digitalWrite( LCD_CE, LOW);
}
void SetLcdSi(void)
{
digitalWrite( SDIN, HIGH);
}
void ClrLcdSck(void)
{
digitalWrite( SCLK, LOW);
}
void SetLcdSck(void)
{
digitalWrite( SCLK, HIGH);
}
void SetLcdCe(void)
{
digitalWrite( LCD_CE, HIGH);
}
void ClrLcdSi(void)
{
digitalWrite( SDIN, LOW);
}
voidSetLcdDc()
{
digitalWrite( LCD_DC, HIGH);
}

void LcdReset(void)
{
ClrLcdRes();//RES置低
delayMicroseconds(1);
SetLcdRes();//RES置高
delayMicroseconds(10);
}
/////////////////////////End of function/////////////////////////////


/********************************************************************
* 函数功能:LCD写命令。
* 入口参数:cmd:要写的命令。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdWriteCmd(unsigned char cmd)
{
unsigned char i;

ClrLcdDc(); //选择命令
ClrLcdCe(); //片选
for(i=0;i<8;i++) //写一个字节的命令
{
    if(cmd&0x80)
    {
      SetLcdSi();
    }
    else
    {
      ClrLcdSi();
    }
    //产生一个上升沿
    ClrLcdSck();
    cmd<<=1;   //左移一位
    SetLcdSck();
}
SetLcdCe();
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:LCD写数据。
* 入口参数:dat:要写的数据。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdWriteData(unsigned char dat)
{
unsigned char i;

SetLcdDc(); //选择数据
ClrLcdCe(); //片选
for(i=0;i<8;i++) //写一个字节的数据
{
    if(dat&0x80)
    {
      SetLcdSi();
    }
    else
    {
      ClrLcdSi();
    }
    //产生一个上升沿
    ClrLcdSck();
    dat<<=1;   //左移一位
    SetLcdSck();
}
SetLcdCe();
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:LCD设置坐标值。
* 入口参数:相应的x、y值。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdSetXy(int x, int y)
{
LcdWriteCmd(0x80|(x&0x7F)); //X
LcdWriteCmd(0x40|(y&0x07)); //Y
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:将LCD缓冲区数据写到LCD中。
* 入口参数:无。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdRefresh(void)
{
int i;
LcdSetXy(0,0); //设置到坐标原点
for(i=0;i<6*84;i++)
{
    LcdWriteData(((unsigned char *)LcdBuffer)); //将buffer内数据发送到LCD
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:LCD清屏。
* 入口参数:无。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdCls(void)
{
int i;
LcdSetXy(0,0);//设置回原点
LcdSetPoint(0,0); //设置为原点
for(i=0;i<6*84;i++) //全部字节写入0
{
    LcdWriteData(0);
    ((unsigned char *)LcdBuffer)=0; //清空buffer
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:LCD初始化
* 入口参数:无。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdInit(void)
{


LcdReset();
LcdWriteCmd(0x21);        // 使用扩展命令设置LCD模式
LcdWriteCmd(0xc8);        // 设置偏置电压
LcdWriteCmd(0x06);        // 温度校正
LcdWriteCmd(0x13);        // 1:48
LcdWriteCmd(0x20);        // 使用基本命令
LcdCls();                 // 清屏
LcdWriteCmd(0x0c);        // 设定显示模式,正常显示
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:设置LCD显示的点。
* 入口参数:坐标x、y。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdSetPoint(int x, int y)
{
LcdX=x; //设置坐标
LcdY=y;
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:画一个点。
* 入口参数:坐标x、y。
* 返    回:无。
* 备    注:该函数调用完后必须调用LcdRefresh()函数刷新LCD才能显示。
********************************************************************/
void LcdDrawPoint(int x, int y)
{
if((x>83)||(y>47))return; //无效点,返回
LcdBuffer|=(1<<(y%8));//设置缓冲区中对应的点
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:擦除一个点。
* 入口参数:坐标x、y。
* 返    回:无。
* 备    注:该函数调用完后必须调用LcdRefresh()函数刷新LCD才能显示。
********************************************************************/
void LcdErasePoint(int x, int y)
{
if((x>83)||(y>47))return; //无效点,返回
LcdBuffer&=(unsigned char)(~(1<<(y%8)));//设置缓冲区中对应的点
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:画一个圆。
* 入口参数:x、y:圆心坐标;r:圆半径。
* 返    回:无。
* 备    注:该函数调用完后必须调用LcdRefresh()函数刷新LCD才能显示。
********************************************************************/
void LcdDrawCircle(int x, int y, int r)
{
int Angle;
float s,c;
for(Angle=0;Angle<360;Angle++) //从0到360度画一个圆
{
    //计算正弦和余弦值
    s=r*sin(Angle*PI/180);
    c=r*cos(Angle*PI/180);
    //四舍五入
    if(s<0)s-=0.5;
    else s+=0.5;
    if(c<0)c-=0.5;
    else c+=0.5;
    LcdDrawPoint(x+c,y+s); //画一个点
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:从点x0、y0画直线到x1、y1。
* 入口参数:起点坐标x0、y0,终点坐标x1、y1。
* 返    回:无。
* 备    注:该函数调用完后必须调用LcdRefresh()刷新LCD。
********************************************************************/
void LcdDrawLine(int x0, int y0, int x1, int y1)
{
int x,y,dx,dy,i,dir;
float d;

if((x0==x1)&&(y0==y1)) //如果只有一个点,那么就只画一个点
{
    LcdDrawPoint(x0,y0);
    return;
}

dx=abs(x1-x0); //求x、y的距离
dy=abs(y1-y0);
x=x0; //起点
y=y0;
if(dx>dy)   //如果x距离长,则从x轴方向移动
{
    //求出运动方向
    if(x1>x0)dir=1;
    else dir=-1;
    for(i=1;i<dx+1;i++)
    {
      LcdDrawPoint(x,y); //绘制对应的点
      x+=dir;//x改变一个单位
      d=(float)(y1-y0)*i/dx;
      if(d<0)d-=0.5;
      else d+=0.5;
      y=y0+d; //求出对应的y值
    }
}
else//如果y距离长,则从y轴方向移动
{
    if(y1>y0)dir=1; //求出运动方向
    else dir=-1;
    for(i=1;i<dy+1;i++)
    {
      LcdDrawPoint(x,y); //绘制对应的点
      y+=dir;//y改变一个单位
      d=(float)(x1-x0)*i/dy;
      if(d<0)d-=0.5;
      else d+=0.5;
      x=x0+d; //求出对应的x值
    }
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:填充一个矩形,包括边缘
* 入口参数:x0、y0:矩形的一个顶点;x1、y1:矩形的另一个顶点。
* 返    回:无。
* 备    注:该函数调用完后必须调用LcdRefresh()函数刷新LCD才能显示。
********************************************************************/
void LcdFill(int x0, int y0, int x1, int y1)
{
int d,i,y;
if(x0==x1) //只需要填充边沿
{
    LcdDrawLine(x0,y0,x0,y1);//用直线填充
    return;
}
if(y0==y1) //只需要填充边沿
{
    LcdDrawLine(x0,y0,x1,y0);//用直线填充
    return;
}
d=abs(y1-y0);
if(y1>y0) y=y0; //选择一个小的作为起点
else y=y1;
for(i=0;i<d;i++)
{
    LcdDrawLine(x0,y,x1,y);//用直线填充
    y++; //画下一条线
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:显示一个英文字符。
* 入口参数:要显示的字符的ASCII码。
* 返    回:无。
* 备    注:显示位置由LcdX和LcdY决定。如果显示范围,多余的部分将无法显示。
* 该函数调用完后必须调用LcdRefresh()函数刷新LCD才能显示。
********************************************************************/
void LcdPutChar(unsigned char ch)
{
unsigned char i,j,temp;
if((LcdX>83)||(LcdY>47))return; //超过范围,不用显示
ch-=' '; //字库是从空格开始的
for(i=0;i<6;i++) //每个字符有6个字节
{
    if(LcdX>83)break;//如果超过范围,则跳过
    temp=Font6x8;//取出一个字节
    for(j=0;j<8;j++)
    {
      if(LcdY>47)break; //如果超过范围,则跳过
      if(temp&0x01)LcdDrawPoint(LcdX,LcdY); //对应的位为1,画点
      else LcdErasePoint(LcdX,LcdY);   //对应的位为0,擦除
      temp>>=1;
      LcdY++;
    }
    LcdY-=j; //调整回Y值
    LcdX++;//调整X值
}
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
* 函数功能:在LCD上显示一个字符串。
* 入口参数:p:字符串指针。
* 返    回:无。
* 备    注:无。
********************************************************************/
void LcdPrints(unsigned char * p)
{
while(*p)
{
    LcdPutChar(*p);
    p++;
}
}
/////////////////////////End of function/////////////////////////////
void loop()
{
int bo;
LcdInit();
LcdDrawLine(0,24,84,24);
LcdDrawLine(0,0,0,48);
LcdRefresh();

bo=35;
while(1){
    for(int i=0;i<84;i++)
    {
      int step=720/84;
      float y1=sin(i*PI/bo)*24;
      float y2=sin((i+1)*PI/bo)*24;
      LcdDrawLine(i,24-y1,i+1,24-y2);
      //LcdDrawPoint(i,24-vet );
      //LcdRefresh();
    }

    LcdRefresh();
}

LcdCls();
}

Randy 发表于 2012-4-29 11:27:14

有空可以研究研究!做成库还是很方便的!

fangtaonj 发表于 2013-4-7 22:01:47

好东西!留记号备用!

wasdpkj 发表于 2013-4-7 23:59:56

能附上效果图就更好了

Fortware 发表于 2013-5-19 17:25:30


好啊,用得着,能附上效果图就更好了

wsy0315 发表于 2013-6-23 21:35:17

:) 标记一下

loucat 发表于 2014-3-13 20:08:14

Marking for remind

快乐每一天 发表于 2015-9-29 16:07:04

感觉超声波没有什么作用啊
页: [1]
查看完整版本: NOKIA 5110 LCD画图程序