51RTOS.com 版权所有 Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号 |
我爱嵌入式系统
这个屏我们有几种玩法:
采用3线串行方式的程序
//--------------------------------------------
//name: TG12232E 驱动程序
//mcu: ATmega8
//software: winavr
//time: 2005.5.10
//--------------------------------------------
// CS ----- PB2 LCD片选(串行) 0:禁止 1:允许
// SID ---- PB3 LCD输入串行数据(串行)
// CLK ---- PB5 LCD输入串行脉冲(串行)
#include <inttypes.h>
#include <avr/io.h>
#include <avr/delay.h>
#define FREQ 8 //Meaga8L,8MHz
#define SS PB2//LCD片选(串行) 0:禁止 1:允许
#define MOSI PB3//LCD输入串行数据(串行)
#define SCK PB5//LCD输入串行脉冲(串行)
void port_init(void)
{
DDRB = 0;//设置B口全为输入
DDRC = 0;//设置C口全为输入
DDRD = 0;//设置D口全为输入
PORTB = 0xff;//设置B口全部上拉
PORTC = 0xff;//设置C口全部上拉
PORTD = 0xff;//设置D口全部上拉
}
void spi_init(void)
{
// 设置MOSI 和SCK 及SS 为输出,其他为输入
DDRB = (1 << MOSI) | (1 << SCK) | (1 << SS);
PORTB = (1 << MOSI) | (1 << SCK) | (1 << SS);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0);
}
void delay_ms(unsigned int t)
{
unsigned int i;
for(i = 0; i < t; i++)
_delay_loop_2(250 * FREQ);
}
void spi_send(unsigned char data)
{
SPDR = data; // 启动spi
while(!(SPSR & (1 << SPIF))); // 等待传输结束
}
//---------------------------------------------------
// 发送8位LCD控制命令
//--------------------------------------------------
void lcd_send_com(unsigned char com)
{
PORTB |= (1 << SS); //SS=1,启动SPI
spi_send(0xf8); //发送LCD控制命令
spi_send(com & 0xf0); //发送高4位LCD控制命令
spi_send(com << 4); //发送低4位LCD控制命令
PORTB &= ~(1 << SS); //SS=0,关闭SPI
if (com == 0x01) _delay_loop_2(1600 * FREQ);//1.6mS
else _delay_loop_2(72 * FREQ); //st7920要求等待72uS
}
//--------------------------------------------------------
// 发送8位LCD显示数据
//-------------------------------------------------------
void lcd_send_data(unsigned char data)
{
PORTB |= (1 << SS); //SS=1,启动SPI
spi_send(0xfa); //发送LCD显示数据
spi_send(data & 0xf0); //发送高4位LCD显示数据
spi_send(data << 4); //发送低4位LCD显示数据
PORTB &= ~(1 << SS); //SS=0,关闭SPI
_delay_loop_2(72 * FREQ); //st7920要求等待延时72uS
}
//---------------------------------------------------
// LCD初始化设置
//---------------------------------------------------
void lcd_init(void)
{
delay_ms(100); //上电等待延时1000Ms
spi_init(); //SPI初始化
lcd_send_com(0b00100000); //发送4位控制命令
lcd_send_com(0b00000100); //发送进入点命令
lcd_send_com(0b00001100); //发送开显示关光标命令
lcd_send_com(0b00000001); //发送清除显示命令
lcd_send_com(0b10000000); //发送设定DDRAM地址0x00命令
}
//------------------------------------------
//定位
//----------------------------------------
unsigned char set_lcd_position(unsigned char row, unsigned char col)
{
if ((row < 2) && (col < 8)) //汉字字符为2行7.5列(汉字必须偶数对齐)
{
lcd_send_com(0x80 + row * 16 + col);//发送设定DDRAM地址row * 16 + col命令
return 1;//成功返回
}
else
return 0;//失败返回
}
//---------------------------------------------------
//显示字符串
//---------------------------------------------------
void lcd_display_string(unsigned char * string)
{
while(*string) lcd_send_data(*string ++);
}
//------------------------------------------------------------------------------------
//在指定位置显示
//------------------------------------------------------------------------------------
void lcd_display(unsigned char row, unsigned char col, unsigned char * string)
{
if (set_lcd_position(row, col))
{
lcd_display_string(string);
}
}
//========main=======================
int main(void)
{
port_init();
lcd_init();
set_lcd_position(0,1); //汉字定位到上行左端
lcd_display_string('欢迎光临本站');
lcd_display(1,0,' WWW.ICBEAN.COM ');
while(1);
}
采用并行8位式的程序
//--------------------------------------------
//name: TG12232E 驱动程序
//mcu: ATmega8
//software: winavr
//time: 2005.5.10
//author:Bromi
//7920中文LCD屏,带中文字库 TG12232E 并行8位
//联接: LCD MEGA8
// RS ----- PORTD.0
// RD ----- PORTD.1
// EN ----- PORTD.2
// DB0~7 ----- PORTB
//-----------------------------------------------
#include <inttypes.h>
#include <avr/io.h>
#include <avr/delay.h>
#define FREQ 8 //Meaga8L,8MHz
void delay_ms(unsigned int t) //毫秒延迟
{
unsigned int i;
for(i = 0; i < t; i++)
_delay_loop_2(250 * FREQ);
}
#define d_us(d) _delay_loop_2(d * FREQ)//微秒延迟
//-----------------------------------------------
//将数据输出到LCD接口,LCD数据口宽度为8bit
//rs: 1 操作指令寄存器,0 操作数据寄存器
//rd: 1 从LCD读出数据, 0 向LCD写数据
//portb: 要写入的数据
//-----------------------------------------------
//rs=PORTD.0
#define set_rs sbi( PORTD,0) //数据
#define clr_rs cbi( PORTD,0) //控制
//rw=PORTD.1
#define set_rw sbi( PORTD,1) //读
#define clr_rw cbi( PORTD,1) //写
//en=PORTD.2
#define set_e sbi( PORTD,2)
#define clr_e cbi( PORTD,2)
#define lcd_send_com(d) clr_rs;clr_rw;PORTB=d;set_e;d_us(200);clr_e //写指令
#define lcd_send_data(d) set_rs;clr_rw;PORTB=d;set_e;d_us(200);clr_e //写数据
//---------------------------------------------------
// LCD初始化设置
//---------------------------------------------------
void lcd_init(void)
{
delay_ms(100); //上电等待延时1000Ms
lcd_send_com(0b00110000); //发送8位控制命令
lcd_send_com(0b00000100); //发送进入点命令
lcd_send_com(0b00001100); //发送开显示关光标命令
lcd_send_com(0b00000001); //发送清除显示命令
lcd_send_com(0b10000000); //发送设定DDRAM地址0x00命令
}
//------------------------------------------
//定位
//----------------------------------------
unsigned char set_lcd_position(unsigned char row, unsigned char col)
{
if ((row < 2) && (col < 8)) //汉字字符为2行7.5列(汉字必须偶数对齐)
{
lcd_send_com(0x80 + row * 16 + col);//发送设定DDRAM地址row * 16 + col命令
return 1;//成功返回
}
else
return 0;//失败返回
}
//---------------------------------------------------
//显示字符串
//---------------------------------------------------
void lcd_display_string(unsigned char * string)
{
while(*string) lcd_send_data(*string ++);
}
//------------------------------------------------------------------------------------
//在指定位置显示
//------------------------------------------------------------------------------------
void lcd_display(unsigned char row, unsigned char col, unsigned char * string)
{
if (set_lcd_position(row, col))
{
lcd_display_string(string);
}
}
void port_init(void)
{
DDRB = 0xff; //设置B口全为输出
DDRC = 0; //设置C口全为输出
DDRD = 0xff; //设置D口全为输出
PORTB = 0xff; //设置B口全部上拉
PORTC = 0xff; //设置C口全部上拉
PORTD = 0xff; //设置D口全部上拉
}
//========main=======================
int main(void)
{
port_init();
lcd_init();
set_lcd_position(0,1); //汉字定位到上行左端
lcd_display_string('?迎光临本站')'
lcd_display(1,0,' 'WW.ICBEAN.COM ')'
while(1);
}
采用并行8位式的程序(C++版)
//-------------------------------------------
//name: TG12232E 驱动程序
//mcu: ATmega8
//software: AVR-GCC C++ TEST
//time: 2005.5.10
//-------------------------------------------
#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>
#include <string.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
#define FREQ 8 //Meaga8L,8MHz
#define SS PB2//LCD片选(串行) 0:禁止 1:允许
#define MOSI PB3//LCD输入串行数据(串行)
#define SCK PB5//LCD输入串行脉冲(串行)
class lcd
{
private:
unsigned char row,col;
void spi_mode_set(void);
public:
lcd(void); //lcd的构造函数
void lcd_send(unsigned char);
void dl_ms(unsigned int);
void lcd_init(void);
void lcd_send_com(unsigned char);
void lcd_send_data(unsigned char);
unsigned char set_position(unsigned char, unsigned char);
void get_position(unsigned char &, unsigned char &);
void lcd_display(unsigned char, unsigned char, const char *);
void lcd_display(const char *);
void lcd_display(uchar);
void lcd_display(int);
};
lcd::lcd(void)
{
row = 0;
col = 0;
spi_mode_set();
}
void lcd::spi_mode_set(void)
{
DDRB = (1 << MOSI) | (1 << SCK) | (1 << SS);
PORTB = (1 << MOSI) | (1 << SCK) | (1 << SS);
SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA) | (1 << SPR0);
}
void lcd::lcd_send(unsigned char cData)
{
SPDR = cData;
while(!(SPSR & (1 << SPIF)));
}
void lcd::dl_ms(unsigned int t)
{
unsigned int i;
for(i = 0; i < t; i++)
_delay_loop_2(250 * FREQ);
}
//--------------------------------------------------------
// 发送8位LCD控制命令
//------------------------------------------------------
void lcd::lcd_send_com(unsigned char cCommand)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
PORTB |= (1 << SS); //SS=1,启动SPI
lcd_send(0xf8); //发送LCD控制命令
lcd_send(cCommand & 0xf0);//发送高4位LCD控制命令
lcd_send(cCommand << 4);//发送低4位LCD控制命令
PORTB &= ~(1 << SS);//SS=0,关闭SPI
if (cCommand == 0x01) _delay_loop_2(1600 * FREQ);//1.6mS
else _delay_loop_2(72 * FREQ);//st7920要求等待72uS
}
/*--------------------------------------------------------
发送8位LCD显示数据
--------------------------------------------------------*/
void lcd::lcd_send_data(unsigned char cData)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
PORTB |= (1 << SS);//SS=1,启动SPI
lcd_send(0xfa);//发送LCD显示数据
lcd_send(cData & 0xf0);//发送高4位LCD显示数据
lcd_send(cData << 4);//发送低4位LCD显示数据
PORTB &= ~(1 << SS);//SS=0,关闭SPI
_delay_loop_2(72 * FREQ);//st7920要求等待延时72uS
}
/*---------------------------------------------------
LCD初始化设置
----------------------------------------------------*/
void lcd::lcd_init(void)
{
dl_ms(100);//上电等待延时1000Ms
spi_mode_set();//SPI初始化
lcd_send_com(0b00100000);//发送4位控制命令
lcd_send_com(0b00000010);//发送位址归位命令,设定DDRAM位址计数器为0
lcd_send_com(0b00000100);//发送进入点命令
lcd_send_com(0b00001100);//发送开显示关光标命令
lcd_send_com(0b00000001);//发送清除显示命令
lcd_send_com(0b10000000);//发送设定DDRAM地址0x00命令
}
unsigned char lcd::set_position(unsigned char row, unsigned char col)
{
row --;
col --;
if ((row < 2) && (col < 8)) {//汉字字符为2行7.5列(汉字必须偶数对齐)
lcd_send_com(0x80 + row * 16 + col);//发送设定DDRAM地址row * 16 + col命令
row = row;
col = col << 1;
return 1;
}
else
return 0;
}
void lcd::get_position(unsigned char &row, unsigned char &col)
{
row = row + 1;
col = col + 1;
}
void lcd::lcd_display(unsigned char row, unsigned char col, const char * string)
{
if (set_position(row, col)) lcd_display(string);
}
void lcd::lcd_display(const char * string)
{
while(*string) {
lcd_send_data(*string ++);
col ++;
}
}
void lcd::lcd_display(uchar Val)
{
char str[4];
itoa((int)Val, (char *)str, 10);
lcd_display((char *)str);
}
void lcd::lcd_display(int Val)
{
char str[6];
itoa(Val, (char *)str, 10);
lcd_display((char *)str);
}
lcd disp;
//-------------main程序------------------
int main(void)
{
disp.lcd_init(); //LCD初始化
for(;;)
{ //死循环
//----------------------------------------------------------------
// C++函数重载演示,所有LCD显示函数都使用一个函数名lcd_display()
//----------------------------------------------------------------
disp.lcd_display(1,2,'迎光临本站'); //在当前位置显示汉字串
disp.dl_ms(1000); //延时1000Ms
disp.lcd_display(2,1,'WWW.ICBEAN.COM');//www.ICBEAN.COM'
}
}
51RTOS.com 版权所有 Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号 |