📄 24c64带显示.c
字号:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define AddWr 0xa0 //器件地址选择及写标志
#define AddRd 0xa1 //器件地址选择及读标志
#define lcd_dport P3 //lcd_dport为数据输出口
/*****************************************************************************************************/
//注意:24C64和24C02的不同在于24C64要送两次地址,分别是高位地址和低位地址,24C02只要送一个,但是还有一个不同,
//可能在于在写数据的时候其写周期限制不同,不同厂家相同型号的存储器可能其写周期限制也不同,所以这个也可能要
//调整一下延时。
/***************************************************************************************************/
/*#define LINE1 0
#define LINE2 1
#define LINE1_HEAD 0x80
#define LINE2_HEAD 0xC0
#define LCD_DELAY_TIME 40
#define DATA_MODE 0x38
#define OPEN_SCREEN 0x0C
#define DISPLAY_ADDRESS 0x80
#define CLEARSCREEN LCD_en_command(0x01)
//common part
#define HIGH 1
#define LOW 0
#define TRUE 1
#define FALSE 0
#define ZERO 0
#define MSB 0x80
#define LSB 0x01*/
/*******************************************************************/
/*#define LCDIO P3
sbit LCD1602_RS=P1^0;
sbit LCD1602_RW=P1^1;
sbit LCD1602_EN=P1^2;*/
/*****************************************************************************************************/
/****************************************************************************************************/
/*有关全局变量*/
sbit Sda= P2^0; //串行数据
sbit Scl= P2^1; //串行时钟
sbit WP= P0^2; //硬件写保护
sbit rs=P1^0; //rs数据寄存器(1)与控制寄存器(0)的选择
sbit rw=P1^1; //rw为读(1)/写(0)的选择
sbit e=P1^2; //e 为使能信号,写时下降沿有效,读时高电平有效
sbit bf=P3^7; //bf为LCM忙标志信号,为1时忙,0时允许操作
void delayms(uchar j);
unsigned char code tab[]={'0','1','2','3','4','5','6','7','8','9'};
void mDelay(uchar j)
{
uint i;
for(;j>0;j--)
{
for(i=0;i<125;i--)
{;}
}
}
/*起始条件*/
void Start(void)
{
Sda=1;
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Sda=0;
_nop_();_nop_();_nop_();_nop_();
}
/*停止条件*/
void Stop(void)
{
Sda=0;
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Sda=1;
_nop_();_nop_();_nop_();_nop_();
}
/*应答位*/
void Ack(void)
{
Sda=0;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Scl=0;
}
/*反向应答位*/
void NoAck(void)
{
Sda=1;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Scl=0;
}
/*发送数据子程序,Data为要求发送的数据*/
void Send(uchar Data)
{
uchar BitCounter=8; //位数控制
uchar temp; //中间变量控制
do
{
temp=Data;
Scl=0;
_nop_();_nop_();_nop_();_nop_();
if((temp&0x80)==0x80) //如果最高位是1
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1; //RLC
Data=temp;
BitCounter--;
}while(BitCounter);
Scl=0;
}
/*读一个字节的数据,并返回该字节值*/
uchar Read(void)
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do{
Scl=0;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
if(Sda) //如果Sda=1
temp=temp|0x01; //temp的最低位置1
else
temp=temp&0xfe; //否则temp的最低位清0
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}while(BitCounter);
return(temp);
}
void WrToROM(uchar Data[],uchar AddressG,uchar AddressD,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start(); //发送启动信号
Send(0xa0); //发送SLA+W
Ack();
Send(AddressG); //发送高位地址
Ack();
Send(AddressD+i); //发送低位地址
Ack();
Send(*(PData+i));
Ack();
Stop();
mDelay(80);
}
}
void RdFromROM(uchar Data[],uchar AddressG,uchar AddressD,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(0xa0);
Ack();
Send(AddressG); //发送高位地址
Ack();
Send(AddressD+i); //发送低位地址
Ack();
Start();
Send(0xa1);
Ack();
*(PData+i)=Read();
Scl=0;
NoAck();
Stop();
}
}
/******************************************************************************************/
/******************************************************************************************/
/*void LCD_delay(void)
{
unsigned char i;
for(i=LCD_DELAY_TIME;i>ZERO;i--)//be sure lcd reset
;
} */
/********************************************************************/
/*void LCD_en_command(unsigned char command)
{
LCDIO=command;
LCD1602_RS=LOW;
LCD1602_RW=LOW;
LCD1602_EN=LOW;
LCD_delay();
LCD1602_EN=HIGH;
} */
/********************************************************************/
/*void LCD_en_dat(unsigned char dat)
{
LCDIO=dat;
LCD1602_RS=HIGH;
LCD1602_RW=LOW;
LCD1602_EN=LOW;
LCD_delay();
LCD1602_EN=HIGH;
} */
/********************************************************************/
/*void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == LINE1)
address = LINE1_HEAD + x;
else
address = LINE2_HEAD + x;
LCD_en_command(address);
} */
/********************************************************************/
/*void LCD_write_char( unsigned x,unsigned char y,unsigned char dat)
{
LCD_set_xy( x, y );
LCD_en_dat(dat);
} */
/********************************************************************/
/*void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
LCD_set_xy( X, Y ); //set address
while (*s) // write character
{
LCDIO=*s;
LCD_en_dat(*s);
s ++;
}
} */
/********************************************************************/
/*void LCD_init(void)
{
CLEARSCREEN;//clear screen
LCD_en_command(DATA_MODE);//set 8 bit data transmission mode
LCD_en_command(OPEN_SCREEN);//open display (enable lcd display)
LCD_en_command(DISPLAY_ADDRESS);//set lcd first display address
CLEARSCREEN;//clear screen
} */
/********************************************************************/
/*********************** OTHER PART *********************************/
/*void delay_nms(unsigned int n)
{
unsigned int i=0,j=0;
for (i=n;i>0;i--)
for (j=0;j<1140;j++);
} */
/**********************************************************************/
/**********************************************************************/
///////////////////////////////////////////////////////
//名称:LCM1602模块的应用
//功能:可直接写字符串(函数lcd_wstring)或写单个字符(函数lcd_wchar)
//完成于2007-7-22
/////////////////////////////////////////////////////////
void lcd_delay() //判断是否忙子函数,只有不忙时才退出此函数
{
//rs=0;
//rw=1;
//lcd_dport=0xff;
// _nop_();
//delayms(5);
//e=1;
//while(bf);
//e=0;
do
{
lcd_dport=0xff;
rs=0;
rw=1;
e=0;
_nop_();
e=1; // //高电平有效
}
while(bf==1);
}
void lcd_wc() //写命令(控制字)函数
{
rs=0;
rw=0;
e=1;// //下降沿有效
_nop_();
e=0;
lcd_delay(); //判忙不退出此函数
}
void lcd_wd() //写数据函数
{
rs=1;
rw=0;
e=1; //下降沿有效
_nop_();
e=0;
lcd_delay(); //判忙不退出此函数
}
void lcd_rst() //模块初使化函数
{
uchar i=3;
while(i) // 此处
{ // 为模
lcd_dport=0x30; // 块初使化
lcd_wc(); // 时的3次
delayms(5); // 写入
i--; // 16进制
} // 数0x30
lcd_delay();
lcd_dport=0x38; //
lcd_wc();
lcd_dport=0x06;
lcd_wc();
lcd_dport=0x0c;
lcd_wc();
}
////////////////////////////
//写字符串函数,string1,string2分别为要写入第一行和第二行的数据的指针
////////////////////////////
void lcd_wstring(uchar *string1,uchar *string2)
{
uchar i=0;
lcd_dport=0x80; //设置LCM中第一行首地址命令0x80(即首地址为00H)
lcd_wc();
while(*(string1+i)) //字符串的最后一个停止符为/0,十六进制数即为0,可用以判断
{
lcd_dport=*(string1+i);
lcd_wd();
i++;
}
i=0;
lcd_dport=0xc0; //设置LCM中第一行首地址命令0xc0(即首地址为40H)
lcd_wc();
while(*(string2+i))
{
lcd_dport=*(string2+i);
lcd_wd();
i++;
}
}
void delayms(uchar j) //廷时函数,j 为廷时的ms数
{
uchar i=0;
for(;j>0;j--)
{
for(i=0;i<124;i++);
}
}
//////////////////////////
//写字符函数,其中zifu,por分别为要写的字符和要写到LCM上的位置,
//要注意第一行的首地址por为0x80,第二行的首地址por为0xc0
//////////////////////////
void lcd_wchar(uchar zifu,uchar por)
{
lcd_delay();
lcd_dport=por; //写入要显示字符的地址
lcd_wc();
lcd_dport=zifu; //写入要显示字符的数据
lcd_wd();
}
void lcd_clearscreen(void)
{
lcd_dport=0x01;
rs=0;
rw=0;
e=0;
_nop_();
e=1;
}
///////////////////////////////////////////////////////////////////////////
/*void main()
{
uchar a[]="*&* !SHA!";
uchar b[]=" Go ahead";
lcd_rst();
lcd_wstring(a,b);
lcd_wchar('A',0xc5);
while(1);
}*/
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void main()
{ uint i;
uchar *joe1,Number[4]={1,2,3,4},joe[4],b[]=" ",addd=0xc5;
joe1=joe;
WP=0;
WrToROM(Number,0,25,4); //将初始化后的数值写入EEPROM
mDelay(20);
Number[0]=0;
Number[1]=0;
Number[2]=0;
Number[3]=0; //将数组中的值清掉,以验证读出的数是否正确
RdFromROM(Number,0,25,4);
for(i=0;i<4;i++) //LCD显示;
{joe[i]=tab[Number[i]] ;}
LCD_rst();
/*CLEARSCREEN;
delay_nms(2);
LCD_write_string(0,LINE1,joe1);
delay_nms(200); */
//lcd_wstring(joe,b);
lcd_clearscreen();
for(i=0;i<4;i++,addd++)
{
lcd_wchar(joe[i],addd);
}
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -