⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emodem.c

📁 嵌入式modem编程
💻 C
字号:
//////////////////////////////////////////////////////////////////
//初始化MODEM
void InitializeModem(void)
{
        register BYTE i;

        PtrRecv=0;PtrSend=0;
        CounterRecv=0;
        CounterRing=0;
        MainReadFlash(62,4,(BYTE*)&ProductNumber,(BYTE*)&PRODUCTNUMBER);
        if(ProductNumber==0xffffffff)ptrcom=0;
        c8255ctl=0x02;          //reset modem
        DelayMs(200);           //100ms
        c8255ctl=0x03;
        DelayMs(2500);          //2.5s

        i=0x83;
        asm{stb i,lcr;}         //dlab=1,8 bits length,1 stop bit
        DelayUs(1);
        dlm=0;
        DelayUs(1);
        if(SystemParameter.Baudrate==600)dll=0xc0;
        else if(SystemParameter.Baudrate==1200)dll=0x60;
        else if(SystemParameter.Baudrate==2400)dll=0x30;
        else if(SystemParameter.Baudrate==4800)dll=0x18;
        else dll=12;            //baudrate=9600
        DelayUs(1);
        lcr=0x03;               //dlab=0;
        DelayUs(1);
        mcr=0x0b;               //interrupt mode
        DelayUs(1);
        fcr=0;
        DelayUs(1);
        ier=0x03;               //R&T interrupt
        DelayMs(5000);          //5s
        SendAt((void*)&AtMode);
        DelayMs(100);
}


//MODEM(extint1)中断
#pragma interrupt(Extint1=29)
void Extint1(void)
{
        BYTE i=iir&0x0e;
        asm{ldb 0,lsr;}
        asm{ldb 0,msr;}

//send buffer empty
        if(i&0x02)
        {
                if((PtrSend!=0)&&(PtrSend<=((UWORD)SendBuffer[9]+11)))thr=SendBuffer[PtrSend++];
                else
                {
                        PtrSend=0;
                        mcr|=0x04;      //out1
                }
        }
//receive data available
        if(i&0x04)
        {
                i=rbr;
                if(PtrRecv>180)
                {
                        PtrRecv=0;
                        return;
                }
                RecvBuffer[PtrRecv++]=i;
                CounterRecv=2;
        }
}

//通讯地址校验
//return:TRUE---address valid
//       FALSE--address invalid
BYTE CheckAddress(void)
{
        BYTE i,temp;
        UDWORD addr;

        if(RecvBuffer[6]==0x99)
        {
                if((RecvBuffer[5]==0x99)&&(RecvBuffer[4]==0x99)&&(RecvBuffer[3]==0x99)&&(RecvBuffer[2]==0x99)&&(RecvBuffer[1]==0x99))return TRUE;
        }
        else if(RecvBuffer[6]==0xaa)
        {
                MainReadFlash(62,4,(BYTE*)&addr,(BYTE*)&PRODUCTNUMBER);
                for(i=1;i<6;i++)
                {
                        temp=addr%10;
                        addr/=10;
                        temp+=(addr%10)<<4;
                        addr/=10;
                        if(RecvBuffer[i]!=temp)return FALSE;
                }
                return TRUE;
        }
        return FALSE;
}

//MODEM处理程序
void ComModem(void)
{
        BYTE i,ccode,*ptr;
        UWORD rdata,temp;
        TIMERECORD *addr=(TIMERECORD*)&main_flash_memory;
//使用EMODEM时打开以下语句
/*        if(FlagModem==FALSE)return;
        if((ioport2&0x04)||                     //p2.2(extint)
           (lsr&0x02)||                         //overflow err
           (lsr&0x08)||                         //framing err
           CheckRing())                         //check ring overflow
        InitializeModem();
*/
        if((PtrRecv==0)||(CounterRecv!=0))return;
        PtrRecv=0;
        if(RecvBuffer[0]!=0x68)return;

        CounterRing=0;
        if(!CheckAddress())return;
        if(RecvBuffer[7]!=0x68)return;
        ccode=0;
        for(i=0;i<(RecvBuffer[9]+10);i++)ccode+=RecvBuffer[i];
        if(ccode!=RecvBuffer[RecvBuffer[9]+10])return;

        rdata=RecvBuffer[8];
//read data
//read follow data
        if((rdata==0x01)||
           (rdata==0x02))
        {
                temp=RecvBuffer[10]+(((UWORD)RecvBuffer[11])<<8);
                if(temp==0xed33)                //0xed=0xba+0x33;variable
                {
                        if((rdata==0x02)&&(ptrcom!=RecordNumber))ptrcom++;
                        if(ptrcom>7167)ptrcom=0;
                        if(ptrcom!=RecordNumber)
                        {
                                SendBuffer[8]=RecvBuffer[8]|0xa0;
                                SendBuffer[9]=0x82;
                                                //130;data length
                                addr+=ptrcom%128;
                                MainReadFlash(ptrcom/128,128,&SendBuffer[12],(BYTE*)addr);
                        }
                        else
                        {
                                SendBuffer[8]=RecvBuffer[8]|0x80;
                                                //control code
                                SendBuffer[9]=0x02;
                                                //data length
                        }
                        SendBuffer[10]=0;       //data id
                        SendBuffer[11]=0xba;
                        PrepareData();
                        SendData();
                }
                else if(temp==0xf933)           //0xf9=0xc6+0x33;parameter
                {
                        SendBuffer[8]=RecvBuffer[8]|0x80;
                                                //control code
                        SendBuffer[9]=92;       //data length
                        SendBuffer[10]=0;       //data id
                        SendBuffer[11]=0xc6;
                        MainReadFlash(60,44,&SendBuffer[12],(BYTE*)&FlashSystemParameter);
                        MainReadFlash(63,46,&SendBuffer[56],(BYTE*)&FlashReactiveParameter);
                        PrepareData();
                        SendData();
                }
        }
//repeat read data
        else if(rdata==0x03)
        {
                ccode=SendBuffer[8];
                SendBuffer[8]|=0x03;            //control code
                SendBuffer[SendBuffer[9]+10]+=SendBuffer[8]-ccode;
                                                //check code
                SendData();
        }
//write data
        else if(rdata==0x04)
        {
                rdata=RecvBuffer[10]+(((UWORD)RecvBuffer[11])<<8);
                if(rdata==0xf933)               //0xf9=0xc6+0x33;parameter
                {
                        for(i=12;i<102;i++)RecvBuffer[i]-=0x33;
                        MainEraseFlashSector(60);
                        while(!(i=MainFlashEraseTest(60)));
                        while(i==0xff);
                        MainWriteFlash(60,44,(BYTE*)&FlashSystemParameter,(BYTE*)&RecvBuffer[12]);
                        MainEraseFlashSector(63);
                        while(!(i=MainFlashEraseTest(63)));
                        while(i==0xff);
                        MainWriteFlash(63,46,(BYTE*)&FlashReactiveParameter,(BYTE*)&RecvBuffer[56]);
                        SendBuffer[8]=0x84;     //control code
                        SendBuffer[9]=0;        //data length
                        PrepareData();
                        SendData();
                }
        }
//check clock
        else if(rdata==0x08)
        {
                rtcctr1=0xd6;
                second=RecvBuffer[10]-0x33;
                minute=RecvBuffer[11]-0x33;
                hour=RecvBuffer[12]-0x33;
                day=RecvBuffer[13]-0x33;
                month=RecvBuffer[14]-0x33;
                year=RecvBuffer[15]-0x33;
                SECOND=GetUnixt();
                rtcctr1=0x56;
        }
//change baudrate
        else if(rdata==0x0c)
        {
        }

//read checkout data
        else if(rdata==0x81)
        {
                if(CounterCheck!=0)return;
                SendBuffer[8]=0x81;
                SendBuffer[9]=29;
                SendBuffer[10]=0;       //data id
                SendBuffer[11]=0xba;
                SendBuffer[12]=0x33;
                ptr=(BYTE*)&Effective.Ua;
                for(i=0;i<12;i++)
                {
                        SendBuffer[13+2*i]=*ptr++;
                        SendBuffer[14+2*i]=*ptr++;
                }
                SendBuffer[37]=(BYTE)Effective.Frequency;
                SendBuffer[38]=(BYTE)(Effective.Frequency>>8);
                PrepareData();
                SendData();
        }
//checkout meter
        else if(rdata==0x84)
        {
                if((CounterCheck!=0)||(RecvBuffer[12]!=(0x33+0x33)))return;
                for(i=0;i<13;i++)
                {
                        CheckData[i]=(WORD)(RecvBuffer[13+2*i]-0x33)+((WORD)(RecvBuffer[14+2*i]-0x33))<<8;
                        if((i<6)&&(CheckData[1]>0x5555))SystemParameter.Channel[i]=1024;
                }
                if(CheckData[6]<20)             //Pa
                {
                        SystemParameter.Channel[6]=0;
                        SystemParameter.Channel[8]=0;
                }
                else if(CheckData[7]<20)        //Qa
                {
                        SystemParameter.Channel[7]=0;
                        SystemParameter.Channel[9]=0;
                }
                if(CheckData[1]>0x5555)
                {
                        MainWriteFlash(60,44,(BYTE*)&FlashSystemParameter,(BYTE*)&SystemParameter);
                        CounterCheck=3;                 //3s
                }
        }

        else
        {
                PtrSend=0;
                PtrRecv=0;
        }
}

//振铃检测
BYTE CheckRing(void)
{
        if(msr&0x04)CounterRing++;
        if(CounterRing>3)return TRUE;
        else return FALSE;
}

void PrepareData(void)
{
        BYTE i,ccode;
        UDWORD addr;

        SendBuffer[0]=0x68;
        ccode=0x68;
        for(i=1;i<7;i++)
        {
                SendBuffer[i]=RecvBuffer[i];
                ccode+=RecvBuffer[i];
        }
        SendBuffer[7]=0x68;
        ccode+=0x68;
        ccode+=SendBuffer[8];
        ccode+=SendBuffer[9];
        for(i=10;i<(SendBuffer[9]+10);i++)
        {
                SendBuffer[i]+=0x33;
                ccode+=SendBuffer[i];
        }
        SendBuffer[i]=ccode;
        SendBuffer[i+1]=0x16;
}

void SendData(void)
{
        BYTE i;

        mcr&=0xfb;              //out1
        CounterSend=2;          //2s
        thr=SendBuffer[0];
        PtrSend=1;
}

void SendAt(BYTE str[])
{
        BYTE i=0;

        do
        {
                thr=str[i];
                DelayUs[1];
        }while(str[i++]!=0x0d);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -