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

📄 dtmf.c

📁 16为单片机实现调制解调器功能
💻 C
📖 第 1 页 / 共 2 页
字号:
            if(g_chHandShakeTail > 2)
            {//已经收到了 三个码
                if((g_chHandShakeBuf[0] == '#') && (g_chHandShakeBuf[1] == '1') && (g_chHandShakeBuf[2] == '#'))
                {//握手成功
                    g_chBuildDTMFReBuildCount = 0;//
                    g_intMark &= ~RS232PhysicsReceiveWorkToPCBuf_Mark;//保证RS232 不在接收,
                    g_intMark |= ICanPush_Mark;//主动发信息
                    g_chMainPushReport_Stat = 0;//从 0 开始运行----强调!
                    g_intMark |= RS232DTMFSendPC_Mark;//使用DTMF通信----可能会无条件抢用 RS232资源
                    g_intMark |= CommBuilded_Mark;//通信建立
                    //清 发送缓冲区------------------------------可能会无条件抢用 RS232资源
                    g_chSendPCHead = 0;
                    g_chSendPCTail = 0;
                    g_chSendPCBuf_Stat = 1;
                    //主动发码
                    g_chBuildDTMF_Stat = 18;
                }
                else
                {//握手失败
                    g_chBuildDTMF_Stat = 19;//挂机处理
                    //可能是 PARAM 错误!要转到。。。下
                    g_chBuildDTMFReBuildCount++;
                    if(g_chBuildDTMFReBuildCount > BuildDTMFReBuildCount_MAX)
                    {
                        g_chBuildDTMFReBuildCount = 0;
                        if(g_intMark & CommDebugUart_Mark)
                        {
                            //调试!
                        }
                        else
                        {
                            //无条件去试用 RS232
                            g_intMark &= ~RS232DTMFSendPC_Mark;//切换到 RS232 方式下
                            g_chBuildDTMF_Stat = 19;//挂机处理
                            {
                                unsigned char chM[] = "切换到 RS232 方式\n\r";  
                                ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
                            }
                        }
                    }
                    else
                    {
                        unsigned char chM[] = "握手信息错误\n\r";   
                        ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
                    }
                }
            }
            //15 秒 挂机,
            if(g_chBuildDTMFTime_1s > BuildDTMFTime_1sShakeHandMAX)
            {
                g_chBuildDTMF_Stat = 19;//挂机处理
                //DEBUG --无握手
                {
                    unsigned char chM[] = "无握手挂16\n\r"; 
                    ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
                }
            }
        break;
        case 17://
            //是否接收完成,有尾巴既完成
            //g_intMark |= DTMFPhysicsReceiveWorkToPCBuf_Mark;//可以收 DTMF 码
            g_intMark |= DtmfPhysicsReceive_Mark;//可以接受码了
            //5 秒 挂机,
            
            if(g_chBuildDTMFTime_1s > BuildDTMFTime_1sRecerivMAX)
            {
                g_chBuildDTMF_Stat = 19;
                {
                    unsigned char chM[] = "收超时挂17\n\r"; 
                    ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
                }
            }
        break;
        case 18://主动发码
            g_intMark |= ICanPush_Mark;//主动发信息
            g_intMark &= ~DtmfPhysicsReceive_Mark;//不可以接受码了
            //无信息要发,也发 单 * 后 挂机
            if(g_intMark & ReportPC_Mark)
            {
                //在自动发
            }
            else
            {//没有信息要主动发了
                //等待发 单 码
                if(g_chSendDtmf == 0xFF)
                {
                    g_chSendDtmf = '*';
                    g_chBuildDTMF_Stat = 20;//等待 1--2 秒,保证 发送完成
                    g_chBuildDTMFTime_1s = 0;
                }
            }
            //5 秒 挂机,按流程肯定有发送,这里还没有发码肯定有问题,
            if(g_chSendPCBuf_Stat == 1)
            {//在等待发送
                //5 秒 挂机,
                if(g_chBuildDTMFTime_1s > BuildDTMFTime_1sRecerivMAX)
                {
                    g_chBuildDTMF_Stat = 19;
                    {
                        unsigned char chM[] = "发超时挂18\n\r"; 
                        ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
                    }
                }
            }
        break;
        case 19://挂机
            g_intMark &= ~CommBuilded_Mark;//通信断开
            g_chBuildDTMF_Stat = 1;
            g_chBuildDTMFTime_1s = 0;
            //DEBUG --挂
            {
                unsigned char chM[] = "挂19\n\r";   
                ExternInsertDebugSendBuf((unsigned char *)chM,sizeof(chM) - 1);
            }
        break;
        case 20://等待 1--2 秒,保证 发送完成
            if(g_chBuildDTMFTime_1s > 1)
            {
                g_chBuildDTMF_Stat = 19;
            }
        break;
        default://
            g_chBuildDTMF_Stat = 1;
            g_chBuildDTMFTime_1s = 0;
        break;  
    }
}
/**************************************
*功能: DTMF 物理层接收   
*参数: DtmfPhysicsReceive_Mark 
*返回: 接收缓冲区处理
*备注: 实时调用
**************************************/
void DtmfPhysicsReceive(void)
{
    //收
    if((g_intMark & DtmfPhysicsReceive_Mark) && (g_chSendDtmf == 0xFF))//完全由 外界 控制
    {//握手以后 = 1,接收完全 = 0,发送完全 = 1------这样收发码肯定不会冲突!
        unsigned char chDtmf;
        P5OUT |= DTM1;//收码
        if(g_chDtmfPhysicsReceive_50ms > 2)
        {
            g_chDtmfPhysicsReceive_50ms = 3;
            //不亮
            P2OUT |= Receive_LED;
        }
        //亮
        P2OUT &= ~CommBuild_LED;//正在收码,灯一定要亮
        chDtmf = Get_DTMF();
        if(chDtmf < 16)
        {//可能 还要有变换---变为 ASC 码
            g_chBuildDTMFTime_1s = 0;
            g_chDtmfPhysicsReceive_50ms = 0;
            //亮
            P2OUT &= ~Receive_LED;
            //该 计时器是来检查DTMF 不活动的时间
            if(chDtmf == 10)
            {
                chDtmf = 48;//'0'
            }
            else if(chDtmf == 0)
                {
                    chDtmf = 68;//'D';
                }
                else if(chDtmf == 11)
                    {
                        chDtmf = 42;//'*';
                    }
                    else if(chDtmf == 12)
                        {
                            chDtmf = 35;//'#';
                        }
                        else if(chDtmf > 12)//A-C A= 65    13+ 52=65  C= 15 15+52=67
                            {
                                chDtmf += 52;
                            }
                            else//1--9
                            {
                                chDtmf += 48;
                            }
            //这里收到 一个码,马上打印
            ExternInsertDebugSendBuf(&chDtmf,1);//给 变量的地址
            if(g_chBuildDTMF_Stat == 3)
            {//被动握手,等待 #
                if(g_chHandShakeTail < 3)
                {
                    g_chHandShakeBuf[g_chHandShakeTail] = chDtmf;// 如果第一个 码不是 #,则握手失败
                    g_chHandShakeTail++;
                }
            }
            else if(g_chBuildDTMF_Stat == 16)
                {//主动握手,等待 #1#
                    if(g_chHandShakeTail < 3)
                    {
                        g_chHandShakeBuf[g_chHandShakeTail] = chDtmf;// 如果第一个 码不是 #,则握手失败
                    }
                    g_chHandShakeTail++;
                }
                else
                {
                    if(g_chReceivePCTail == 0)
                    {
                        if(chDtmf == '#')
                        {
                            g_intMark |= DTMFPhysicsReceiveWorkToPCBuf_Mark;
                        }
                    }
                    if(g_intMark & DTMFPhysicsReceiveWorkToPCBuf_Mark)
                    {//缓冲区是单向数组
                        g_chReceivePCTail++;
                        g_chReceivePCTail %= ReceivePcBufMAX;//保证可以收到尾巴
                        g_chReceivePCBuf[g_chReceivePCTail] = chDtmf;
                    }
                }
        }
    }
}
/**************************************
*功能: DTMF 物理层发送   
*参数: g_chSendDtmf 
*返回: 
*备注: 每 50 ms 被调用一次
**************************************/
void DtmfPhysicsSend(void)
{
    switch(g_chDtmfPhysicsSendMark)
    {
        case 1://无事--检查 是否 有 东西要 发
            if(g_chSendDtmf != 0xFF)
            {
                g_chDtmfPhysicsSendMark = 2;
            }
        break;
        case 2://开 TONE OUT
            //亮
            P2OUT &= ~Send_LED;
            P5OUT &= ~DTM1;
            //这里发送 一个码,马上打印
            ExternInsertDebugSendBuf(&g_chSendDtmf,1);//给 变量的地址
            write_CR(1);      //置位CRA 的TOUT:允许DTMF输出
            {//写数据
                if(g_chSendDtmf == '0')
                {
                    g_chSendDtmf = 10;
                }
                else if(g_chSendDtmf == 'D')
                    {
                        g_chSendDtmf = 0;//'D';
                    }
                    else if(g_chSendDtmf == '*')
                        {
                            g_chSendDtmf = 11;//'*';
                        }
                        else if(g_chSendDtmf == '#')
                            {
                                g_chSendDtmf = 12;//'#';
                            }
                            else if(g_chSendDtmf > 64)//A-C A= 65    13+ 52=65
                                {
                                    g_chSendDtmf -= 52;
                                }
                                else//1--9
                                {
                                    g_chSendDtmf -= 48;
                                }
                Write_DTMF(g_chSendDtmf);//写数据  chSendPCBuf_Hard[chSendPCHead_Hard];
            }
            ////开 TONE OUT
            g_chDtmfPhysicsSendMark = 3;
        break;
        case 3://停一次
            g_chDtmfPhysicsSendMark = 4;
        break;
        case 4://关 TONE OUT
            //关 TONE OUT
            write_CR(0);
            g_chDtmfPhysicsSendMark = 5;
        break;
        case 5://停一次
            //不亮
            P2OUT |= Send_LED;
            P5OUT |= DTM1;
            g_chDtmfPhysicsSendMark = 1;
            //不加的话,肯定会收到自己发的码,加上后,无该事情发生!
            read_SR();//读状态寄存器(清除状态寄存器),以清除接收端可能在状态寄存器中产生的置位
            //这时 肯定收到了码 * !
            g_chSendDtmf = 0xFF;//表明发送完成,还会等待 50 ms 再发下一个
        break;
        default:
            g_chDtmfPhysicsSendMark = 1;
        break;
    }   
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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