/*******************************lcd1602.h 头文件*************************************/
***it en=P2^6;
***it rs=P2^4;
***it rw=P2^5;
uchar code table1[]="nationalflag R&L";
uchar code table2[]=" H:00cmV:1.1cm/s";
void delay1(uint z) //毫秒级延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
uchar nSwap(uchar *com) //调整1602与P0高低位对应的函数
{
uchar i,nNum[8];
for(i=0;i<8;i++)
{
nNum[i]=(*com)%2;
*com/=2;
}
*com=0;
for(i=0;i<8;i++)
*com=2*(*com)+nNum[i];
}
void write_com(uchar com) //1602 写命令
{
rs=0;
rw=0;
nSwap(&com);
P0=com;
delay1(2);
en=1;
delay1(2);
en=0;
}
void write_data(uchar date) //1602 写数据
{
rs=1;
rw=0;
nSwap(&date);
P0=date;
delay1(2);
en=1;
delay1(2);
en=0;
}
void init_lcd() //1602 初始化
{
uchar num;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<16;num++)
{
write_data(table1[num]);
delay1(2);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(table2[num]);
delay1(2);
}
}
/**********************************i2c bus.h 头文件**********************************/
#include
***it wp=P1^0;
***it scl=P1^1;
***it sda=P1^2;
void delay2() //微妙级延时
{
uint i;
for(i=0;i<6;i++)_nop_();
}
void init_i2c()
{
wp=0;
sda=1;
delay2();
scl=1;
delay2();
}
void start() //开始信号
{
sda=1;
delay2();
scl=1;
delay2();
sda=0;
delay2();
}
void response() //应答信号
{
sda=1;
delay2();
scl=1;
delay2();
scl=0;
delay2();
}
void stop() //停止信号
{
sda=0;
delay2();
scl=1;
delay2();
sda=1;
delay2();
}
void write_byte(uchar date) //写字节
{
uchar i,temp;
temp=date;
wp=0;
scl=0;
delay2();
for(i=0;i<8;i++)
{
if(temp&0x80)
sda=1;
else
sda=0;
delay2();
scl=1;
delay2();
scl=0;
delay2();
temp=temp<<1;
}
scl=0;
delay2();
sda=1;
delay2();
}
uchar read_byte() //读字节
{
uchar i,k;
sda=1;
for(i=0;i<8;i++)
{
scl=1;
delay2();
k=k<<1;
if(sda)
k=k|0x01;
else
k=k&0xfe;
scl=0;
delay2();
}
return k;
}
void write_add(uchar address,uchar date) //写数据
{
wp=0;
start();
write_byte(0xae);
response();
write_byte(address);
response();
write_byte(date);
response();
stop();
}
uchar read_add(uchar address) //读数据
{
uchar date;
start();
write_byte(0xae);
response();
write_byte(address);
response();
start();
write_byte(0xaf);
response();
date=read_byte();
stop();
return date;
}
/*********************************************/
// "nationalflag R&L" //
// //
// 国旗升降仪.C 文件 //
// "H:00cmV:1.1cm/s" //
// //
/*******************************************/
#include
#define uint unsigned int
#define uchar unsigned char
#include
#include //1602头文件
***it k1=P3^0; // 上升控制位
***it k2=P3^1; //下降控制位
***it k3=P3^2; // 调速位
***it k4=P3^3; // 自定义高度位
***it mot=P1^4; // 电机脉冲控制位
***it dir=P1^5; //电机方向控制位
***it beep=P2^7; // 蜂鸣器控制位
uchar flagk1,flagk2,flag;// 国旗各个状态标志位
uchar cm,high1,high2,v; //定义变量,脉冲个数cm,上升下降高度hingh1,自定义高度high2,速度v
uchar speed;
void delay(uint x)//延时函数
{
uint i,j;
for(i=x;i>0;i--)
for(j=120;j>0;j--);
}
void display2(uchar com,uchar date) //1602 液晶第二行显示函数1,显示上升标志+,下降标志—
{
write_com(0x80+0x40+com);
write_data(date);
}
void display3(uchar com,uchar date) //1602 液晶第二行显示函数2 ,显示国旗高度
{
write_com(0x80+0x40+com);
write_data(0x30+date);
}
void G_init() // 全局变量初始化
{ mot=1;
speed=0;//初始速度为1.1cm/s
flag=0; //
TMOD=0x01; //定时器T0方式1
TH0=(65536-10750)/256;
TL0=(65536-10750)%256;
EA=1;
ET0=1;
high1=read_add(8);//上电读取EEROM存储的值
_nop_();
_nop_();
_nop_();
_nop_();
}
void keyscan() //键盘扫描函数
{
uchar raise;
if(high1!=0)
flagk2=1;
if(flagk1==0)
{
if(k1==0)//上升按键有效
{
delay(10);
if(k1==0)
{
flag=0;
beep=0; //上升时开启国歌
TR0=1; //上升时电机启动
flagk1=1; //上升时关闭上升标志
flagk2=1; //上升时打开下降标志
dir=1;
raise=0x2b;
display2(0,raise);//上升时液晶显示+
}
}
while(!k1);
}
if(flagk2==1)
{
if(k2==0) //下降按键有效
{
delay(10);
if(k2==0)
{
flag=0;
flagk1=0; //下降时打开上升标志
flagk2=0; //下降时关闭下降标志
beep=1; //下降时关闭国歌
TR0=1; //下降时电机启动
dir=0;
raise=0x2d;
display2(0,raise) ; //下降时液晶显示—
}
}
while(!k2);
}
if(k3==0) //调速按键有效
{
delay(10);
if(k3==0)
{
speed++;
switch(speed)
{
case 0:v=11;display3(9,v/10);
display3(11,v%10);break;
case 1:v=22;display3(9,v/10);
display3(11,v%10);break;
case 2:v=44;display3(9,v/10);
display3(11,v%10);break;
case 3:v=88;display3(9,v/10);
display3(11,v%10);break;
case 4:speed=0;v=11;display3(9,v/10);
display3(11,v%10);break;
}
while(!k3);
}
}
if(k4==0)//自定义高度按键有效
{
delay(10);
if(k4==0)
{
flag=1;
high2=high2+12;
if(high2==48)
high2=0;
}
while(!k4);
}
if(dir==1) // 电机正传,即上升时
{
if((high1==48)||((high2==high1)&&high2!=0))//上升时当上升到48cm或者上升到自定义高度时停止上升
{
raise=0x20;
display2(0,raise);
high2=0;
TR0=0;
beep=1;
flagk1=1;
flagk2=1;
}
}
if(dir==0) //电机反转,即下降时
{
if((high1==0)||((high2==high1)&&high2!=0)) //下降时当下降到0cm或者下降到自定义高度时停止下降
{
TR0=0;
raise=0x20;
display2(0,raise);
high2=0;
dir=1;
flagk1=0;
flagk2=0;
}
}
}
void main() //主函数
{
init_lcd();
init_i2c;
G_init();
while(1)
{
keyscan();
if(flag==0)//当在上升或者下降时
{
display3(3,high1/10); //高度送液晶显示
display3(4,high1%10); //高度送液晶显示
}
else//当在自定义高度时
{
display3(3,high2/10); //高度送液晶显示
display3(4,high2%10); //高度送液晶显示
}
}
}
void timer0() interrupt 1
{
switch(speed) //通过改变定时器初值进行调速
{
case 0:TH0=(65536-10750)/256;TL0=(65536-10750)%256;break;
case 1:TH0=(65536-5375)/256;TL0=(65536-5375)%256;break;
case 2:TH0=(65536-2688)/256;TL0=(65536-2688)%256;break;
case 3:TH0=(65536-1344)/256;TL0=(65536-1344)%256;break;
}
mot=~mot;
cm++;
if(cm==42) //进入42次中断,即发了42个脉冲,显示高度就加1厘米
{
cm=0;
if(dir==1) //上升时
{
high1=high1+1;
write_add(8,high1); //送E2PROM 芯片保存
}
else//下降时
{
high1=high1-1;
write_add(8,high1);
}
}
}
/****************************义勇军进行曲C 源代码 *******************************/
#include
***it beep=P1^1; //蜂鸣器发声
unsigned char tl0,th0; //定时器赋值
unsigned int code FreqTab[]={ //简谱对应的简谱码
65535,
64260,64400,64524,64579,64685,64778,64860,
64898,64968,65030,65057,65110,65157,65198,
65217,65252,65283,65297,65323,65346,65367,
};
unsigned char code yyjjxq[]={ //曲谱贮存格式:音高,音长,音高,音长
8,0x08,0,0x04,5,0x04,
8,0x0c,8,0x04,
8,0x06,8,0x02,5,0x04,6,0x02,7,0x02,
8,0x08,8,0x08,
0,0x04,10,0x04,8,0x04,9,0x02,10,0x02,
12,0x08,12,0x08,
10,0x06,10,0x02,8,0x06,10,0x02,
12,0x06,10,0x02,9,0x08,
9,0x10,
13,0x08,12,0x08,
9,0x08,10,0x08,
12,0x04,10,0x04,0,0x04,12,0x04,
10,0x04,9,0x02,10,0x02,8,0x08,
10,0x08,0,0x08,
5,0x06,6,0x04,8,0x04,8,0x04,
10,0x06,10,0x02,12,0x04,12,0x04,
9,0x04,9,0x02,9,0x02,6,0x08,
9,0x0c,5,0x04,
8,0x0c,8,0x04,
10,0x0c,10,0x04,
12,0x10,
8,0x06,10,0x02,12,0x04,12,0x04,
13,0x08,12,0x08,
10,0x06,8,0x02,12,0x08,
10,0x04,0,0x04,8,0x04,0,0x04,
5,0x08,8,0x08,
10,0x06,8,0x02,12,0x08,
10,0x04,0,0x04,8,0x04,0,0x04,
5,0x08,8,0x08,
5,0x08,8,0x08,
5,0x08,8,0x08,
8,0x08,0,0x08,
0xff,0xff, //结束符0xff;休止符0x00
};
void delay(unsigned char t) //1/8 拍延时函数
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1
for(t2=0;t2<1800;t2++);
TR0=0;
}
void delayms(unsigned int x) //毫秒级延时
{
unsigned int a,b;
for(a=x;a>0;a--)
for(b=124;b>0;b--);
}
void timer0() interrupt 1
{
TR0=0;
beep=~beep;
TL0=tl0;
TH0=th0;
TR0=1;
}
void main()
{
unsigned char k;
TMOD=0x01; //定时器0 工作16 位计数方式
ET0=1; //允许定时器0 溢出中断;
EA=1; //开总中断
while(1)
{
if( yyjjxq[k]==0xff)
{
beep=1;
TR0=0;
delayms(500); //唱完后延时
delayms(500);
delayms(500);
//k=0; //可多次播放
}
else
{
if( yyjjxq[k]==0x00)
{
TR0=0;
delay(yyjjxq[k+1]);
k+=2;
}
else
{
th0=FreqTab[ yyjjxq[k]]/256;
tl0=FreqTab[ yyjjxq[k]]%256;
TR0=1;
delay(yyjjxq[k+1]);
k+=2;
}
}
}
}
|