8051单片机,用6线驱动1602共用6个IO口,并行驱动显示
51通常的例程,大部分是用并行8线来驱动的,我们尝试用4线,分两次发送。写命令和数据。这样的话数据口就只用4条线。
R/W线,因为我们主要用的是写数据,或者是写命令,很少用到读,只有需要读忙状态才用到,我们可以用1毫秒的延时来替代,这样的话直接R/W接地。
上接线图,R22是用来限流,可以直接接VCC也就是直接连到2脚上,16脚直接连到1脚上。
3脚VL,接1K电阻到1脚,这样能正常显示,只是不能调节对比度,管它呢,只要能显示就行。
这样一来 ,需要8条线,两条电源线,6条数据线。
硬件连线上图
没有找到碳膜电阻用个0603焊上了。{:ciya:}{:ciya:}
硬件接完了,接下来就是函数了。
我们不做太多显示,只显示一个字符,证明能显示就是。
分下面几部
1,定义管脚
2,写一个字节数据函数
3,写一个字节命令函数
4,屏幕初始化
5,写一个需要显示位置的函数
这样就可以显示字符了
写函数之前强调一下,通常的1602规格书没有介绍,4线和8线如何配置,其实初始化写命令时把,0X38改成0X28就改好了。
写一个字节数据
//写一个字节数据
void LCD1602_Write_Data(unsigned char dat) //写数据
{
DelayXms(1); //毫秒延时跳过忙检测
RS = 1; //发数据写 1
//写高4位
//Data_IO_Port = dat & 0xF0;//写高4位
LCD_Data8 = dat & 0x80;// 1000 0000
LCD_Data7 = dat & 0x40;// 0100 0000
LCD_Data6 = dat & 0x20;// 0010 0000
LCD_Data5 = dat & 0x10;// 0001 0000
EN = 1; //打开使能
Delay10us();//10微秒延时
EN = 0; //关闭使能
//写低4位
//Data_IO_Port = dat<< 4;//写低4位
LCD_Data8 = dat & 0x08; //0000 1000
LCD_Data7 = dat & 0x04; //0000 0100
LCD_Data6 = dat & 0x02; //0000 0010
LCD_Data5 = dat & 0x01; //0000 0001
EN = 1; //打开使能
Delay10us();//10微秒延时
EN = 0; //关闭使能
}写一个字节命令
//写一个字节命令
void LCD1602_Write_Cmd(unsigned char Cmd) //写命令
{
DelayXms(1); //毫秒延时跳过忙检测
RS = 0; //发命令写 0
//写高4位
//Data_IO_Port = dat;//高4位
LCD_Data8 = Cmd & 0x80;// 1000 0000
LCD_Data7 = Cmd & 0x40;// 0100 0000
LCD_Data6 = Cmd & 0x20;// 0010 0000
LCD_Data5 = Cmd & 0x10;// 0001 0000
EN = 1; //打开使能
Delay10us();//10微秒延时
EN = 0; //关闭使能
//写低4位
//Data_IO_Port = dat <<4;//低4位
LCD_Data8 = Cmd & 0x08; //0000 1000
LCD_Data7 = Cmd & 0x04; //0000 0100
LCD_Data6 = Cmd & 0x02; //0000 0010
LCD_Data5 = Cmd & 0x01; //0000 0001
EN = 1; //打开使能
Delay10us();//10微秒延时
EN = 0; //关闭使能
}
屏幕初始化
//屏幕初始化
void LCD1602_LCDInit() //屏幕初始化
{
LCD1602_Write_Cmd(0x28); //4位接口,2行显示 5*8点阵
DelayXms(10); //毫秒延时
LCD1602_Write_Cmd(0x28); //4位接口,2行显示 5*8点阵
LCD1602_Write_Cmd(0x01); //清屏指令
LCD1602_Write_Cmd(0x06); //指针自增
LCD1602_Write_Cmd(0x0C); //显示开,光标关
}
显示位置
void LCD1602_Position_ShowString(bit x, unsigned char y)//显示字符串 //参数1:显示行位置(0和1)。参数2:显示列位置。
{
unsigned char position; //位置
if(x == 0)
{
position = 0x80 + y;//显示上行的位置
}
else
{
position = 0xC0 + y;//显示下行的位置
}
LCD1602_Write_Cmd(position); //写入位置
}
Delay 里面如下
#include "delay.h"
#include <intrins.h>//包含空语句
void Delay10us(void)//10微秒延时 //@11.0592MHz
{
unsigned char data i;
i = 2;
while (--i);
}
void Delay1ms() //1毫秒延时 //@11.0592MHz
{
unsigned char data i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void DelayXms(unsigned int xms) //1毫秒延时
{
unsigned chari;
for(i=xms;i>0;i--)
{
Delay1ms(); //@11.0592MHz
}
}
这样就写好了接下来调用就行
主函数
#include <reg52.h>
#include "lcd1602.h"
#include "delay.h"
/*
测试单片机型号STC89C51RC
晶振:外部晶振11.0592
*/
void main()
{
LCD1602_LCDInit(); //屏幕初始化
LCD1602_Position_ShowString(0,3);//参数1:显示行位置(0和1)。参数2:显示列位置
LCD1602_Write_Data('h'); //显示字符
while(1)
{
}
}
上附件
六年前写的4位并口1602程序供参考
#include <STC89C5xRC.H>
#define LCD1602_RS P22
#define LCD1602_EN P23
#define LCD1602_D4 P24
#define LCD1602_D5 P25
#define LCD1602_D6 P26
#define LCD1602_D7 P27
#define Command 0
#define Data 1
#define Clear_Display 0x01 //Clear_Display
#define Return_Home 0x02 //Return_Home
#define Entry_Mode_Cursor_Left 0x04 //Entry_Mode_Set
#define Entry_Mode_Entire_Right 0x05 //Entry_Mode_Set
#define Entry_Mode_Cursor_Right 0x06 //Entry_Mode_Set
#define Entry_Mode_Entire_Left 0x07 //Entry_Mode_Set
#define Display_Off 0x08 //Display_ON/OFF
#define Display_On 0x0c //Display_ON/OFF
#define Display_On_Cursor_Off_Blink_On 0x0d //Display_ON/OFF
#define Display_On_Cursor_On_Blink_Off 0x0e //Display_ON/OFF
#define Display_On_Cursor_On_Blink_On 0x0f //Display_ON/OFF
#define Cursor_Move_Left 0x10 //Cursor_or_Display_Shift
#define Cursor_Move_Right 0x14 //Cursor_or_Display_Shift
#define Display_Move_Left 0x18 //Cursor_or_Display_Shift
#define Display_Move_Right 0x1c //Cursor_or_Display_Shift
#define Setting_Basic_Instruction_Set 0x28 //Function_Set
#define Setting_Extended_Instruction_Set 0x29 //Function_Set
#define Function_Set 0x38 //Function_Set
#define Contrast_Set 0x78 //Contrast_Set
#define Internal_OSC 0x14 //Internal_OSC
#define Power_ICON_Contrast 0x5e //Power_ICON_Contrast
#define Follower_Control 0x6a //Follower_Control
#define Power_ICON_Contrast 0x5e //Power_ICON_Contrast
unsigned char code Display_Hex={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
unsigned char code Display_Data1=
{
"LCD_1602_Program" //0x80
"Conter:000000000" //0xc0
};
/*----------------------------延时10us@STC-Y1@11.0592MHz----------------------------*/
void Delay_10us(void)
{
unsigned char i;
i=2;
while(--i);
}
/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
while(x--)
Delay_10us();
}
/*----------------------------延时10ms@STC-Y1@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
unsigned char i,j;
i=18;
j=235;
do
{
while(--j);
}while(--i);
}
/*----------------------------延时x10ms----------------------------*/
void Delay_x10ms(unsigned char x)
{
while(x--)
Delay_10ms();
}
/*----------------------------LCD1602_Enable----------------------------*/
void LCD1602_Enable(void)
{
LCD1602_EN=1;
Delay_10us();
LCD1602_EN=0;
}
/*----------------------------写命令或数据,x=0传送命令,x=1传送数据----------------------------*/
void LCD1602_Write(unsigned char temp,bit x)
{
LCD1602_RS=x; //x=0传送命令,x=1传送数据
LCD1602_D4=temp&0x10;
LCD1602_D5=temp&0x20;
LCD1602_D6=temp&0x40;
LCD1602_D7=temp&0x80;
LCD1602_Enable();
LCD1602_D4=temp&0x01;
LCD1602_D5=temp&0x02;
LCD1602_D6=temp&0x04;
LCD1602_D7=temp&0x08;
LCD1602_Enable();
}
/*----------------------------整页显示字符----------------------------*/
void Display_Text(unsigned char code *addr)
{
unsigned char i;
LCD1602_Write(0x80,Command); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD1602_Write(*addr,Data);
addr++;
}
LCD1602_Write(0xc0,Command); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD1602_Write(*addr,Data);
addr++;
}
}
/*----------------------------指定位置显示字符----------------------------*/
void Display_Data(unsigned char x,unsigned char y,unsigned char temp)
{
switch(y)
{
case 0:
LCD1602_Write(0x80+x,Command); //设置DDRAM地址
Delay_10us();
LCD1602_Write(temp,Data);
break;
case 1:
LCD1602_Write(0xc0+x,Command); //设置DDRAM地址
Delay_10us();
LCD1602_Write(temp,Data);
break;
}
}
/*----------------------------初始化LCD1602----------------------------*/
void LCD12864_Init(void)
{
Delay_10ms();
Delay_10ms();
Delay_10ms();
Delay_10ms(); //延时40ms
// LCD1602_Write(Function_Set,Command); //Function_Set
// Delay_x10us(200); //延时2ms
// LCD1602_Write(Function_Set,Command); //Function_Set
// Delay_x10us(3); //延时3us
LCD1602_Write(Function_Set,Command); //Function_Set
Delay_x10us(3); //延时3us
LCD1602_Write(Setting_Basic_Instruction_Set,Command); //Setting_Basic_Instruction_Set
Delay_x10us(3); //延时3us
LCD1602_Enable();
LCD1602_Write(Setting_Extended_Instruction_Set,Command); //Setting_Extended_Instruction_Set
Delay_x10us(3); //延时3us
// LCD1602_Write(Cursor_Move_Right,Command); //Cursor_Move_Right
// Delay_x10us(3); //延时3us
// LCD1602_Write(Contrast_Set,Command); //Contrast_Set
// Delay_x10us(3); //延时3us
// LCD1602_Write(Internal_OSC,Command); //Internal_OSC
// Delay_x10us(3); //延时3us
// LCD1602_Write(Power_ICON_Contrast,Command); //Power_ICON_Contrast
// Delay_x10us(3); //延时3us
// LCD1602_Write(Follower_Control,Command); //Follower_Control
// Delay_x10ms(20); //延时200ms
LCD1602_Write(Display_On,Command); //Display_On
Delay_x10us(3); //延时3us
LCD1602_Write(Clear_Display,Command); //Clear_Display
Delay_x10us(200); //延时2ms
// LCD1602_Write(Entry_Mode_Cursor_Right,Command); //Entry_Mode_Cursor_Right
// Delay_x10us(3); //延时3us
}
void main(void)
{
unsigned int a=0,b=0;
LCD12864_Init();
while(1)
{
Display_Text(Display_Data1);
while(1)
{
Display_Data(7,1,Display_Hex);
Display_Data(8,1,Display_Hex);
Display_Data(9,1,Display_Hex);
Display_Data(10,1,Display_Hex);
Display_Data(11,1,Display_Hex);
Display_Data(12,1,Display_Hex);
Display_Data(13,1,Display_Hex);
Display_Data(14,1,Display_Hex);
Display_Data(15,1,Display_Hex);
Delay_x10ms(2);
b++;
if(b>=10000)
{
b=0;
a++;
}
}
}
}
SPI-DMA 刷 LCD12864 程序,整屏523us,AI8051U 驱动1.44寸黑白点阵屏,超高帧频 - LCD12864,LCD1602,DMA-M6800并口自动刷屏,CPU不等待,DMA-SPI刷屏 国芯人工智能技术交流网站 - AI32位8051交流社区
{:baoquan:} 学习了.
页:
[1]