正文

LPC213X模拟SPI之LCD12864 C++代码2008-02-22 22:30:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/niao0311/32874.html

分享到:

/*--------------------------------------------------------------------

LPC213X模拟SPI之LCD12864 C++代码

HotPower@126.com

--------------------------------------------------------------------*/

//由于SPI/SSP都专用了,不得不用IO模拟SPI控制LCD

 

//__inline
LcdObj::LcdObj(void)
{
  LcdPinSetup();
  LcdInit();
}


//__inline
void LcdObj::LcdPinSetup(void)
{
/*
  POWER->P_CONP |= (1 << PCSPI0);
  PINSEL->PIN_SEL0 |= ((P0_4_SCK0 << P0_4_PINSEL) | (P0_6_MOSI0 << P0_6_PINSEL));
//  SPI->SPI_SPCCR = 0x168;              // 设置SPI时钟分频
  SPI->SPI_SPCCR = 0x52;              // 设置SPI时钟分频
  SPI->SPI_SPCR  =
            (1 << CPHA) |    // CPHA = 0, 数据在SCK 的第一个时钟沿采样
        (1 << CPOL) |    // CPOL = 1, SCK 为低有效
       (1 << MSTR) |    // MSTR = 1, SPI 处于主模式
       (0 << LSBF) |    // LSBF = 0, SPI 数据传输MSB (位7)在先
       (0 << SPIE);    // SPIE = 0, SPI 中断被禁止
*/


/* 设置MOSI 和SCK 及SS 为输出,其他为输入 */
  LCDPORT->IODIR |= (1 << LCDRST) | (1 << LCDCS) | (1 << LCDSCK) | (1 << LCDSID);
  LCDPORT->IOCLR  = (1 << LCDRST) | (1 << LCDCS);
  LCDPORT->IOSET = (1 << LCDSCK) | (1 << LCDSID);
  _delay_loop_(10);
  LCDPORT->IOSET = (1 << LCDRST);
  _delay_loop_(100);
}

//__inline
void LcdObj::LcdInit(void)
{
/*---------------------------------------------------
    LCD模块上电等待延时
----------------------------------------------------*/
  LcdClearBuffer();
  LcdSendCommand(0x20);//发送4位控制命令
//  LcdSendCommand(0x30);//发送8位控制命令//与8位4位无关!!!
  LcdSendCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0
  LcdSendCommand(0x04);//发送进入点命令
  LcdSendCommand(0x0c);//发送开显示关光标命令
  LcdSendCommand(0x01);//发送清除显示命令
  LcdSendCommand(0x80);//发送设定DDRAM地址0x00命令
//汉字0xfd出错测试   
  LcdDisplay("褒饼昌除待谍洱俘");
  SetLcdDisplayPos(1, 0);//汉字定位到上行左端
  LcdDisplay("庚过糊积箭烬君魁");
  SetLcdDisplayPos(2, 0);//汉字定位到上行左端
  LcdDisplay("例笼慢谬凝琵讫驱");
  SetLcdDisplayPos(3, 0);//汉字定位到上行左端
  LcdDisplay("三升数她听妄锡淆");

}

//__inline
void LcdObj::LcdSend(char cData)
{
unsigned int i;
//  _delay_loop_(1);
  for (i = 0; i < 8; i ++) {
//    _delay_loop_(1);
    LCDPORT->IOCLR = (1 << LCDSCK);
//    _delay_loop_(1);
    if (cData & 0x80) {//MSB最高位为1时
      LCDPORT->IOSET = (1 << LCDSID);
 }
 else {
      LCDPORT->IOCLR = (1 << LCDSID);
 }
//    _delay_loop_(1);
 cData <<= 1;
    LCDPORT->IOSET = (1 << LCDSCK);
//    _delay_loop_(1);
  } 
/*
  SPI->SPI_SPDR = cData;                        //发送数据(相当于51的SBUF = DATA)
  while(!(SPI->SPI_SPSR & (1 << SPIF)));  // 等待SPIF置位,即等待数据发送完毕
*/
}

 

/*--------------------------------------------------------
    发送8位LCD控制命令
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendCommand(char cCommand)
{
/*--------------------------------------------------------
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
  LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
  LcdSend(0xf8);//发送LCD控制命令
  LcdSend(cCommand & 0xf0);//发送高4位LCD控制命令
  LcdSend(cCommand << 4);//发送低4位LCD控制命令
  LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
  if (cCommand == 0x01) _delay_loop_(160);//1.6mS
  else _delay_loop_(72);//st7920要求等待72uS
}

/*--------------------------------------------------------
    发送8位LCD显示数据
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendData(char cData)
{
/*--------------------------------------------------------
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
  LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
  LcdSend(0xfa);//发送LCD显示数据
  LcdSend(cData & 0xf0);//发送高4位LCD显示数据
  LcdSend(cData << 4);//发送低4位LCD显示数据
  LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
  _delay_loop_(72);//st7920要求等待延时72uS
}

//__inline
void LcdObj::SetLcdDisplayPos(unsigned char row, unsigned char col)
{
  row &= 0x03;//4行汉字
  col &= 0x0f;//每行8个汉字16个字符
  LcdRow = row;
  LcdCol = col;
  LcdRowWriteEnable[row] = 1;//允许此行刷新汉字显示
}

//__inline
void LcdObj::LcdClearBuffer(void)
{
unsigned char i, j;
  for (i = 0;i < 4;i ++) {
    for (j = 0;j < 16; j ++) {
      LcdBuffer[i][j] = ' ';
    }
    LcdRowWriteEnable[i] = 1;//允许此行刷新汉字显示
  }
  LcdRow = 0;
  LcdCol = 0;
}

//__inline
void LcdObj::LcdDisplayBuffer(void)
{
unsigned char i, j;
  for (i = 0; i < 4; i ++) {//4行汉字
    if (LcdRowWriteEnable[i]) {//允许此行刷新汉字显示
      LcdSendCommand(0x80 + (i & 1) * 16 + (i >> 1) * 8);//移动光标
      for (j = 0; j < 16; j ++) {//每行8个汉字16个字符
        LcdSendData(LcdBuffer[i][j]);//刷新显示字符
      }
   LcdRowWriteEnable[i] = 0;//过后不允许此行刷新汉字显示
 }
  }
}

//__inline
void LcdObj::LcdDisplay(const char * string)
{
  while(*string) {
    LcdBuffer[LcdRow][LcdCol ++] = *string ++;
  }
}

void LcdObj::LcdDisplay(unsigned char hexstr[], unsigned int len)
{
unsigned char ch;
  for (int i = 0; i < len; i ++) {
    ch = *hexstr++;
 if (ch < 0xa0) {
      LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) + '0';
 }
 else {
      LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) - 10 + 'A';
 }
 if ((ch & 0x0f) < 0x0a) {
      LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) + '0';
 }
 else {
      LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) - 10 + 'A';
 }
  }
}

void LcdObj::LcdDisplay(unsigned int Val, unsigned char size1, signed char size0)
{
char str[7], *ptr;
unsigned char i;
  ptr = str + 5;
  if (size0 > 0) {//有小数
    for (i = 0; i < 3; i ++) {
   *ptr -- = (Val % 10) + '0';
   Val /= 10;
    }
    ptr[size0 + 1] = 0;
    *ptr -- = '.';
  }
  else {
    *ptr -- = 0;
  }
  for (i = 0; i < size1; i ++) {
    if (i && (Val == 0)) {
   if (size0 < 0) {
     *ptr -- = '0';
   }
   else {
     *ptr -- = ' ';
   }
    }
 else *ptr -- = (Val % 10) + '0';
 Val /= 10;
  }
  LcdDisplay(ptr + 1);
}

阅读(2409) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册