免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2321 | 回复: 6
打印 上一主题 下一主题

另类C大家看看 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-28 14:22 |只看该作者 |倒序浏览
小弟最近写的一起和大家分享下...
还有就是代码优化前后的对比..
#include <reg51.h>     没有优化的程序...
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit P3_7=0xb0^7;
sbit P3_5=0xb0^5;
uchar idata Operand[1];
uchar i,Addr,Insbuf,Reccmd,Recaddr,cmd,ucmTime;
bit bCheckFlag,bStageFlag,TimeFlag,CmdFlag;



sfr WDTC=0x9f;                                        /*watchdog address*/
sfr SCONF=0xbf;
sbit Sda=P3^2;                                        /**EEPROMSDA*/
sbit Scl=P3^3;                                        /**EEPROMSCL*/
void mDelay(uchar j);
void Start(void);
void Stop(void);
void Ack(void);
void NoAck(void);
void Send(uchar Data);
uchar Read(void);
void WrToRom(uchar ucData[],uchar Address,uchar Num);
void RdFmRom(uchar ucData[],uchar Address,uchar Num);





void TimeDelay(void);
void WDT(void);





//=================================
//          主程序
//==================================
void main(void)
{  
      
   TMOD=0x21;  /*设T1定时器工作方式2*/
   TH1=0xfd;   /*波特率为9600,11.0592MHZ晶振*/
   TCON=0x40;   /*开启T1记时器*/
   SCON=0x50;   /*开启串行口方式1工作,允许接收,多机通讯方式*/
   IE=0x90;     /*开串行口中断*/
   PCON=0x00;
   P3_7=0;
   P1=0xff;
   TimeDelay();
   while(1)
  {  
     if(bCheckFlag==1) //群检位1的话执行
       {                 
        ucmTime=50;                //5ms
        TimeFlag=1;
        TimeDelay();      
        while(TimeFlag==1);         
        P3_7=1;
        SBUF=Insbuf;
        while(TI!=1);TI=0;
        P3_7=0;
        bCheckFlag=0;      
        }
               
    if(CmdFlag==1)     //写状态同时把状态存好
      {
       if (Recaddr==0)      
         {
           RdFmRom(Operand,100,1);
         if(Operand[0]!=0xff)         
           {
            Operand[0]=0xff;
            mDelay(10);
            WrToRom(Operand,100,1);            
            }
           CmdFlag=0;
         }
           
       if (Recaddr==1)      
         {
           RdFmRom(Operand,100,1);
         if(Operand[0]!=0xfc)         
           {
            Operand[0]=0xfc;
            mDelay(10);
            WrToRom(Operand,100,1);            
            }
           CmdFlag=0;
         }
       if (Recaddr==2)      
         {
           RdFmRom(Operand,100,1);
         if(Operand[0]!=0xfa)         
           {
            Operand[0]=0xfa;
            mDelay(10);
            WrToRom(Operand,100,1);            
            }
           CmdFlag=0;
         }
      
       }
      
      
        if(TimeFlag==0)          //喂狗程序20ms      
        { ucmTime=200;
          TimeFlag=1;                                                                                         
          WDT();
         }      
         
   }  
  
}
//===============================
//          串口中断
//===============================
  void ssio(void) interrupt 4 using 1
{
   RI=0;  /*接收位置0*/
   ES=0;  /*关串行中断*/
   Addr=P1;
   Addr=Addr>>4;
   //Addr=Addr&0x0f;
   Insbuf=SBUF;
   Reccmd=Insbuf&0xf0;
   Recaddr=Insbuf&0x0f;
     if (Reccmd==0xe0)
        {
       if(Recaddr==Addr)
               
          bCheckFlag=1;
        }
     if (Reccmd==0xf0)
        {
       if (Recaddr==Addr)
           bStageFlag=1;                  
        }
         
     if ((Reccmd==0xd0)&&(bStageFlag==1))
   {  
       if (Recaddr==0)
       {  
          P1=0xff;
          bStageFlag=0;
          CmdFlag=1;
        }            
       if (Recaddr==1)
        {
          P1=0xfc;                    
          bStageFlag=0;
          CmdFlag=1;                  
         }
       if (Recaddr==2)
        {
          P1=0xfa;              
          bStageFlag=0;
          CmdFlag=1;         
         }
    }
   
    ES=1;
}   

//========================================      
       void TimeDelay(void)


{      TR0=0;
       TMOD=TMOD|0x01;
       TH0=(65536-100)/256;
       TL0=(65536-100)%256;
       EA=1;
       ET0=1;
       TR0=1;
}      
         
void timer0(void)interrupt 1 using 2
{
        TH0=(65536-100)>>8;
        TL0=(65536-100)%256;      
        if (TimeFlag==1)   
       {
        ucmTime--;
        if(ucmTime==0){TimeFlag=0;}
       }
}

void WDT(void)
{P3_5=~P3_5;}   
//===========================
//         读写ROM
//=============================/
void mDelay(uchar j)
{
        uint i;
        for(;j>0;j--)
        {
                for(i=0;i<250;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 ucData[],uchar Address,uchar Num)
{
        uchar i;
        uchar *PData;
        PData=ucData;
        for(i=0;i<Num;i++)
        {
                Start();
                Send(0xa0);
                Ack();
                Send(Address+i);
                Ack();
                Send(*(PData+i));
                Ack();
                Stop();
                mDelay(1;                //050929g:30/060227G:16
        }
}

void RdFmRom(uchar ucData[],uchar Address,uchar Num)
{
        uchar i;
        uchar *PData;
        PData=ucData;
        for(i=0;i<Num;i++)
        {
                Start();
                Send(0xa0);
                Ack();
                Send(Address+i);
                Ack();
                Start();
                Send(0xa1);
                Ack();
                *(PData+i)=Read();
                Scl=0;
                NoAck();
                Stop();
        }
}

//======================================================
                            优化后的程序

#include <reg51.h>
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit P3_7=0xb0^7;
sbit P3_5=0xb0^5;
uchar idata Operand[1];
uchar i,Addr,Insbuf,Reccmd,Recaddr,cmd,ucmTime;
uchar CamCTR;
bit bCheckFlag,bStageFlag,TimeFlag,CmdFlag;



sfr WDTC=0x9f;                                        /*watchdog address*/
sfr SCONF=0xbf;
sbit Sda=P3^2;                                        /**EEPROMSDA*/
sbit Scl=P3^3;                                        /**EEPROMSCL*/
void mDelay(uchar j);
void Start(void);
void Stop(void);
void Ack(void);
void NoAck(void);
void Send(uchar Data);
uchar Read(void);
void WrToRom(uchar ucData[],uchar Address,uchar Num);
void RdFmRom(uchar ucData[],uchar Address,uchar Num);





void TimeDelay(void);
void WDT(void);





//=================================
//          主程序
//==================================
void main(void)
{  
        TMOD=0x21;  /*设T1定时器工作方式2*/
        TH1=0xfd;   /*波特率为9600,11.0592MHZ晶振*/
        TCON=0x40;   /*开启T1记时器*/
        SCON=0x50;   /*开启串行口方式1工作,允许接收,多机通讯方式*/
        IE=0x90;     /*开串行口中断*/
        PCON=0x00;
        P3_7=0;
        P1=0xff;       

        TimeDelay();       
        while(1)
        {  
                P1=CamCTR;
             if(bCheckFlag==1) //群检位1的话执行
                {                 
                ucmTime=50;                //5ms
                TimeFlag=1;
                TimeDelay();      
                while(TimeFlag==1);         
                P3_7=1;
                SBUF=Insbuf;
                while(TI!=1);TI=0;
                P3_7=0;
                bCheckFlag=0;      
                }
                RdFmRom(Operand,100,1);   
                   if(CamCTR!=Operand[0])
                   {
                           mDelay(5);
                           Operand[0]=CamCTR;
                WrToRom(Operand,100,1);
                }
                if(TimeFlag==0)          //喂狗程序20ms      
                {
                        ucmTime=200;
                        TimeFlag=1;                                                                                         
                        WDT();
        }      
   }                  //while(1)
}                   
               
   
//===============================
//          串口中断
//===============================
  void ssio(void) interrupt 4 using 1
{
   RI=0;  /*接收位置0*/
   ES=0;  /*关串行中断*/
   Addr=P1;
   Addr=Addr>>4;
   //Addr=Addr&0x0f;
   Insbuf=SBUF;
   Reccmd=Insbuf&0xf0;
   Recaddr=Insbuf&0x0f;
     if (Reccmd==0xe0)
     {
               if(Recaddr==Addr)
          bCheckFlag=1;
        }
    if (Reccmd==0xf0)
    {
                if(Recaddr==Addr)
          bStageFlag=1;                  
    }
        if ((Reccmd==0xd0)&&(bStageFlag==1))
   {  
       if (Recaddr==0){CamCTR=0xff;}                     
       if (Recaddr==1){CamCTR=0xfc;}
       if (Recaddr==2){CamCTR=0xfa;}
   
        bStageFlag=0;
    }
    ES=1;
}   

//========================================      
void TimeDelay(void)
{      TR0=0;
       TMOD=TMOD|0x01;
       TH0=(65536-100)/256;
       TL0=(65536-100)%256;
       EA=1;
       ET0=1;
       TR0=1;
}      
         
void timer0(void)interrupt 1 using 2
{
        TH0=(65536-100)/256;
        TL0=(65536-100)%256;      
        if (TimeFlag==1)   
       {
        ucmTime--;
        if(ucmTime==0){TimeFlag=0;}
       }
}

void WDT(void)
{P3_5=~P3_5;}   
//===========================
//         读写ROM
//=============================/
void mDelay(uchar j)
{
        uint i;
        for(;j>0;j--)
        {
                for(i=0;i<250;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 ucData[],uchar Address,uchar Num)
{
        uchar i;
        uchar *PData;
        PData=ucData;
        for(i=0;i<Num;i++)
        {
                Start();
                Send(0xa0);
                Ack();
                Send(Address+i);
                Ack();
                Send(*(PData+i));
                Ack();
                Stop();
                mDelay(1;                //050929g:30/060227G:16
        }
}

void RdFmRom(uchar ucData[],uchar Address,uchar Num)
{
        uchar i;
        uchar *PData;
        PData=ucData;
        for(i=0;i<Num;i++)
        {
                Start();
                Send(0xa0);
                Ack();
                Send(Address+i);
                Ack();
                Start();
                Send(0xa1);
                Ack();
                *(PData+i)=Read();
                Scl=0;
                NoAck();
                Stop();
        }
}

一开始心态有点急编的很乱有好多问题.
后来优化了下感觉清爽多了..

论坛徽章:
0
2 [报告]
发表于 2006-07-28 14:33 |只看该作者
原帖由 无聊的风 于 2006-7-28 14:22 发表
void ssio(void) interrupt 4 using 1
...


这种语法没见过,是哪个编译器支持的?

论坛徽章:
0
3 [报告]
发表于 2006-07-28 14:45 |只看该作者
原帖由 mik 于 2006-7-28 14:33 发表


这种语法没见过,是哪个编译器支持的?

KILL C51呵呵..是一个串行口中断入口

论坛徽章:
0
4 [报告]
发表于 2006-07-29 18:57 |只看该作者
原帖由 无聊的风 于 2006-7-28 14:45 发表

KILL C51呵呵..是一个串行口中断入口



是KEIL C把,哈哈! 8051的程序

论坛徽章:
0
5 [报告]
发表于 2006-07-29 19:42 |只看该作者
单片机 8051
c51
呵呵!
偶是搞硬件的!

论坛徽章:
0
6 [报告]
发表于 2006-07-30 10:24 |只看该作者
单片机的程序啊,呵呵

论坛徽章:
0
7 [报告]
发表于 2006-07-31 11:18 |只看该作者
原帖由 mik 于 2006-7-28 14:33 发表


这种语法没见过,是哪个编译器支持的?

handle interrupt 4, using register bank 1


51,上大学时搞过的东东。现在想想还是挺有意思的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP