⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 st7920.txt

📁 ST7920带中文字库液晶原码程序 12864 keil的
💻 TXT
📖 第 1 页 / 共 2 页
字号:
12864 keil的,串行方式 编写时已经考虑到往avr上的移植了,spi可以用avr硬件的,也可以用io模拟,甚至可以用mega48的串口做spi主机 


,经过我的测试串行方式,在cs无效时,7920还是可以接受数据,导致显示被误改,如果spi上接了其它器件,小心使用。 

sbit ST7920CS=P3^3; 

void write7920cmd(unsigned char cmd) 
{ 
   unsigned char i=0; 
    
    
   ST7920CS=1; 
   Spi(0xf8); 
   Spi(cmd&0xf0); 
   Spi(cmd<<4);    
   ST7920CS=0; 
   Delay10us(10); 
} 
void write7920data(unsigned char dat) 
{ 
    
   ST7920CS=1; 
   Spi(0xfa); 
   Spi(dat&0xf0); 
   Spi(dat<<4);    
   ST7920CS=0; 
   Delay10us(10); 
} 
void init7920(void) 
{ 
   write7920cmd(0x20);//4bit 基本指令 
   write7920cmd(0x20);//4bit 基本指令 
   write7920cmd(0x0c);//开显示 
   write7920cmd(0x01);//清屏 
   write7920cmd(0x06); 
} 




void DispSetCursor(unsigned char LineNum, unsigned char ColumnNum) 
{ 

    unsigned char i=0x00; 
    switch(LineNum&0x0f)   //确定行号 
    { 
   case 0x00: 
      i=0x80; 
      break; 
   case 0x01:  
      i=0x90;  
      break; 
   case 0x02:  
      i=0x88; 
      break; 
   case 0x03: 
      i=0x98; 
      break; 
   default :  
      break; 
    } 
    i = (ColumnNum&0x0f)|i; //确定列号 
   write7920cmd(i); 
    
} 


汉字显示参考代码 


unsigned char code mainmenu[]="1:当前时间2:tcp/ip参数设置3:AD采样按 1,2,3选择操作"; 


void dis_mainmenu(void) 
{ 
    
   unsigned char i; 
    
    
      DispSetCursor(0,0);     // 
      for (i=0;i<10;i++)    // 
          
      { 
         write7920data(mainmenu[i]); //1:当前时间 
      } 
      DispSetCursor(1,0);     // 
      for (;i<26;i++)    // 
          
      { 
         write7920data(mainmenu[i]); //2:tcp/ip参数设置 
      } 
      DispSetCursor(2,0);     // 
      for (;i<34;i++)    // 
          
      { 
         write7920data(mainmenu[i]); //3:AD采样 
      } 
      DispSetCursor(3,0);     // 
      for (;i<50;i++)    // 
          
      { 
         write7920data(mainmenu[i]); //按 1,2,3选择操作 
      } 
} 


谢谢mucode... 

我也将51asm移植到WinAvr,但由于买的是5V的HS12232-9,但手头只有3.3V的M8L系统,所以驱动不了,不知对否??? 
山区确实山路崎岖,3.3V的HS12232-9必须一周后才能到货... 

只好明天上班用5V系统了... 

以下是我移植的,请mucode同志个指教一番...主要是在时序方面... 

#include <inttypes.h> 
#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <avr/signal.h> 
#include <avr/wdt.h> 
#include <avr/ina90.h> 
#include <avr/eeprom.h> 
//#include <stdio.h> 
#include <avr/delay.h> 


#define  FREQ 8  //Meaga8L,8MHz 
#define  CS   PB2//LCD片选(串行) 0:禁止 1:允许 
#define  SID  PB3//LCD输入串行数据(串行) 
#define  CLK  PB5//LCD输入串行脉冲(串行) 

#define  SS   PB2//LCD片选(串行) 0:禁止 1:允许 
#define  MOSI PB3//LCD输入串行数据(串行) 
#define  SCK  PB5//LCD输入串行脉冲(串行) 

void PortIoInit(void) 
{ 
  DDRB  = 0;//设置B口全为输入 
  DDRC  = 0;//设置C口全为输入 
  DDRD  = 0;//设置D口全为输入 
  PORTB = 0xff;//设置B口全部上拉 
  PORTC = 0xff;//设置C口全部上拉 
  PORTD = 0xff;//设置D口全部上拉 
} 

void SPI_MasterInit(void) 
{ 
/* 设置MOSI 和SCK 为输出,其他为输入 */ 
  DDRB = (1 << MOSI) | (1 << SCK); 
/* 使能SPI 主机模式,设置时钟速率为fck/16 ,SPI方式3*/ 
  SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA) | (1 << SPR0); 
/* 使能SPI 主机模式,设置时钟速率为fck/16 ,SPI方式2*/ 
//  SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << SPR0); 
} 

void SPI_MasterTransmit(unsigned char cData) 
{ 
/* 启动数据传输 */ 
  SPDR = cData; 
/* 等待传输结束 */ 
  while(!(SPSR & (1 << SPIF))); 
} 

void DelayMs(unsigned int t) 
{ 
unsigned int i; 
  for(i = 0; i < t; i++) 
    _delay_loop_2(250 * FREQ); 
} 

/*-------------------------------------------------------- 
    发送8位LCD控制命令 
--------------------------------------------------------*/ 
void LcdSendCommand(unsigned char cCommand) 
{ 
  _delay_loop_2(72 * FREQ);//st7920要求等待72uS 
/*-------------------------------------------------------- 
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右) 
--------------------------------------------------------*/ 
  PORTB &= ~(1 << SS);//SS=0,启动SPI 
  SPI_MasterTransmit(0xf8);//发送LCD控制命令 
  SPI_MasterTransmit(cCommand & 0xf0);//发送高4位LCD控制命令 
  SPI_MasterTransmit(cCommand << 4);//发送低4位LCD控制命令 
  PORTB |= (1 << SS);//SS=1,关闭SPI 
} 

/*-------------------------------------------------------- 
    发送8位LCD显示数据 
--------------------------------------------------------*/ 
void LcdSendData(unsigned char cData) 
{ 
  _delay_loop_2(72 * FREQ);//st7920要求等待延时72uS 
/*-------------------------------------------------------- 
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右) 
--------------------------------------------------------*/ 
  PORTB &= ~(1 << SS);//SS=0,启动SPI 
  SPI_MasterTransmit(0xfa);//发送LCD显示数据 
  SPI_MasterTransmit(cData & 0xf0);//发送高4位LCD显示数据 
  SPI_MasterTransmit(cData << 4);//发送低4位LCD显示数据 
  PORTB |= (1 << SS);//SS=1,关闭SPI 
} 


/*--------------------------------------------------- 
    LCD初始化设置 
----------------------------------------------------*/ 
void LcdInit(void) 
{ 
/*--------------------------------------------------- 
    LCD模块上电等待延时 
----------------------------------------------------*/ 
  DelayMs(1000);//上电等待延时1000Ms 
  SPI_MasterInit();//SPI初始化 
  LcdSendCommand(0b00100000);//发送4位控制命令 
  LcdSendCommand(0b00000010);//发送位址归位命令,设定DDRAM位址计数器为0 
  LcdSendCommand(0b00000100);//发送进入点命令 
  LcdSendCommand(0b00001100);//发送开显示关光标命令 
  LcdSendCommand(0b00000001);//发送清除显示命令 
  LcdSendCommand(0b10000000);//发送设定DDRAM地址0x00命令 
} 

unsigned char SetLcdDisplayCharPos(unsigned char row, unsigned char col) 
{ 
  if ((row < 2) && (col < 16))//英文字符为2行16列 
  { 
    LcdSendCommand(0x80 + row * 16 + col);//发送设定DDRAM地址row * 16 + col命令 
   return 1; 
  } 
  else  
    return 0; 
} 


void LcdDisplayChar(unsigned char row, unsigned char col, unsigned char * string) 
{ 
  if (SetLcdDisplayCharPos(row, col)) 
  { 
    LcdSendData(*string); 
  } 
} 

unsigned char SetLcdDisplayChinsePos(unsigned char row, unsigned char col) 
{ 
  if ((row < 2) && (col < 8))//汉字字符为2行8列(偶数对齐) 
  { 
    LcdSendCommand(0x80 + row * 16 + col * 2);//发送设定DDRAM地址row * 16 + col * 2命令 
   return 1; 
  } 
  else 
    return 0; 
} 

void LcdDisplayChinse(unsigned char row, unsigned char col, unsigned char * string) 
{ 
  if (SetLcdDisplayChinsePos(row, col)) 
  { 
    LcdSendData(*string); 
    LcdSendData(*(string + 1)); 
  } 
} 

void LcdDisplayString(unsigned char * string) 
{ 
  while(*string) LcdSendData(*string ++); 
} 


//main程序 
void main(void) 
{ 
  PortIoInit(); 
  LcdInit(); 
// sei(); 
  SetLcdDisplayChinsePos(0, 0);//汉字定位到上行左端 
  LcdDisplayString("汉字显示演示程序"); 
  SetLcdDisplayCharPos(1,0);//字符定位到下行左端 
  LcdDisplayString("0123456789ABCDEF"); 
  for(;;) 
  { 
  }    
} 


用串行方式的最大缺点:无法读取显示ram 
复杂的图形操作可能就不好做了 

另外我用的这个12864,和一个spi的ad挂在一起,用两个io分别使能,结果ad控制正常,st7920却不受cs控制,始终接受数据,导致控制ad时显示乱码。现在pcb不能改,只好想办法破坏时序,避免显示出错。 
我正好写过一个,不过是4位的。 


//******************************************** 
//7920中文LCD屏,带中文字库 
//联接: LCD      MEGA128 
//      RS ----- PORTC.0 
//      RD ----- PORTC.1 
//      EN ----- PORTC.2 
//     DB4 ----- PORTC.4 
//     DB5 ----- PORTC.5 
//     DB6 ----- PORTC.6 
//     DB7 ----- PORTC.7 
//******************************************** 
#define LCD_RS PORTC.0 
#define LCD_RD PORTC.1 
#define LCD_EN PORTC.2 
#define LCD_DB PORTC 


//******************************************** 
//将数据输出到LCD接口,LCD数据口宽度为4bit 
//rs: 1 操作指令寄存器,0 操作数据寄存器 
//rd: 1 从LCD读出数据, 0 向LCD写数据 
//db: 要写入的数据,仅底4位有效 
//******************************************** 
void lcd_setport(char rs,char rd,char db) 
{ 
 //unsigned char temp; 
 db=db<<4; 
 LCD_RS=rs; 
 LCD_RD=rd; 
 delay_us(20); 
 LCD_EN=1; 
 delay_us(10); 
 LCD_DB=LCD_DB&0x0F; 
 LCD_DB=LCD_DB|db; 
 //LCD_DB=db; 
 delay_us(10); 
 LCD_EN=0; 
 delay_us(20); 

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -