本文主要是介绍STC15W408AS读FM24C64写内部IAP点阵显示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
#include <reg52.h> //上电后写字符表内容到内部EEPROM
#include <intrins.h> //从内部EEPROM取数据显示
#define uchar unsigned char
#define uint unsigned int
#define NOP _nop_()
uint Font_Counter; //文字总数
typedef uchar BYTE;
typedef uint WORD;
uchar kcounter,kstatus; //按键计数标志 按键状态标志
uint aa=0;
uint s,i,j,k; //移动汉字的总数。
uchar a_data,b_data,c_data; //
uint move,total,step; //location为0取文字右半部数据。
bit mflag; //位变量移动显示标志
sbit OE=P1^1; //74HC245 A1
sbit A1=P1^4; //74HC138A
sbit B1=P1^3; //74HC138B
sbit SRCK=P1^2; //11脚 移位时钟
sbit RCK=P3^7; //12脚 锁存时钟
sbit SER=P3^6; //14 脚数据输入
sbit key_in1=P3^2;
sbit key_in2=P3^3;
sbit SDA=P3^0; /****EEPROM数据****/
sbit SCL=P3^1; /****EEPROM脉冲****/
bdata char com_data; /****暂用 ****/
sbit mos_bit=com_data^7; /****高位****/
sbit low_bit=com_data^0; /****低位****/
/***********************************************/
#define URMD 2 //0:使用定时器 2 作为波特率发生器
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP 字节读命令
#define CMD_PROGRAM 2 //IAP 字节编程命令
#define CMD_ERASE 3 //IAP 扇区擦除命令
uint iap_eepromadd; //EEPROM编辑地址
uint IAP_ADD; //EEPROM地址
uchar RDEEPROM_ADD; //需增加文字总数读出后写IAP_TOTAL 0x0000
#define IAP_TOTAL 0x0000 //文字计数器 地址 第128个字节 EEPROM首地址
#define IAP_TOTAL 0x0000 //文字计数器 地址 第128个字节 EEPROM首地址
#define IAP_ADDA 0x0200 //EEPROM首地址 第一文字存储扇区
#define IAP_ADDB 0x0400 //EEPROM首地址 第二文字存储扇区
#define IAP_ADDC 0x0600 //EEPROM首地址 第三文字存储扇区
#define IAP_ADDD 0x0800 //EEPROM首地址 第四文字存储扇区
#define IAP_ADDE 0x0A00 //EEPROM首地址 第五文字存储扇区
#define IAP_ADDF 0x0C00 //EEPROM首地址 第六文字存储扇区
#define IAP_ADDG 0x0E00 //EEPROM首地址 第七文字存储扇区
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
uint ISPIAPADD;
/***********************************************/
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_();
_nop_();
_nop_();
_nop_();
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_();
_nop_();
_nop_();
_nop_();
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR=ENABLE_IAP; //使能IAP
IAP_CMD=CMD_PROGRAM; //设置IAP命令
IAP_ADDRL=addr; //设置IAP低地址
IAP_ADDRH=addr >> 8; //设置IAP高地址
IAP_DATA=dat; //写ISP/IAP/EEPROM数据
IAP_TRIG=0x5a; //写触发命令(0x5a)
IAP_TRIG=0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_();
_nop_();
_nop_();
_nop_();
IapIdle();
}
/*---扇区擦除---------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR=ENABLE_IAP; //使能IAP val=IapReadByte(IAP_ADDRESS+1);
IAP_CMD=CMD_ERASE; //设置IAP命令
IAP_ADDRL=addr; //设置IAP低地址
IAP_ADDRH=addr>>8; //设置IAP高地址
IAP_TRIG=0x5a; //写触发命令(0x5a)
IAP_TRIG=0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_(); //等待ISP/IAP/EEPROM操作完成
_nop_();
_nop_();
_nop_();
_nop_();
IapIdle();
}
/**************************************/
void start()
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;
}
/***************************************/
void stop()
{
SDA=0;
SCL=1;
SDA=1;
}
/***************************************/
void ack()
{
SCL=1;
SCL=0;
}
/***************************************/
void shift8(char a)
{
data uchar i;
com_data=a;
for(i=0;i<8;i++)
{
SDA=mos_bit;
SCL=1;
SCL=0;
com_data=com_data*2;
}
}
/***************************************/
uchar rd_24C64(uint a)
{
uint addh,addl;
data uint i,command;
addl=a;
addh=a>>8;
SDA=1;
SCL=0;
start();
command=160;
shift8(command); /*****写入160*****/
ack();
shift8(addh); /*****写高八位地址addh 高三位无效*****/
ack();
shift8(addl); /*****写入低八位地址 addl*****/
ack();
start();
command=161;
shift8(command); /*****写入161*****/
ack();
SDA=1;
for(i=0;i<8;i++)
{
com_data=com_data*2;
SCL=1;
low_bit=SDA;
SCL=0;
}
stop();
return(com_data);
}
/**************数据串行输出到74HC595***********************/
void serial_input(uchar dat)
{
uint m;
for(m=0;m<8;m++)
{
if(dat&0x80)
SER=1;
else
SER=0;
SRCK=0;
SRCK=1; //数据移入移位寄存器
NOP;
NOP;
SRCK=0;
NOP;
NOP;
dat=dat<<1;
}
}
/*************并出****************************************/
void serial_output()
{
RCK=1; //上升沿移位寄存器数据存入8为锁存器
NOP;
NOP;
RCK=0;
}
/*************行显控制**********************************/
void HC138_scan(uchar temp)
{
OE=1;
A1=0x01&temp;
B1=0x01&(temp>>1);
}
/**************数据移位合并**************/
void Data_Move()
{
a_data<<=1; //左部数据先移动一步
c_data=a_data; //缓冲显示数据等于左移一位后的左部数据
b_data<<=1; //右部数据也移动一步
if(CY==1) //如果右部数据移动后进位标志为1
c_data|=0X01; //缓冲显示数据等于最低位和1相与
else //否则进位标志为0
c_data|=0X00; //缓冲显示数据等于最低位和0相与
a_data=c_data;
}
/**************移动第0--7步数据处理函数**********************/
/*i=0显示屏左部移出第一个字左部数据,移入第一个字右部数据****/
/*i=1显示屏右部移出第一个字右部数据,移入第二个字的左部数据**/
void handledata1(uint total,uint i,uint j,uint k,uchar step) //移动汉字的总数。
{ //i==0写入左半部数据
uchar tmove;
if(i==0)//i=0 上一行 i=0下一行
{ //
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32); //第一个字的左部数据起始为字符表24
b_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32+1); //第一个字的右部数据起始为字符表25
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32); //第一个字的左部数据起始为字符表16
b_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32+1); //第一个字的右部数据起始为字符表17
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32); //第一个字的左部数据起始为字符表8
b_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32+1); //第一个字的右部数据起始为字符表9
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32); //第一个字的左部数据起始为字符表0
b_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32+1);//第一个字的右部数据起始为字符表1
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
}
if(i==1) //i=0 上一行 i=0下一行
{
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32); //第一个字的右部数据起始为字符表25
b_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+j+total+1)*32); //第二个字的左部起始为第二个字的0
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32); //第一个字的右部起始为起始为17
b_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+j+total+1)*32); //第二个字的左部起始为第二个字的16
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32); //第一个字的右部起始为起始为9
b_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+j+total+1)*32); //第二个字的左部起始为第二个字的8
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32);//第一个字的右部起始为1
b_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+j+total+1)*32);//第二个字的左部起始为第二个字的0
for(tmove=0;tmove<step;tmove++)
{
Data_Move();
}
serial_input(~c_data);
}
}
/***移动第8--15步数据处理函数**********************/
/*i=0显示屏左部移出第一个字的右部数据,移入第二个字的左部数据*****/
/*i=1显示屏左部移出第一个字的右部数据,移入第二个字的左部数据*****/
void handledata2(uint total,uint i,uint j,uint k,uchar step) //移动汉字的总数。)
{
uchar tmove;
if(i==0)//i=0 上一行 i=0下一行
{ //(i+1)
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为25 J=0X*32 j*32
b_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的24
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+total+j)*32+1); //第一个字的右部数据起始为17
b_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+total+j+1)*32); //第二个字的左部数据起始为第二个字的16
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为9
b_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的8
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为1
b_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的0
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
}
if(i==1) //i=0 上一行 i=0下一行
{
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+j+total+1)*32); //第二个字的左部数据
b_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+j+total+1)*32);//第二个字的左部数据
b_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+j+total+1)*32); //第二个字的左部数据
b_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
c_data=0X00;
a_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+j+total+1)*32);//第二个字的左部数据
b_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
for(tmove=0;tmove<step-7;tmove++)
{
Data_Move();
}
serial_input(~c_data);
}
}
/*************数据处理函数**********************/
/***外部传递一个移动步数参数,内部设定共需移动汉
字总数,判断运算汉字的左右部标识函数需修改***/
void disdata(uchar step)
{
uchar FontCode;
if(step==0) //移动步数等于0
{ //读当前汉字计数值文字。
for(k=0;k<4;k++) //4行同时扫描,共扫4次4X4=16
{
for(s=0;s<2;s++) //左右两个屏
{
for(j=0;j<2;j++) //变量j=0或=1为两个字的其中一个
{
for(i=0;i<2;i++) //一个字的两行 i=0起始(24,25).(16,17)以此类推
{ //j+total显示汉字的位置加当前汉字计数器地址
FontCode=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+j+total)*32);
serial_input(~FontCode);//第一个起始为24 J=0X*32 j*32
FontCode=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+j+total)*32);
serial_input(~FontCode);//第一个起始为16
FontCode=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+j+total)*32);
serial_input(~FontCode);//第一个起始为8
FontCode=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+j+total)*32);
serial_input(~FontCode);//第一个起始为0
}
}
}
serial_output(); // 左右两个屏同时扫描两行,4X2=8行一个区
HC138_scan(k);
}
} //L483--L500开机显示第一个和第二个文字正确2015 7 23
else if(step>0&step<9) //移动1-7步处理函数
{
for(k=0;k<4;k++) //4行同时扫描,共扫4次4X4=16
{
for(s=0;s<2;s++) //左右两个屏
{
for(j=0;j<2;j++) //两个字的其中一个
{
for(i=0;i<2;i++) //一个字的两排 i=0为一个字的左半部i=1为一个字的右半部
{ //j+total显示汉字的位置加当前汉字计数器地址
handledata1(total,i,j,k,step); //左半部数据处理显示函数
}
}
}
serial_output(); //output
HC138_scan(k);
}
}
else if(step>7&step<16) //移动7-15步处理函数
{
for(k=0;k<4;k++) //4行同时扫描,共扫4次4X4=16
{
for(s=0;s<2;s++) //左右两个屏
{
for(j=0;j<2;j++) //两个字的其中一个
{
for(i=0;i<2;i++) //一个字的两排 i=0为一个字的左半部i=1为一个字的右半部
{ //j+total显示汉字的位置加当前汉字计数器地址
handledata2(total,i,j,k,step);
}
}
}
serial_output();
HC138_scan(k);
}
}
}
/***定时器计数到检测刷新标志mflag对数据刷新一次***/
void display1()
{
if(mflag==1) //如果移动显示标志为1。
{ //
mflag=0; //移动标志复位归0,等待下次定时器中断激发。
move++; //移动步数加1。
if(move>=16) //如果移动步数大于等于16。
{ //
move=0; //步数计数器归0。
total++; //文字计数器加1
if(total>Font_Counter+3) //移动文字计数值大于Font_Counter+3 总数之后为空代码
total=0; //归0
} //每移动8位文字左右部标识取反一次
} //1取文字左半部数据 0取右半部
disdata(move); //处理并显示数据
}
/*-------定时器中断子程序--中断aa次刷新一次显示-------------*/
void exint0() interrupt 1 //INT0中断入口
{
aa=aa+1;
TH0=0X53;
TL0=0X32;
if(aa==6)
{
mflag=1;
aa=0;
}
}
/*------------延时子程序---------------------*/
void delay(uint t)
{
uint i;
for(i=0;i<t;i++)
{}
}
/**************Delay_50ms***************************/
void Delay_50ms(uint ms) //
{
uint m;
for(;ms>0;ms--)
for(m=62450;m>0;m--);
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
delay(10); //延时
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
delay(10); //延时
}
/****************读外部FM24C64到IAP中******************/
/*************开始和结束写4个字各32字节空代码**********/
void Write_Code()
{
uchar F_Counter;
uchar Data_Code;
uchar m;
IapEraseSector(IAP_ADDA);
IapEraseSector(IAP_ADDB);
IapEraseSector(IAP_ADDC);
IapEraseSector(IAP_ADDD);
IapEraseSector(IAP_ADDE);
IapEraseSector(IAP_ADDF);
IapEraseSector(IAP_ADDG);
Font_Counter=rd_24C64(3840); //文字总数等于读EEPROM
//写4个空字符
///
/*******第一扇区*********/
for(F_Counter=0;F_Counter<4;F_Counter++) //4个字,写第一扇区(包括空代码)
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDA+F_Counter*32+m,0X00); //内部存储单元
}
}
//如果总数大于12 读12个字写到IAP_ADDA
///
if(Font_Counter>12)
{
for(F_Counter=0;F_Counter<12;F_Counter++) //12个字,写第一扇区(包括空代码)
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64(F_Counter*32+m); //外部EEPROM从第一个地址开始读
IapProgramByte(IAP_ADDA+(F_Counter+4)*32+m,Data_Code);
}
}
}
//如果总数小于等于12个字写总数个数到IAP_ADDA
///
else if(Font_Counter<=12) //例总数10
{
for(F_Counter=0;F_Counter<Font_Counter;F_Counter++) //总数个字,写第一扇区(包括空代码)
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64(F_Counter*32+m); //外部EEPROM从第一个地址开始读
IapProgramByte(IAP_ADDA+(F_Counter+4)*32+m,Data_Code); //加四个字空代码地址
}
}
//文字总数小于12 12-总数 列 总数8 12-8=4个空代码 //
for(F_Counter=0;F_Counter<(12-Font_Counter);F_Counter++) //12个字,写第一扇区(包括空代码)
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDA+(Font_Counter+4)*32+m,0X00); //总数8+4=12 字节开始写空代码
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //16个字下一扇区空代码
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDB+F_Counter*32+m,0X00);
}
}
return;
}
//A扇区小于12个字结束
//如果总数大于28 读16个字写到IAP_ADDB
//总数大于28个字 写B扇区16个字
/**************第二扇区*************/
if(Font_Counter>28) //12第一扇区 16第二扇区
{
for(F_Counter=0;F_Counter<16;F_Counter++) //32个字,写第二扇区(包括空代码)
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+12)*32+m); //外部EEPROM 从第十二个地址开始读
IapProgramByte(IAP_ADDB+F_Counter*32+m,Data_Code);
}
}
}
//如果总数小于等于28个字写总数个数减上一扇区12个字到IAP_ADDB
///
else if(Font_Counter<=28) //例Font_Counter-12=26-12=14
{
for(F_Counter=0;F_Counter<Font_Counter-12;F_Counter++)//总数减第一扇区12字开始
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+12)*32+m); //外部EEPROM从第12个地址开始读
IapProgramByte(IAP_ADDB+F_Counter*32+m,Data_Code); //4空代码 12有效文字
}
}
//文字总数小于28 28-总数 例 总数26 28-26=IAP_ADDB余2个空代码
for(F_Counter=0;F_Counter<(28-Font_Counter);F_Counter++)//28-总数 例 总数26 28-26=2个空代码
{
for(m=0;m<32;m++) //例26-12=14 从14个字地址开始写两个空代码
{ //例Font_Counter-12=26-12=14,本扇区已写入14个字代码空间剩余2个字代码空间
IapProgramByte(IAP_ADDB+(Font_Counter-12+F_Counter)*32+m,0X00); //总数减12后加变量
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDC+F_Counter*32+m,0X00);
}
}
return;
}
//B扇区小于28个字结束 A扇区12加B扇区16
//如果总数大于44 读16个字写到IAP_ADDC
/*******第三扇区******/
//总数大于44个字 写C扇区16个字
if(Font_Counter>44) //12第一扇区 16第二扇区 16第三扇区
{
for(F_Counter=0;F_Counter<16;F_Counter++) //32个字,写第二扇区(包括空代码)
{
for(m=0;m<32;m++)
{ //第一扇区12个字第二扇区16个字 第28个字位置开始
Data_Code=rd_24C64((F_Counter+28)*32+m); //外部EEPROM 从第28个地址开始读
IapProgramByte(IAP_ADDC+F_Counter*32+m,Data_Code);
}
}
}
else if(Font_Counter<=44) //总数不够写满第三扇区
{ //例总数40个字 40-28=12 写12个字
for(F_Counter=0;F_Counter<Font_Counter-28;F_Counter++)//第一扇区12个字第二扇区16个字 第28个字位置开始
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+28)*32+m); //外部EEPROM从第28个地址开始读第一12个字第二扇区16个字
IapProgramByte(IAP_ADDC+F_Counter*32+m,Data_Code); //4空代码 12有效文字
}
}
//文字总数小于44 44-总数 例 总数40 44-40=IAP_ADDC余4个空代码 //第三扇区剩余空间
for(F_Counter=0;F_Counter<(44-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字
{
for(m=0;m<32;m++) //例44-40==4 从40个字地址开始写4个空代码
{
IapProgramByte(IAP_ADDC+(Font_Counter-28+F_Counter)*32+m,0X00); //总数减28后加变量
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDD+F_Counter*32+m,0X00);
}
}
return;
}
//C扇区小于44个字结束 A扇区12加B扇区16 加C扇区16
//如果总数大于60 读16个字写到IAP_ADDD
/*******第四扇区*******/
if(Font_Counter>60) //12第一扇区 16第二扇区 16第三扇区 16第四扇区
{
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{ //
Data_Code=rd_24C64((F_Counter+44)*32+m); //外部EEPROM 从第44个地址开始读
IapProgramByte(IAP_ADDD+F_Counter*32+m,Data_Code); //第四扇区首地址
}
}
}
else if(Font_Counter<=60) //总数不够写满第四扇区
{
for(F_Counter=0;F_Counter<Font_Counter-44;F_Counter++)//总数减44 范围60-44=16
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+44)*32+m); //外部EEPROM从第44个地址开始读12+16+16
IapProgramByte(IAP_ADDD+F_Counter*32+m,Data_Code); //4空代码 12有效文字
}
}
//文字总数小于60 60-总数 例 总数50 60-50=IAP_ADDD余10个空代码 //第四扇区剩余空间
for(F_Counter=0;F_Counter<(60-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字
{
for(m=0;m<32;m++) //例44-40==4 从40个字地址开始写4个空代码
{
IapProgramByte(IAP_ADDD+(Font_Counter-44+F_Counter)*32+m,0X00); //总数减44后加变量
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDE+F_Counter*32+m,0X00);
}
}
return;
}
//C扇区小于60个字结束 A扇区12+B扇区16+C扇区16+D扇区16
//如果总数大于76 读16个字写到IAP_ADDE
/******第五扇区******/
if(Font_Counter>76) //12第一扇区 16第二扇区 16第三扇区 16第四扇区 16第五扇区
{
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{ //
Data_Code=rd_24C64((F_Counter+60)*32+m); //外部EEPROM 从第60个地址开始读
IapProgramByte(IAP_ADDE+F_Counter*32+m,Data_Code); //第四扇区首地址
}
}
}
else if(Font_Counter<=76) //总数不够写满第四扇区
{
for(F_Counter=0;F_Counter<Font_Counter-60;F_Counter++)//总数减44 范围76-60=16
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+60)*32+m); //外部EEPROM从第60个地址开始读12+16+16+16
IapProgramByte(IAP_ADDE+F_Counter*32+m,Data_Code); //4空代码 12有效文字
}
}
//文字总数小于76 76-总数
for(F_Counter=0;F_Counter<(76-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字
{
for(m=0;m<32;m++) //例44-40==4 从40个字地址开始写4个空代码
{
IapProgramByte(IAP_ADDE+(Font_Counter-60+F_Counter)*32+m,0X00); //总数减44后加变量
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDF+F_Counter*32+m,0X00);
}
}
return;
}
//E扇区小于76个字结束 A扇区12+B扇区16+C扇区16+D扇区16+E扇区16
//如果总数大于92 读16个字写到IAP_ADDF
/******第六扇区******/
if(Font_Counter>92) //12第一扇区 16第二扇区 16第三扇区 16第四扇区 16第五扇区
{
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{ //
Data_Code=rd_24C64((F_Counter+76)*32+m); //外部EEPROM 从第60个地址开始读
IapProgramByte(IAP_ADDF+F_Counter*32+m,Data_Code); //第四扇区首地址
}
}
}
else if(Font_Counter<=76) //总数不够写满第四扇区
{
for(F_Counter=0;F_Counter<Font_Counter-76;F_Counter++)//总数减44 范围76-60=16
{
for(m=0;m<32;m++)
{
Data_Code=rd_24C64((F_Counter+76)*32+m); //外部EEPROM从第60个地址开始读12+16+16+16
IapProgramByte(IAP_ADDF+F_Counter*32+m,Data_Code); //4空代码 12有效文字
}
}
//文字总数小于92 92-总数
for(F_Counter=0;F_Counter<(92-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字
{
for(m=0;m<32;m++) //例44-40==4 从40个字地址开始写4个空代码
{
IapProgramByte(IAP_ADDF+(Font_Counter-76+F_Counter)*32+m,0X00); //总数减44后加变量
}
}
//字节内容后一扇区空代码
for(F_Counter=0;F_Counter<16;F_Counter++) //
{
for(m=0;m<32;m++)
{
IapProgramByte(IAP_ADDG+F_Counter*32+m,0X00);
}
}
return;
}
}
/***主程序运行启动定时器,首先清屏,定时器定时到刷新显示******/
/***运行到最后一个文字连续写入0X00使发光管熄灭****************/
void main()
{
AUXR=0X80; //STC系列的1T 设置
TMOD=0X01;
TH0=0X53;
TL0=0X32;
EA=1;
ET0=1;
TR0=1;
total=0; //移动汉字总数计数器归0.
Write_Code();
Delay_50ms(50);
while(1) //
{
display1(); //开始移动显示
}
} //L818 CODE5373 2019 7 9 10:20
这篇关于STC15W408AS读FM24C64写内部IAP点阵显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!