#define uchar unsigned char
#define uint unsigned int
sbit SCLK = P3^1//液晶时钟线
sbit SDAT = P3^0//液晶数据线
void SEND_BYTE_LCD(uchar data_to_lcd)
void SEND_DATA_SER(bit codeordata, uchar SERIAL_DATA)//code 为1
void wrlcd(uchar HANG, uchar LIE, uchar *SENTENCE)
void lcdinit(void)
//void delay(uchar deltime)
/*********************************************************/
//延时程序
/********************************************************/
void delay(uint deltime)
{
uchar i
uint j
for (j = 0j <deltimej++)
for (i = 0i <255i++)
}
/*********************************************************
液晶写命令子程序
**********************************************************/
void SEND_BYTE_LCD(uchar data_to_lcd)
{
uchar j
for (j = 0j <8j++)
{
SDAT = (bit) (data_to_lcd &0x80)
SCLK = 0
SCLK = 0
SCLK = 0
SCLK = 0
SCLK = 0
SCLK = 1
SCLK = 1
SCLK = 1
SCLK = 1
SCLK = 1
data_to_lcd <<= 1
SCLK = 0
SCLK = 0
SCLK = 0
SCLK = 0
SCLK = 0
}
}
void SEND_DATA_SER(bit codeordata, uchar SERIAL_DATA)
{
uchar first, second, third
if (codeordata)
{
first = 0xf8
}
else
{
first = 0xfa
}
second = SERIAL_DATA &0xf0
third = SERIAL_DATA <<4
SEND_BYTE_LCD(first)
SEND_BYTE_LCD(second)
SEND_BYTE_LCD(third)
}
void wrlcd(uchar HANG, uchar LIE, uchar *SENTENCE)
{
uchar position
position = HANG + LIE
SEND_DATA_SER(1, position)
delay(2)
while (*SENTENCE)
{
SEND_DATA_SER(0, *SENTENCE++)
}
}
void lcdinit(void)
{
delay(100)
SEND_DATA_SER(1, 0X30)
delay(4)//基本功能设置
//SEND_DATA_SER(1,0X06)delay(2)
SEND_DATA_SER(1, 0X0C)
delay(4)
SEND_DATA_SER(1, 0X01)
delay(40)
SEND_DATA_SER(1, 0X02)
delay(40)
// SEND_DATA_SER(1,0X80)delay(2)
delay(10)
}
要注意,你说的通用型其实并不通用,LCD模块中使用不同的控制器,其控制方法都不同!所有的LCD模块都在Optoelectronics大类下。1602是LM016L;
12232有好几种:
AGM1232G DISPLAY122x32 Graphical LCD with SED1520 controllers
EW12A03GLY DISPLAY122x32 Graphical LCD with SED1520 controllers
HDM32GS12-B DISPLAY122x32 Graphical LCD with SED1520 controllers, LED Backlight
HDM32GS12Y-3 DISPLAY122x32 Graphical LCD with SED1520 controllers, Selectable Interface, VAC LED Backlight
12864也有好几种:
AMPIRE128X64DISPLAY128x64 Graphical LCD with KS0108 controllers
HDG12864F-1 DISPLAY128x64 Graphical LCD with SED1565 controller, Serial data input
HDG12864F-3 DISPLAY128x64 Graphical LCD with SED1565 controller, Parallel data input
HDG12864L-4 DISPLAY128x64 Graphical LCD with SED1565 controller, Parallel data input, LED Backlight
HDG12864L-6 DISPLAY128x64 Graphical LCD with SED1565 controller, Selectable Interface, LED Backlight
LGM12641BS1R DISPLAY128x64 Graphical LCD with KS0108 controllers
LM3228 DISPLAY128x64 Graphical LCD
LM4228 DISPLAY128x64 Graphical LCD
LM4265 DISPLAY128x128 Graphical LCD
PG128128A DISPLAY128x128 Graphical LCD Display
PG12864F DISPLAY128x64 Graphical LCD Display
TG126410GFSBDISPLAY128x66 Graphical LCD with SED1565 controllers, Bottom View
/*LCD12864显示程序此程序控制LCD12864液晶屏,IC为KS0108或兼容型号
图形文件获取方法:
在字模提取V21软件中 ,导入一幅128*64黑白图像.
* 参数设置:
* 参数设置->其它选项,选择纵向取模,勾上字节倒序,保留逗号,
* 取模方式为C51。
将生成的数组通过keilc等C编译软件,在编译软件中新建一工程,写入源程序如下:
unsigned char code tab[]=
{
//图像数据
}
编译此工程将得到hex文件.在QII中使用lpm_rom宏功能模块中调用此hex文件.
*
*******************************************************************************/
module newlcd(clock,rst_n,rs,rw,en,data,lcd_cs)
// I/O口声明
input clock //系统时钟
input rst_n //复位信号
output[1:0] lcd_cs //
outputrs //1:数据模式;0:指令模式
outputrw //1:读 *** 作;0:写 *** 作
outputen //使能信号,写 *** 作时在下降沿将数据送出;读 *** 作时保持高电平
output[7:0] data//LCD数据总线
// I/O寄存器
reg rs
reg en
reg[1:0] lcd_cs
reg[7:0] data
//内部寄存器
reg[3:0] state //状态机
reg[3:0] next_state
reg[20:0] div_cnt //分频计数器
reg[9:0] cnt //写 *** 作计数器
reg cnt_rst //写 *** 作计数器复位信号
wire[7:0] showdata //要显示的数据
reg[1:0] cs_r
reg [2:0] page_addr
reg [5:0] row_addr
//内部网线
wire clk_div//分频时钟
wire clk_divs
wire page_done //写一行数据完成标志位
wire frame_done //写一屏数据完成标志位
wire left_done
//状态机参数
parameter idle =4'b0000,
setbase_1=4'b0001,
setbase_2=4'b0011,
setmode_1=4'b0010,
setmode_2=4'b0110,
SETpage_addr_1=4'b0111,
SETpage_addr_2=4'b0101,
SETrow_addr_1 =4'b1101,
SETrow_addr_2 =4'b1111,
write_right_1 =4'b1110,
write_right_2 =4'b1010,
write_nextpage_1 =4'b1011,
write_nextpage_2 =4'b1001,
wr_data_1 =4'b0100,
wr_data_2 =4'b1100
// set_1=4'b1000
//******************************代码开始*********************************
assign rw = 1'b0 //对LCD始终为写 *** 作
//时钟分频
always@(posedge clock or negedge rst_n)
begin
if(!rst_n)
div_cnt <= 0
else
div_cnt <= div_cnt+1'b1
end
assign clk_div = (div_cnt[15:0] == 20'h7fff)
//状态机转向
always@(posedge clock or negedge rst_n)
begin
if(! rst_n)
state <= idle
else if(clk_div)
state <= next_state
end
//************************状态机逻辑*********************************
always@(state or page_done or left_done or frame_done or cnt or showdata or page_addr or row_addr or cs_r)
begin
rs <= 1'b0
en <= 1'b0
lcd_cs <= cs_r
cnt_rst <= 1'b0
data <= 8'h0
case(state)
idle:
begin
next_state <= setbase_1
cnt_rst <= 1'b1
end
//**************************初始化LCD********************************
setbase_1: //基本指令 *** 作
begin
lcd_cs <= 2'b11
next_state <= setbase_2
data <= 8'hc0
en <= 1'b1
end
setbase_2:
begin
lcd_cs <= 2'b11
next_state <= setmode_1
data <= 8'hc0
end
//******************************************************************
setmode_1:
begin
lcd_cs <= 2'b11
next_state <= setmode_2
data <= 8'h3f
en <=1'b1
end
setmode_2:
begin
next_state <= SETpage_addr_1
data <= 8'h3f
end
//******************************************************************
SETpage_addr_1: //设置页地址
begin
next_state <= SETpage_addr_2
data <=
en <= 1'b1
end
SETpage_addr_2:
begin
next_state <= SETrow_addr_1
data <=
end
SETrow_addr_1: //设置列地址
begin
next_state <= SETrow_addr_2
data <=
en <= 1'b1
end
SETrow_addr_2:
begin
next_state <= wr_data_1
data <=
end
//******************************************************************
/*
write_right_1: //写完左半屏64个,换为右半屏显示
begin
next_state <=write_right_2
row_addr <= 0
end
write_right_2:
begin
next_state <= SETpage_addr_1
end
//******************************************************************
write_nextpage_1: //写完全一行128个
begin
next_state <=write_nextpage_2
row_addr <= 0
end
write_nextpage_2:
begin
next_state <= SETpage_addr_1
end
*/
//******************************************************************
wr_data_1: //写数据到图形显示区
begin
next_state <= wr_data_2
rs <= 1'b1
en <= 1'b1
data <= showdata
end
wr_data_2:
begin
rs <= 1'b1
data <= showdata
if(left_done) //写完左半屏数据64个
begin
if(page_done) //写完一页数据128个
begin
if(frame_done) //写完一屏数据(8页)
next_state <= idle
else
// next_state <= write_nextpage_1
next_state <= SETpage_addr_1
end
else
// next_state <= write_right_1
next_state <= SETpage_addr_1
end
else
next_state <= wr_data_1
end
default: next_state <= idle
endcase
end
//********************************************************************
always@(posedge clock)
begin
if(clk_div)
begin
if(cnt_rst)
begin
cnt <= 0
end
else if(state == wr_data_2)
begin
cnt <= cnt+1'b1
end
end
end
//****************************************************
always@(posedge clock or negedge rst_n)
if(!rst_n)
begin
cs_r <= 2'b01
page_addr <= 0
end
else
if(clk_div &&(state == wr_data_2))
if(page_done)//
begin
cs_r <= 2'b01
page_addr <= page_addr + 1'b1//一页写完时写下一页
end
else
if(left_done)
begin
cs_r <= 2'b10
end
//*********************************************************************
//********************************************************************
assign left_done = (cnt[5:0] == 6'd63) //写完左半屏数据64个
assign page_done = (cnt[6:0] == 7'd127) //写完一页数据128个
assign frame_done = (cnt[9:4] == 7'h3f) //写完一屏数据
//***********************************************************************
//*******************************************************************
//调用ROM(图片数据)
rom rom(.address(cnt+'d8),.clock(clock),.q(showdata))
endmodule
开发板例程 自己看吧
我可以帮助你,你先设置我最佳答案后,我百度Hii教你。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)