主要代码:
//增减图像时,需要修改 switch_show()和 H对应参数
//所用单片机:STC15W408S 内部Rc 11.0592MHz
#include <STC15.H>
#include <intrins.h>
#define POSITIVE 0
#define OPPOSE 1
//sbit P32 = P3^2; //I/O口P3.2 在STC12C56.H已经定义
unsigned char code hao_hao_xue_xi[]={0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,
0x10,0x14,0xF0,0x63,0x80,0x00,0x82,0x00,
0x82,0x40,0x82,0x80,0xE2,0x7F,0x92,0x00,
0x8A,0x00,0xC6,0x00,0x80,0x00,0x00,0x00,
0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,
0x10,0x14,0xF0,0x63,0x80,0x00,0x82,0x00,
0x82,0x40,0x82,0x80,0xE2,0x7F,0x92,0x00,
0x8A,0x00,0xC6,0x00,0x80,0x00,0x00,0x00,
0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,
0x90,0x04,0x90,0x44,0x91,0x84,0x96,0x7E,
0x90,0x06,0x90,0x05,0x98,0x04,0x14,0x04,
0x13,0x04,0x50,0x06,0x30,0x04,0x00,0x00,
0x04,0x00,0x04,0x00,0x04,0x08,0x04,0x18,
0x14,0x04,0x24,0x04,0xC4,0x02,0x04,0x02,
0x04,0x01,0x04,0x21,0x84,0x40,0x04,0x80,
0x04,0x40,0xFE,0x3F,0x04,0x00,0x00,0x00
} ;
unsigned char code tian_tian_xiang_shang[]={0x40,0x80,0x42,0x80,0x42,0x40,0x42,0x20,
0x42,0x10,0x42,0x0C,0x42,0x03,0xFE,0x00,
0x42,0x03,0x42,0x0C,0x42,0x10,0x42,0x20,
0x43,0x40,0x62,0xC0,0x40,0x40,0x00,0x00,
0x40,0x80,0x42,0x80,0x42,0x40,0x42,0x20,
0x42,0x10,0x42,0x0C,0x42,0x03,0xFE,0x00,
0x42,0x03,0x42,0x0C,0x42,0x10,0x42,0x20,
0x43,0x40,0x62,0xC0,0x40,0x40,0x00,0x00,
0x00,0x00,0xF8,0xFF,0x08,0x00,0x08,0x00,
0xCC,0x1F,0x4A,0x08,0x49,0x08,0x48,0x08,
0x48,0x08,0x48,0x08,0xE8,0x1F,0x48,0x40,
0x08,0x80,0xFC,0x7F,0x08,0x00,0x00,0x00,
0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,
0x00,0x40,0x00,0x40,0x00,0x40,0xFF,0x7F,
0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x40,
0x20,0x40,0x00,0x60,0x00,0x40,0x00,0x00
};
。。。。。
。。。。。
unsigned char V; //用于eeprom的记录与读取
unsigned char H; //确定图像数量
void long_delay(unsigned char k);
void short_delay(void);
void show_one(unsigned char *tab,unsigned char k,unsigned char nub);
void switch_show(unsigned char a,unsigned char k);
void cc(unsigned int addr);
void xcx(unsigned int addr,unsigned char dat);
unsigned char dcx(unsigned int addr);
void Q0(void);
void long_delay(unsigned char k)
{
unsigned char i,j;
for(;k>0;k--)
for(i=0;i<50;i++)
for(j=0;j<10;j++);
}
void short_delay()
{
unsigned char i,j;
for(i=0;i<6;i++)
for(j=0;j<25;j++)
;
}
void show_one(unsigned char *tab,unsigned char k,unsigned char nub) //显示一幅画 ,一个字符串
{
int i,n=nub*32-1;
if(k==1) //顺次显示
{
for(i=0;i<n;i++)
{
P1=~tab[i]; short_delay();
P1=0xff;
i++;
P2=~tab[i]; short_delay();
P2=0xff;
long_delay(1);
}
}
else //逆次显示
{
for(i=n;i>0;i--)
{
P2=~tab[i]; short_delay();
P2=0xff;
i--;
P1=~tab[i]; short_delay();
P1=0xff ;
long_delay(1);
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:擦除某一扇区(每个扇区512字节)
入口:addr = 某一扇区首地址
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void cc(unsigned int addr)
{
// 0x83(晶振<12M) 0x82(晶振<20M) 0x81(晶振<24M) 0x80(晶振<30M)
IAP_CONTR = 0x83; // 打开 IAP 功能(ISPEN(ISP_CONTR.7)=1:允许编程改变Flash, 设置 Flash 操作等待时间。
IAP_CMD = 0x03; // 用户可以对"Data Flash/EEPROM区"进行扇区擦除
IAP_ADDRL = addr; // ISP/IAP操作时的地址寄存器低八位,
IAP_ADDRH = addr>>8; // ISP/IAP操作时的地址寄存器高八位。
//EA =0;
IAP_TRIG = 0x5a; // 在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入46h,
IAP_TRIG = 0xa5; // 再写入B9h,ISP/IAP命令才会生效。
_nop_();
Q0(); // 关闭ISP/IAP
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:写一字节
入口:addr = 扇区单元地址 , dat = 待写入数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void xcx(unsigned int addr,unsigned char dat)
{
IAP_CONTR = 0x83;
IAP_CMD = 0x02; // 用户可以对"Data Flash/EEPROM区"进行字节编程
IAP_ADDRL = addr;
IAP_ADDRH = addr>>8;
IAP_DATA = dat; // 数据进ISP_DATA
EA = 0;
IAP_TRIG = 0x5a;
IAP_TRIG = 0xa5;
_nop_();
Q0(); // 关闭ISP/IAP
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:读一字节
入口:addr = 扇区单元地址
出口:dat = 读出的数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
unsigned char dcx(unsigned int addr)
{
unsigned char dat;
IAP_CONTR = 0x83;
IAP_CMD = 0x01; // 用户可以对"Data Flash/EEPROM区"进行字节读
IAP_ADDRL = addr;
IAP_ADDRH = addr>>8;
EA = 0;
IAP_TRIG = 0x5a;
IAP_TRIG = 0xa5;
_nop_();
dat = IAP_DATA; // 取出数据
Q0(); // 关闭ISP/IAP
return dat;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:关闭ISP/IAP操作
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Q0()
{
IAP_CONTR = 0; // 关闭IAP功能
IAP_CMD = 0; // 待机模式,无ISP操作
IAP_TRIG = 0; // 关闭IAP功能, 清与ISP有关的特殊功能寄存器
// IAP_ADDRH = 0x80; //将地址设置到非IAP
// IAP_ADDRL = 0;
}
void eeprom()
{
/*用于测试eeprOM
unsigned char kk;
cc(0x0200); // 擦除第2个扇区(0200h~03FFh)
xcx(0x0200,7);
kk= dcx(0x0200);
if(kk==7)
P37=0;
*/
unsigned char a;
// a= PCON;
// a&=0xdf;
// PCON=a; //由于PCON的初始值为默认LVDF为1,所以必须软件清除
// short_delay();
// a= PCON;
// a&=0x20; //判断电压是否过低
a=0;
if(a==0)
{
V = dcx(0x0000); // 开机读取EEPROM区0000h数据
cc(0x0000); // 擦除第1个扇区(0000h~01FFh)
if(V<H) //不同的一次显示图像个数
{
V++;
xcx(0x0000,V); // 对EEPROM区0000h写入V的值
}
else
{
V=1; //少了这一句,折腾了老半天
xcx(0x0000,V); // 对EEPROM区0000h写入1
}
}
else
{
P37=0;
V=3;
}
}
//不能将button_down与button_up 通过P32=state(一个变量)的形式进行合成一个函数
//因为P32只能写成P32==0或者P32==1,不能与变量进行比较
unsigned char button_down(unsigned char n)
{
while(P32==0){
n--;
short_delay();
if(n==0) return 1;
}
return 0;
}
unsigned char button_up(unsigned char n)
{
while(P32==1){
n--;
short_delay();
if(n==0) return 1;
}
return 0;
}
void main(void)
{
unsigned char k=0;
H=6; //图像数量,即字符串数量
// P3M0=0x04; //P32设置为高阻,其他端口不变
// P3M1=0x00;
long_delay(100); //防止上电时对eeproM操作不稳定
eeprom();
while(1)
{
if(button_up(5)==1&&k==1){
long_delay(85);
switch_show(V,OPPOSE) ;
k=0;
}
if(button_down(5)==1&&k==0){
long_delay(85);
switch_show(V,POSITIVE) ;
k=1;
}
// if(button_down(3)==1) {
// P1=0xff;
// k=0;
// long_delay(100);
// }
// else P1=0xfe;
}
}