www.openedv.com
您好,欢迎您!    会员注册 | 登入 
公告:欢迎访问www.openedv.com开源电子网,开源共享共同进步,祝您新年快乐,万事如意!
设为首页 | 加入收藏
论坛首页 » 51单片机 前往: 
【Ling.Ju的百宝箱】STC SPI 应用之12864(7920)~
发表人 内容
[Down] [Up]
[楼主位] LingJu


等级:NO
注册时间:
2010/12/14 09:02
文章: 13
来自: 上海
离线

 呵呵,那什么练手好呢,看了下7920的12864,就是他了,先对比下时序

一步步来。


上面是7920的SPI时序,下面是STC的SPI时序,用的是STC12C5A60S2,STC的英文资料,难得吧,感觉E文的广告能少点。。。。

继续折腾完毕~

下面是结果~~



//========================================代码区==========================================//

//#include <STC_NEW_8051.H>
#include "reg51.h"
//============================================================================================================

#define uint unsigned int
#define uchar unsigned char

//引脚定义
sbit    LCD_CS    =P1^4;        // 片选 高电平有效 单片LCD使用时                     可固定高电平
sbit    LCD_SID   =P1^5;        // 数据
sbit    LCD_CLK   =P1^7;        // 时钟
sbit    LCD_PSB   =P3^5;        // 低电平时表示用串口驱动,                          可固定低电平
sbit    LCD_RST   =P3^6;        // LCD复位,LCD模块自带复位电路。                    可不接
//sbit  LCD_BACK  =P2^6;        // LCD背光控制

//=========================================================================


#define MASTER                  //define:master undefine:slave

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;

sfr  AUXR       =   0x8e;       //Auxiliary register
sfr SPSTAT      =   0xcd;       //SPI status register       84
#define SPIF        0x80        //SPSTAT.7
#define WCOL        0x40        //SPSTAT.6

sfr SPCTL       =   0xce;       //SPI control register      85
#define SSIG        0x80        //SPCTL.7
#define SPEN        0x40        //SPCTL.6
#define DORD        0x20        //SPCTL.5
#define MSTR        0x10        //SPCTL.4
#define CPOL        0x08        //SPCTL.3
#define CPHA        0x04        //SPCTL.2
#define SPDHH       0x00        //CPU_CLK/4
#define SPDH        0x01        //CPU_CLK/16
#define SPDL        0x02        //CPU_CLK/64
#define SPDLL       0x03        //CPU_CLK/128

sfr SPDAT       =   0xcf;       //SPI data register         86
sbit SPISS      =   P1^3;       //SPI slave select, connect to slave' SS(P1.4) pin


void InitSPI()
{
    SPDAT = 0;                  //initial SPI data
    SPSTAT = SPIF | WCOL;       //clear SPI status
#ifdef MASTER
    SPCTL = SPEN | MSTR | CPHA | CPOL | SPDH;               //master mode
#else
    SPCTL = SPEN;               //slave mode
#endif
}

BYTE SPISwap(BYTE dat)
{
#ifdef MASTER
    SPISS = 1;                  //pull low slave SS
#endif
    SPDAT = dat;                //trigger SPI send
    while (!(SPSTAT & SPIF));   //wait send complete
    SPSTAT = SPIF | WCOL;       //clear SPI status
#ifdef MASTER
    SPISS = 0;                  //push high slave SS
#endif
    return SPDAT;               //return received SPI data
}

//=========================================================================

void Delay(uint Number)
{
  uint i,j;

  for (i=0; i<Number; i++)
  {
      for(j=0; j<10; j++)
        {
   ;
  }
 }
}

/*****************************************************/

void Send_byte(uchar Byte)
{

    SPISwap(Byte);

// 以下方式为模拟SPI
// uchar i;
//  for (i=0; i<8; i++)
//    {
//     LCD_SID = Byte&0x80;             // 取出最高位 写入串行数据
//     LCD_CLK = 1;                     // 串行同步时钟信号
//     LCD_CLK = 0;
//    Byte <<= 1;                       // 左移
//   } 
}
/*****************************************************/

void WriteCommandLCM(uchar WCLCM)
{
   uchar Start_data,Hdata,Ldata;

 Start_data = 0xf8;                     // 写指令 11111000
 
   Hdata = WCLCM&0xf0;                  // 取高四位   DDDD0000
   Ldata = (WCLCM << 4) & 0xf0;         // 取低四位   0000DDDD

   Send_byte(Start_data);               // 发送起始信号 第1字节-格式:1111ABC
   Delay(5);                            // 延时是必须的

   Send_byte(Hdata);                    // 发送高四位   第2字节-格式:DDDD0000
   Delay(1);                            // 延时是必须的

   Send_byte(Ldata);                    // 发送低四位   第3字节-格式:0000DDDD
   Delay(1);                            // 延时是必须的
}
/*****************************************************/

void WriteDataLCM(uchar WDLCM)
{
   uchar Start_data,Hdata,Ldata;

    Start_data = 0xfa;                   // 写数据 11111010

   Hdata = WDLCM & 0xf0;                 // 取高四位   DDDD0000
   Ldata = (WDLCM << 4) & 0xf0;          // 取低四位   0000DDDD

   Send_byte(Start_data);                // 发送起始信号 第1字节-格式:1111ABC
   Delay(5);                             // 延时是必须的

   Send_byte(Hdata);                     // 发送高四位   第2字节-格式:DDDD0000
   Delay(1);                             // 延时是必须的

   Send_byte(Ldata);                     // 发送低四位   第3字节-格式:0000DDDD
   Delay(1);                             // 延时是必须的
}

/*****************************************************/

void Lcdinit(void) 
{
   Delay(10);                              // 启动等待,等LCM讲入工作状态
   LCD_PSB = 0;                            // 串口驱动模式
   LCD_RST = 0;

    Delay(1);
    LCD_RST = 1;                           // 复位LCD
    LCD_CS = 1;                            // 片选

   WriteCommandLCM(0x30);                  // 8 位介面,基本指令集
   WriteCommandLCM(0x0c);                  // 显示打开,光标关,反白关
   WriteCommandLCM(0x01);                  // 清屏,将DDRAM的地址计数器归零 
}

/*****************************************************/

void DisplayListChar(uchar x, uchar y, uchar code *s)
{
 uchar add;                             // 显示地址

 switch (y)                             // 显示地址计数
 {
  case 0: add = x + 0x80; break;        // 第一行的地址
  case 1: add = x + 0x90; break;        // 第二行的地址 
  case 2: add = x + 0x88; break;        // 第三行的地址
  case 3: add = x + 0x98; break;        // 第四行的地址
  default: break;
 }

 WriteCommandLCM(0x30);                 // 8位介面,基本指令集
 WriteCommandLCM(add);                  // 写入地址

    while (*s > 0)                      // 写入字符串
    {
     WriteDataLCM(*s);
        s++;
        Delay(50);
    }
}

/*****************************************************/

//图形方式

//void DisplayPicture(uint code *img)
//{
//    uchar Line,Row;                   // Line为行地址;Row为列地址
//    uint regist = 0;                  // 图形地址寄存器
//
// WriteCommandLCM(0x36);               // 图形方式,扩展指令
//    // -------------- 上半屏 ----------------
//   for (Line=0; Line<32; Line++)    
//    {
//       WriteCommandLCM(0x80 + Line);  // 写入行地址
//       WriteCommandLCM(0x80);         // 写入列
//
//       for (Row=0; Row<16; Row++)
//  {
//       WriteDataLCM(img[regist++]);   // 写入图片数据
//  }
//    }
//    // --------------- 下半屏 ---------------
//   regist=512;                        // 下半屏起始数据
//
//   for (Line=0; Line<32; Line++) 
//    {
//       WriteCommandLCM(0x80 + Line);  // 写入行地址
//    WriteCommandLCM(0x88);            // 写入列
//
//       for (Row=0; Row<16; Row++)
//  {
//        WriteDataLCM(img[regist++]);  // 写入图片数据
//  }
//    }
//
// WriteCommandLCM(0x30);               // 基本指令
//}

/*****************************************************/

void main(void)
{
     
   InitSPI();                           //initial SPI

   Delay(10);

   Lcdinit();                           // 初始化LCD

   Delay(100);

   DisplayListChar(0,0,"人生若只是初见,");
   DisplayListChar(0,1,"何事秋风悲画扇。");
   DisplayListChar(0,2,"等闲变却故人心,");
   DisplayListChar(0,3,"却道故人心易变。");

   while(1)
   {

   }

}


//========================================代码区完==pp上场==================================//



真正用到的数据口只用了两个哦~



实际的IO用了两个,片选直接接高!

秉承一贯闹着玩的做风~
 
P.S:  这句话!!

SPCTL = SPEN | MSTR | CPHA | CPOL | SPDH;               //master mode

注意SPI的设置!!换了别的东西还得先看看手册啊!!



这篇文章被编辑了 5 次. 最近一次更新是在 2011/01/08 13:12


while(1);
[加为好友] 回复 引用回复
[Down] [Up]
[1楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8089
来自: 湖南
在线

STC应该也没有说的那么差了。
7920,我好像貌似用过。小个头的LCD。。。



我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
 
前往: 

Powered by ALIENTEK工作室 © 粤ICP备12000418号-1