微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 国旗升降

国旗升降

时间:10-02 整理:3721RD 点击:
                          /*******************************lcd1602.h 头文件*************************************/
sbit en=P2^6;
sbit rs=P2^4;
sbit 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<intrins.h>
sbit wp=P1^0;
sbit scl=P1^1;
sbit 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<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#include<i2c bus.h>
#include<lcd1602.h>          //1602头文件
sbit k1=P3^0;                   // 上升控制位
sbit k2=P3^1;                   //下降控制位
sbit k3=P3^2;                  // 调速位
sbit k4=P3^3;             //  自定义高度位
sbit mot=P1^4;                // 电机脉冲控制位
sbit dir=P1^5;                  //电机方向控制位
sbit 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 <reg52.h>
sbit 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<t;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;
}
}
}
}

哇,在这儿呀 哇,在这儿呀

不错么,小学曾经做过升旗手~~~~

明天给亲们上传完整资料哦

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top