找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4468|回復(fù): 25
打印 上一主題 下一主題
收起左側(cè)

同時(shí)使用單片機(jī)外部中斷0,1與定時(shí)器中斷0,1的程序問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:89072 發(fā)表于 2021-12-7 10:05 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
在調(diào)試485控制時(shí),用到了外部中斷0和外部中斷1,使用的別人的Modbus RTU程序,自己又需要使用紅外設(shè)置,作為按鍵使用,由于基礎(chǔ)不好,現(xiàn)在卡在兩個(gè)定時(shí)器同時(shí)使用時(shí),無法Modbus通訊,設(shè)置了外部中斷1優(yōu)先級為0,當(dāng)設(shè)置定時(shí)器1的工作模式2時(shí)
單片機(jī)源程序如下:
void timer_init(void)//定時(shí)器初始化
{

//    IPH |= 0x01;
//    PT1=1;
//IP = 0x08;
//IPH = 0x08;
        TMOD =0x30;/////////設(shè)置工作方式2
        TH1=0x00; //重載值
        TL1=0x00; //初始化值
        EA=1;        
        ET1=1;//開總中斷;開定時(shí)器中斷
        TR1=1;////////啟動(dòng)計(jì)數(shù)器
}

TMOD=0x20時(shí),Modbus RTU就無法使用,很郁悶,請大神幫我分析下怎樣設(shè)置,非常感謝。

void TimesMsinitInt(void)
{
    unsigned long tmp = 0;

    TMOD &= ~GATE0;//0000 0000
    TMOD &= ~C_T0;//0000 0000
    TMOD |= T0_M1;//0000 0001                        //模式1,16位

    //$$$. 定時(shí)器初值計(jì)算
    //tmp=(0xffff-TimeVals*(1000.0/(FOSC/12000)));        //時(shí)間計(jì)算公式
    //.................................................................
    tmp = 65536UL - FOSC / 12000000.0 * TimeVals;
    TIMER_HIGHT = (uchar)(tmp >> 8);                //初值計(jì)算
    TIMER_LOW = (uchar)(tmp & 0xff);
    //
    TH0 = TIMER_HIGHT;                                                //加載初值
    TL0 = TIMER_LOW;



    //$$$. 允許中斷,開啟定時(shí)器
    //.................................................................
    TR0 = 1;                                                                //打開定時(shí)器
    ET0 = 1;                                                                //允許定時(shí)器中斷
}

//這是Modbus的定時(shí)器設(shè)置
//T1 相關(guān)的位定義
#define         GATE1        0x80
#define         C_T1        0x40
#define         T1_M2        0x20
#define         T1_M1        0x10
//T0 相關(guān)的位定義
#define         GATE0        0x08
#define         C_T0        0x04
#define         T0_M2        0x02
#define         T0_M1        0x01

這是T1與T0的定義

Modbus.rar

10.25 KB, 下載次數(shù): 9

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:57657 發(fā)表于 2021-12-7 10:59 | 只看該作者
你用了外部中斷0、1,EX0=1; 和 EX1=1;  以及中斷入口哪里去了?
回復(fù)

使用道具 舉報(bào)

板凳
ID:89072 發(fā)表于 2021-12-7 11:11 | 只看該作者
npn 發(fā)表于 2021-12-7 10:59
你用了外部中斷0、1,EX0=1; 和 EX1=1;  以及中斷入口哪里去了?

/*************************************
                01 (0x01)        讀線圈
        02 (0x02)        讀離散量輸入
        03 (0x03)        讀保持寄存器
        04(0x04)         讀輸入寄存器
        05 (0x05)        寫單個(gè)線圈
        06 (0x06)        寫單個(gè)寄存器
        15 (0x0F)        寫多個(gè)線圈
        16 (0x10)        寫多個(gè)寄存器
*************************************/
#define _MAIN_C_
//============================
#include "includeFile.h"
//============================
#include "Delay.h"
sfr P4   = 0xC0; //8 bitPort4

bit irpro_ok,irok;
sbit IR=P3^3;  //紅外接口標(biāo)志
uint count;  
uchar  irtime;
//u8  numa = 234;
sbit LED = P4^4;

uchar IRcord[6];
uchar irdata[33];
uchar code TabA[22]="0123456789ABCDEFGHIJKL";
uchar data TimeNum[]="                      ";

/*------------------------------------------------
                  定時(shí)器1中斷處理
void tm1_isr() interrupt 1
------------------------------------------------*/
void tim1_isr()interrupt 3  //定時(shí)中斷
{
        irtime++;

}
/*------------------------------------------------
                  外部中斷0中斷處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 2  //外部中斷1服務(wù)函數(shù)
{
  static unsigned char   i;             //接收紅外信號處理
  static bit startflag;                //是否開始處理標(biāo)志位
if(startflag)                        
   {

   if(irtime<63&&irtime>=33)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms
            i=0;
                    irdata=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1
                    irtime=0;
                    i++;
                            if(i==33)
                              {
                                   irok=1;
                                 i=0;
                                  }
          }
           else
                {
                irtime=0;
                startflag=1;

                }

}

/*------------------------------------------------
                定時(shí)器0初始化
------------------------------------------------*/
void timer_init(void)//定時(shí)器初始化
{

//    IPH |= 0x01;
//    PT1=1;
//IP = 0x08;
//IPH = 0x08;
        TMOD =0x30;/////////設(shè)置工作方式2
        TH1=0x00; //重載值
        TL1=0x00; //初始化值
        EA=1;       
        ET1=1;//開總中斷;開定時(shí)器中斷
        TR1=1;////////啟動(dòng)計(jì)數(shù)器
}

/*------------------------------------------------
                  外部中斷1初始化
------------------------------------------------*/
void EX0init(void)
{
//IPH = 0x00;
//PX1 = 1;
IPH = 0x04;
IP = 0x00;
        IT1 = 1;   //指定外部中斷1下降沿觸發(fā),INT0 (P3.3)
        EX1 = 1;   //使能外部中斷
        EA = 1;    //開總中斷


}

/*------------------------------------------------
                  鍵值處理
注:分解顯示轉(zhuǎn)換值列表

------------------------------------------------*/
void Ir_work(void)//紅外鍵值散轉(zhuǎn)程序
{
        TimeNum[5] = TabA[IRcord[0]/16];   //處理客戶碼并顯示
        TimeNum[6] = TabA[IRcord[0]%16];
        TimeNum[8] = TabA[IRcord[1]/16];   //處理客戶碼并顯示
        TimeNum[9] = TabA[IRcord[1]%16];
        TimeNum[11] = TabA[IRcord[2]/16];  //處理數(shù)據(jù)碼并顯示
        TimeNum[12] = TabA[IRcord[2]%16];
        TimeNum[14] = TabA[IRcord[3]/16];  //處理數(shù)據(jù)反碼并顯示
        TimeNum[15] = TabA[IRcord[3]%16];
        TimeNum[17] = TabA[IRcord[4]/16];  //處理數(shù)據(jù)反碼并顯示
        TimeNum[18] = TabA[IRcord[4]%16];
        TimeNum[20] = TabA[IRcord[5]/16];  //處理數(shù)據(jù)反碼并顯示
        TimeNum[21] = TabA[IRcord[5]%16];
        irpro_ok=0;//處理完成標(biāo)志
  }

/***************************************************************/
void Ir_towork(void)//紅外鍵值散轉(zhuǎn)程序
{

//            PutStr(1,0,TimeNum);//顯示處理過后的碼值
           switch(IRcord[2])//判斷第三個(gè)數(shù)碼值
         {
                        case 0x0d:OLED_ShowNum(72,6,46,4,16);break;//o
                        case 0x0c:OLED_ShowNum(0,104,RegBuf_HOLD[0],4,16);break;//1 顯示相應(yīng)的按鍵值
                        case 0x18:OLED_ShowNum(72,6,456,4,16);break;//2
/***********
                        case 0x5e:LCD1602_Dis_OneChar(4,0,Tab[3]);break;//3
                        case 0x08:LCD1602_Dis_OneChar(4,0,Tab[4]);break;//4
                        case 0x1c:LCD1602_Dis_OneChar(4,0,Tab[5]);break;//5
                        case 0x5a:LCD1602_Dis_OneChar(4,0,Tab[6]);break;//6
                        case 0x42:LCD1602_Dis_OneChar(4,0,Tab[7]);break;//7
                        case 0x52:LCD1602_Dis_OneChar(4,0,Tab[8]);break;//8
                        case 0x4a:LCD1602_Dis_OneChar(4,0,Tab[9]);break;//9
                        case 0x45:LCD1602_Dis_OneChar(4,0,Tab[10]);break;//1
                        case 0x46:LCD1602_Dis_OneChar(4,0,Tab[11]);break;//1
                        case 0x47:LCD1602_Dis_OneChar(4,0,Tab[12]);break;//1
                        case 0x44:LCD1602_Dis_OneChar(4,0,Tab[13]);break;//1
                        case 0x40:LCD1602_Dis_OneChar(4,0,Tab[14]);break;//1
                        case 0x43:LCD1602_Dis_OneChar(4,0,Tab[15]);break;//1
                        case 0x07:LCD1602_Dis_OneChar(4,0,Tab[16]);break;//1
                        case 0x15:LCD1602_Dis_OneChar(4,0,Tab[17]);break;//1
                        case 0x09:LCD1602_Dis_OneChar(4,0,Tab[18]);break;//1   
                        case 0x16:LCD1602_Dis_OneChar(4,0,Tab[19]);break;//1
                        case 0x19:LCD1602_Dis_OneChar(4,0,Tab[20]);break;//1             
             default:break;       
**********/
                  
                         }
                         irpro_ok=0;//處理完成標(biāo)志                                       
}

/********************************************
                紅外碼值處理
*******************************************/
void Ircordpro(void)//紅外碼值處理函數(shù)
{
  unsigned char  i, j, k;
  unsigned char  cord,value;

  k=1;
  for(i=0;i<4;i++)      //處理4個(gè)字節(jié)
     {
      for(j=1;j<=8;j++) //處理1個(gè)字節(jié)8位
         {
          cord=irdata[k];
          if(cord>7)//大于某值為1,這個(gè)和晶振有絕對關(guān)系,這里使用12M計(jì)算,此值可以有一定誤差
             value|=0x80;
          if(j<8)
                    {
                         value>>=1;
                        }
           k++;
         }
     IRcord=value;
     value=0;
//         tablex(IRcord[2]);     
     }
         irpro_ok=1;//處理完畢標(biāo)志位置1
}


/******************************************************************
功能: 初始化
輸入:        站號設(shè)置
輸出: 無
版本: V15.09.0
作者: 大姆指測控 - 姚工,   QQ:657874307
修改日期: 2015-09
說明:,根據(jù)P2口低四位編碼開關(guān)的設(shè)置,修改從站地址1-32位,默認(rèn)都為0則實(shí)際地址為1
******************************************************************/
uchar  Get_ID_HD(void)
{
    uchar temp,i=50;

    P2|=0x0f;//0000 1111
    while(i--);

    temp=~P2;                //P2.0-P2.3接撥碼開關(guān),用來設(shè)置4位站號 1111 0000
    temp&=0x0f;     //1111 0000&0000 1111 temp = 0000 0000

    if(temp==0)
    {
        return 1;        //站號不能為0,返回默認(rèn)的1
    }
    return temp;        //返回站號
}

/******************************************************************
功能: 初始化
輸入:        無
輸出: 無
版本: V15.09.0
作者: 大姆指測控 - 姚工,   QQ:657874307
修改日期: 2015-09
說明:系統(tǒng)上電之后,先取得系統(tǒng)設(shè)置的參數(shù),然后用這些參數(shù)來對相應(yīng)的模塊進(jìn)行初始化,如下:
                1. 串口通信的波特率 和 校驗(yàn)值 [決定本從機(jī)的通信參數(shù)];
                2. modbus 從機(jī)的站號 ,可以使用撥碼開關(guān)來設(shè)定站號,或者使用EEPROM存儲(chǔ)站號;
******************************************************************/
void SYSinit(void)
{
       TimesMsinitInt();                                        //Ms定時(shí)器初始化,用作產(chǎn)生1ms的系統(tǒng)時(shí)間基準(zhǔn)
                OLED_Init();                        //初始化OLED  
                timer_init();//初始化定時(shí)器(打開后出現(xiàn)連接不上問題)
                EX0init(); //初始化外部中斷

    //先寫相應(yīng)的函數(shù),取得系統(tǒng)參數(shù)....
    //以下例程使用固定值:19200 ,無校驗(yàn),
    //站號 =撥碼開關(guān)設(shè)定1-32
    UartInit(19200, NONE_PARITY);                //串口初始化[須要確定好波特率和校驗(yàn)值]
    ModbusInit(Get_ID_HD(),StartSend);         //Modbus串口初始化[須要確定好站號]
    //
//       IP = 0x03;
//       IPH = 0x09;
    EA = 1;

}


//----------------------------START-------------------------------
//=================================================================
void main(void)
{
               
//                u8 Data_p = P2;
                SYSinit();                                                        //系統(tǒng)初始化

//                numa = 0x01;
                OLED_Clear();
                OLED_ShowCHinese(0,0,0);//
                OLED_ShowCHinese(18,0,1);//
                OLED_ShowCHinese(36,0,2);//
                OLED_ShowCHinese(54,0,3);//
                OLED_ShowCHinese(72,0,4);//
                OLED_ShowCHinese(90,0,5);//
//                OLED_ShowCHinese(108,0,6);//


    while (1)
    {
        UartRxPoll();                                   //串口數(shù)據(jù)幀檢查處理
        TEST1();
        //......
       //繼續(xù)添加應(yīng)用程序代碼...
         LED=1;

/******************************
功能:讀寄存器
調(diào)用:RegBuf_Input[0],0為寄存器地址對應(yīng)30001
*****************************/
                OLED_ShowNum(0,6,RegBuf_Input[0],4,16);
                OLED_ShowNum(32,6,RegBuf_Input[1],4,16);
                OLED_ShowNum(64,6,RegBuf_Input[2],4,16);
                OLED_ShowNum(96,6,RegBuf_Input[3],4,16);

/******************************
功能:讀寫寄存器
調(diào)用:RegBuf_HOLD[0],0為寄存器地址對應(yīng)40001
*****************************/

                OLED_ShowNum(0,4,RegBuf_HOLD[0],4,16);//最大16950
                OLED_ShowNum(32,4,RegBuf_HOLD[1],4,16);//最大16950
                OLED_ShowNum(64,4,RegBuf_HOLD[2],4,16);//最大16950
                OLED_ShowNum(96,4,RegBuf_HOLD[3],4,16);//最大16950

//                OLED_ShowNum(0,6,SwBuf_IN[0],4,16);//最大16950
//      OLED_ShowChar(40,6,SwBuf_IN[0]);

/***************測試控制*************/
                OLED_ShowChar(0,2,TimeNum[5]);
                OLED_ShowChar(8,2,TimeNum[6]);
                OLED_ShowChar(16,2,TimeNum[8]);
                OLED_ShowChar(24,2,TimeNum[9]);
                OLED_ShowChar(32,2,TimeNum[11]);
                OLED_ShowChar(40,2,TimeNum[12]);
                OLED_ShowChar(48,2,TimeNum[14]);
                OLED_ShowChar(56,2,TimeNum[15]);
                OLED_ShowChar(64,2,TimeNum[17]);
                OLED_ShowChar(72,2,TimeNum[18]);
                OLED_ShowChar(80,2,TimeNum[20]);
                OLED_ShowChar(88,2,TimeNum[21]);
                if(irok)                        //如果接收好了進(jìn)行紅外處理
                  {   
         
                   Ircordpro();
                   irok=0;
                  }

                if(irpro_ok)                   //如果處理好后進(jìn)行工作處理,如按對應(yīng)的按鍵后顯示對應(yīng)的數(shù)字等
                  {
                   Ir_work();
                   Ir_towork();
                  }



    }
}



開始以為時(shí)紅外遙控程序問題,我都放在主程序里面調(diào)試了
回復(fù)

使用道具 舉報(bào)

地板
ID:89072 發(fā)表于 2021-12-7 11:13 | 只看該作者
Modbus 程序與紅外程序單獨(dú)調(diào)試都沒問題,但是放在一起就會(huì)沖突
回復(fù)

使用道具 舉報(bào)

5#
ID:234769 發(fā)表于 2021-12-7 11:18 | 只看該作者
UART 也用中斷
回復(fù)

使用道具 舉報(bào)

6#
ID:636538 發(fā)表于 2021-12-7 11:29 | 只看該作者
不明白你想做什么,TMOD =0x30;定時(shí)器/計(jì)數(shù)器1停止工作,此時(shí)無效,TMOD =0x20,定時(shí)器/計(jì)數(shù)器1八位自動(dòng)重載計(jì)數(shù),你想兩個(gè)定時(shí)器同時(shí)使用TMOD=0X20;//定時(shí)器1工作在8位自動(dòng)重載,TMOD |=0X01;//定時(shí)器0工作在模式1,16位,Modbus RTU應(yīng)該是你串口接收停止比如超過10ms,認(rèn)為接收完畢,進(jìn)行數(shù)據(jù)處理,可是你定時(shí)器1來給計(jì)時(shí)的話,你設(shè)定時(shí)間是多少,沒有預(yù)設(shè)值,
void Timer1Init(void)                //10毫秒@11.0592MHz
{
        AUXR &= 0xBF;                //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0x0F;                //設(shè)置定時(shí)器模式
        TL1 = 0x00;                //設(shè)置定時(shí)初始值
        TH1 = 0xDC;                //設(shè)置定時(shí)初始值
        TF1 = 0;                //清除TF1標(biāo)志
        TR1 = 1;                //定時(shí)器1開始計(jì)時(shí)
}
回復(fù)

使用道具 舉報(bào)

7#
ID:89072 發(fā)表于 2021-12-7 12:30 | 只看該作者
SKYLAR123 發(fā)表于 2021-12-7 11:29
不明白你想做什么,TMOD =0x30;定時(shí)器/計(jì)數(shù)器1停止工作,此時(shí)無效,TMOD =0x20,定時(shí)器/計(jì)數(shù)器1八位自動(dòng)重 ...
  1. /*************************************
  2.                 01 (0x01)        讀線圈
  3.         02 (0x02)        讀離散量輸入
  4.         03 (0x03)        讀保持寄存器
  5.         04(0x04)         讀輸入寄存器
  6.         05 (0x05)        寫單個(gè)線圈
  7.         06 (0x06)        寫單個(gè)寄存器
  8.         15 (0x0F)        寫多個(gè)線圈
  9.         16 (0x10)        寫多個(gè)寄存器
  10. *************************************/
  11. #define _MAIN_C_
  12. //============================
  13. #include "includeFile.h"
  14. //============================
  15. #include "Delay.h"
  16. sfr P4   = 0xC0; //8 bitPort4

  17. bit irpro_ok,irok;
  18. sbit IR=P3^3;  //紅外接口標(biāo)志
  19. uint count;  
  20. uchar  irtime;
  21. //u8  numa = 234;
  22. sbit LED = P4^4;

  23. uchar IRcord[6];
  24. uchar irdata[33];
  25. uchar code TabA[22]="0123456789ABCDEFGHIJKL";
  26. uchar data TimeNum[]="                      ";

  27. /*------------------------------------------------
  28.                   定時(shí)器1中斷處理
  29. void tm1_isr() interrupt 1
  30. ------------------------------------------------*/
  31. void tim1_isr()interrupt 3  //定時(shí)中斷
  32. {
  33.         irtime++;

  34. }
  35. /*------------------------------------------------
  36.                   外部中斷0中斷處理
  37. ------------------------------------------------*/
  38. void EX0_ISR (void) interrupt 2  //外部中斷1服務(wù)函數(shù)
  39. {
  40.   static unsigned char   i;             //接收紅外信號處理
  41.   static bit startflag;                //是否開始處理標(biāo)志位
  42. if(startflag)                        
  43.    {

  44.    if(irtime<63&&irtime>=33)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms
  45.             i=0;
  46.                     irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1
  47.                     irtime=0;
  48.                     i++;
  49.                             if(i==33)
  50.                               {
  51.                                    irok=1;
  52.                                  i=0;
  53.                                   }
  54.           }
  55.            else
  56.                 {
  57.                 irtime=0;
  58.                 startflag=1;

  59.                 }

  60. }

  61. /*------------------------------------------------
  62.                 定時(shí)器0初始化
  63. ------------------------------------------------*/
  64. void timer_init(void)//定時(shí)器初始化
  65. {

  66. //    IPH |= 0x01;
  67. //    PT1=1;
  68. //IP = 0x08;
  69. //IPH = 0x08;
  70.         TMOD =0x30;/////////設(shè)置工作方式2
  71.         TH1=0x00; //重載值
  72.         TL1=0x00; //初始化值
  73.         EA=1;       
  74.         ET1=1;//開總中斷;開定時(shí)器中斷
  75.         TR1=1;////////啟動(dòng)計(jì)數(shù)器
  76. }

  77. /*------------------------------------------------
  78.                   外部中斷1初始化
  79. ------------------------------------------------*/
  80. void EX0init(void)
  81. {
  82. //IPH = 0x00;
  83. //PX1 = 1;
  84. IPH = 0x04;
  85. IP = 0x00;
  86.         IT1 = 1;   //指定外部中斷1下降沿觸發(fā),INT0 (P3.3)
  87.         EX1 = 1;   //使能外部中斷
  88.         EA = 1;    //開總中斷


  89. }

  90. /*------------------------------------------------
  91.                   鍵值處理
  92. 注:分解顯示轉(zhuǎn)換值列表

  93. ------------------------------------------------*/
  94. void Ir_work(void)//紅外鍵值散轉(zhuǎn)程序
  95. {
  96.         TimeNum[5] = TabA[IRcord[0]/16];   //處理客戶碼并顯示
  97.         TimeNum[6] = TabA[IRcord[0]%16];
  98.         TimeNum[8] = TabA[IRcord[1]/16];   //處理客戶碼并顯示
  99.         TimeNum[9] = TabA[IRcord[1]%16];
  100.         TimeNum[11] = TabA[IRcord[2]/16];  //處理數(shù)據(jù)碼并顯示
  101.         TimeNum[12] = TabA[IRcord[2]%16];
  102.         TimeNum[14] = TabA[IRcord[3]/16];  //處理數(shù)據(jù)反碼并顯示
  103.         TimeNum[15] = TabA[IRcord[3]%16];
  104.         TimeNum[17] = TabA[IRcord[4]/16];  //處理數(shù)據(jù)反碼并顯示
  105.         TimeNum[18] = TabA[IRcord[4]%16];
  106.         TimeNum[20] = TabA[IRcord[5]/16];  //處理數(shù)據(jù)反碼并顯示
  107.         TimeNum[21] = TabA[IRcord[5]%16];
  108.         irpro_ok=0;//處理完成標(biāo)志
  109.   }

  110. /***************************************************************/
  111. void Ir_towork(void)//紅外鍵值散轉(zhuǎn)程序
  112. {

  113. //            PutStr(1,0,TimeNum);//顯示處理過后的碼值
  114.            switch(IRcord[2])//判斷第三個(gè)數(shù)碼值
  115.          {
  116.                         case 0x0d:OLED_ShowNum(72,6,46,4,16);break;//o
  117.                         case 0x0c:OLED_ShowNum(0,104,RegBuf_HOLD[0],4,16);break;//1 顯示相應(yīng)的按鍵值
  118.                         case 0x18:OLED_ShowNum(72,6,456,4,16);break;//2
  119. /***********
  120.                         case 0x5e:LCD1602_Dis_OneChar(4,0,Tab[3]);break;//3
  121.                         case 0x08:LCD1602_Dis_OneChar(4,0,Tab[4]);break;//4
  122.                         case 0x1c:LCD1602_Dis_OneChar(4,0,Tab[5]);break;//5
  123.                         case 0x5a:LCD1602_Dis_OneChar(4,0,Tab[6]);break;//6
  124.                         case 0x42:LCD1602_Dis_OneChar(4,0,Tab[7]);break;//7
  125.                         case 0x52:LCD1602_Dis_OneChar(4,0,Tab[8]);break;//8
  126.                         case 0x4a:LCD1602_Dis_OneChar(4,0,Tab[9]);break;//9
  127.                         case 0x45:LCD1602_Dis_OneChar(4,0,Tab[10]);break;//1
  128.                         case 0x46:LCD1602_Dis_OneChar(4,0,Tab[11]);break;//1
  129.                         case 0x47:LCD1602_Dis_OneChar(4,0,Tab[12]);break;//1
  130.                         case 0x44:LCD1602_Dis_OneChar(4,0,Tab[13]);break;//1
  131.                         case 0x40:LCD1602_Dis_OneChar(4,0,Tab[14]);break;//1
  132.                         case 0x43:LCD1602_Dis_OneChar(4,0,Tab[15]);break;//1
  133.                         case 0x07:LCD1602_Dis_OneChar(4,0,Tab[16]);break;//1
  134.                         case 0x15:LCD1602_Dis_OneChar(4,0,Tab[17]);break;//1
  135.                         case 0x09:LCD1602_Dis_OneChar(4,0,Tab[18]);break;//1   
  136.                         case 0x16:LCD1602_Dis_OneChar(4,0,Tab[19]);break;//1
  137.                         case 0x19:LCD1602_Dis_OneChar(4,0,Tab[20]);break;//1             
  138.              default:break;       
  139. **********/
  140.                   
  141.                          }
  142.                          irpro_ok=0;//處理完成標(biāo)志                                       
  143. }

  144. /********************************************
  145.                 紅外碼值處理
  146. *******************************************/
  147. void Ircordpro(void)//紅外碼值處理函數(shù)
  148. {
  149.   unsigned char  i, j, k;
  150.   unsigned char  cord,value;

  151.   k=1;
  152.   for(i=0;i<4;i++)      //處理4個(gè)字節(jié)
  153.      {
  154.       for(j=1;j<=8;j++) //處理1個(gè)字節(jié)8位
  155.          {
  156.           cord=irdata[k];
  157.           if(cord>7)//大于某值為1,這個(gè)和晶振有絕對關(guān)系,這里使用12M計(jì)算,此值可以有一定誤差
  158.              value|=0x80;
  159.           if(j<8)
  160.                     {
  161.                          value>>=1;
  162.                         }
  163.            k++;
  164.          }
  165.      IRcord[i]=value;
  166.      value=0;
  167. //         tablex(IRcord[2]);     
  168.      }
  169.          irpro_ok=1;//處理完畢標(biāo)志位置1
  170. }


  171. /******************************************************************
  172. 功能: 初始化
  173. 輸入:        站號設(shè)置
  174. 輸出: 無
  175. 版本: V15.09.0
  176. 作者: 大姆指測控 - 姚工,   QQ:657874307
  177. 修改日期: 2015-09
  178. 說明:,根據(jù)P2口低四位編碼開關(guān)的設(shè)置,修改從站地址1-32位,默認(rèn)都為0則實(shí)際地址為1
  179. ******************************************************************/
  180. uchar  Get_ID_HD(void)
  181. {
  182.     uchar temp,i=50;

  183.     P2|=0x0f;//0000 1111
  184.     while(i--);

  185.     temp=~P2;                //P2.0-P2.3接撥碼開關(guān),用來設(shè)置4位站號 1111 0000
  186.     temp&=0x0f;     //1111 0000&0000 1111 temp = 0000 0000

  187.     if(temp==0)
  188.     {
  189.         return 1;        //站號不能為0,返回默認(rèn)的1
  190.     }
  191.     return temp;        //返回站號
  192. }

  193. /******************************************************************
  194. 功能: 初始化
  195. 輸入:        無
  196. 輸出: 無
  197. 版本: V15.09.0
  198. 作者: 大姆指測控 - 姚工,   QQ:657874307
  199. 修改日期: 2015-09
  200. 說明:系統(tǒng)上電之后,先取得系統(tǒng)設(shè)置的參數(shù),然后用這些參數(shù)來對相應(yīng)的模塊進(jìn)行初始化,如下:
  201.                 1. 串口通信的波特率 和 校驗(yàn)值 [決定本從機(jī)的通信參數(shù)];
  202.                 2. modbus 從機(jī)的站號 ,可以使用撥碼開關(guān)來設(shè)定站號,或者使用EEPROM存儲(chǔ)站號;
  203. ******************************************************************/
  204. void SYSinit(void)
  205. {
  206.        TimesMsinitInt();                                        //Ms定時(shí)器初始化,用作產(chǎn)生1ms的系統(tǒng)時(shí)間基準(zhǔn)
  207.                 OLED_Init();                        //初始化OLED  
  208.                 timer_init();//初始化定時(shí)器(打開后出現(xiàn)連接不上問題)
  209.                 EX0init(); //初始化外部中斷

  210.     //先寫相應(yīng)的函數(shù),取得系統(tǒng)參數(shù)....
  211.     //以下例程使用固定值:19200 ,無校驗(yàn),
  212.     //站號 =撥碼開關(guān)設(shè)定1-32
  213.     UartInit(19200, NONE_PARITY);                //串口初始化[須要確定好波特率和校驗(yàn)值]
  214.     ModbusInit(Get_ID_HD(),StartSend);         //Modbus串口初始化[須要確定好站號]
  215.     //
  216. //       IP = 0x03;
  217. //       IPH = 0x09;
  218.     EA = 1;

  219. }


  220. //----------------------------START-------------------------------
  221. //=================================================================
  222. void main(void)
  223. {
  224.                
  225. //                u8 Data_p = P2;
  226.                 SYSinit();                                                        //系統(tǒng)初始化

  227. //                numa = 0x01;
  228.                 OLED_Clear();
  229.                 OLED_ShowCHinese(0,0,0);//
  230.                 OLED_ShowCHinese(18,0,1);//
  231.                 OLED_ShowCHinese(36,0,2);//
  232.                 OLED_ShowCHinese(54,0,3);//
  233.                 OLED_ShowCHinese(72,0,4);//
  234.                 OLED_ShowCHinese(90,0,5);//
  235. //                OLED_ShowCHinese(108,0,6);//


  236.     while (1)
  237.     {
  238.         UartRxPoll();                                   //串口數(shù)據(jù)幀檢查處理
  239.         TEST1();
  240.         //......
  241.        //繼續(xù)添加應(yīng)用程序代碼...
  242.          LED=1;

  243. /******************************
  244. 功能:讀寄存器
  245. 調(diào)用:RegBuf_Input[0],0為寄存器地址對應(yīng)30001
  246. *****************************/
  247.                 OLED_ShowNum(0,6,RegBuf_Input[0],4,16);
  248.                 OLED_ShowNum(32,6,RegBuf_Input[1],4,16);
  249.                 OLED_ShowNum(64,6,RegBuf_Input[2],4,16);
  250.                 OLED_ShowNum(96,6,RegBuf_Input[3],4,16);

  251. /******************************
  252. 功能:讀寫寄存器
  253. 調(diào)用:RegBuf_HOLD[0],0為寄存器地址對應(yīng)40001
  254. *****************************/

  255.                 OLED_ShowNum(0,4,RegBuf_HOLD[0],4,16);//最大16950
  256.                 OLED_ShowNum(32,4,RegBuf_HOLD[1],4,16);//最大16950
  257.                 OLED_ShowNum(64,4,RegBuf_HOLD[2],4,16);//最大16950
  258.                 OLED_ShowNum(96,4,RegBuf_HOLD[3],4,16);//最大16950

  259. //                OLED_ShowNum(0,6,SwBuf_IN[0],4,16);//最大16950
  260. //      OLED_ShowChar(40,6,SwBuf_IN[0]);

  261. /***************測試控制*************/
  262.                 OLED_ShowChar(0,2,TimeNum[5]);
  263.                 OLED_ShowChar(8,2,TimeNum[6]);
  264.                 OLED_ShowChar(16,2,TimeNum[8]);
  265.                 OLED_ShowChar(24,2,TimeNum[9]);
  266.                 OLED_ShowChar(32,2,TimeNum[11]);
  267.                 OLED_ShowChar(40,2,TimeNum[12]);
  268.                 OLED_ShowChar(48,2,TimeNum[14]);
  269.                 OLED_ShowChar(56,2,TimeNum[15]);
  270.                 OLED_ShowChar(64,2,TimeNum[17]);
  271.                 OLED_ShowChar(72,2,TimeNum[18]);
  272.                 OLED_ShowChar(80,2,TimeNum[20]);
  273.                 OLED_ShowChar(88,2,TimeNum[21]);
  274.                 if(irok)                        //如果接收好了進(jìn)行紅外處理
  275.                   {   
  276.          
  277.                    Ircordpro();
  278.                    irok=0;
  279.                   }

  280.                 if(irpro_ok)                   //如果處理好后進(jìn)行工作處理,如按對應(yīng)的按鍵后顯示對應(yīng)的數(shù)字等
  281.                   {
  282.                    Ir_work();
  283.                    Ir_towork();
  284.                   }



  285.     }
  286. }
復(fù)制代碼

我設(shè)置測試的,就算設(shè)置TOMD=0x30;modbus也會(huì)出現(xiàn)不能用,
回復(fù)

使用道具 舉報(bào)

8#
ID:89072 發(fā)表于 2021-12-7 16:39 | 只看該作者
外部中斷1設(shè)置優(yōu)先級0,,定時(shí)器1是不是也需要設(shè)置優(yōu)先級1?
回復(fù)

使用道具 舉報(bào)

9#
ID:89072 發(fā)表于 2021-12-7 16:50 | 只看該作者
本帖最后由 hslcac 于 2021-12-7 16:56 編輯


外部中斷1優(yōu)先級0,定時(shí)器1優(yōu)先級1,設(shè)置完后還是讀取錯(cuò)誤,接收的紅外解碼FFFFFFFBF7C8B,是時(shí)序問題嗎?請大神幫忙看一下問題出在哪里啊

回復(fù)

使用道具 舉報(bào)

10#
ID:624769 發(fā)表于 2021-12-7 16:59 | 只看該作者
當(dāng)你設(shè)置 IP = 0x04的時(shí)候

你前面寫的 IP = 0x08 就自動(dòng)無效了,

這個(gè)道理你懂得吧?
回復(fù)

使用道具 舉報(bào)

11#
ID:89072 發(fā)表于 2021-12-7 17:41 | 只看該作者
188610329 發(fā)表于 2021-12-7 16:59
當(dāng)你設(shè)置 IP = 0x04的時(shí)候

你前面寫的 IP = 0x08 就自動(dòng)無效了,


明白了非常感謝
回復(fù)

使用道具 舉報(bào)

12#
ID:89072 發(fā)表于 2021-12-7 17:41 | 只看該作者
審核通過的慢,發(fā)的程序重復(fù)了
回復(fù)

使用道具 舉報(bào)

13#
ID:57657 發(fā)表于 2021-12-7 18:16 | 只看該作者
你這代碼都是東拼西湊來的,框架邏輯太亂,根本沒法改,只能從頭寫,并進(jìn)行一些優(yōu)化。
回復(fù)

使用道具 舉報(bào)

14#
ID:89072 發(fā)表于 2021-12-7 18:18 | 只看該作者

調(diào)試不過啊,解碼顯示:0000 0000 7E3A
回復(fù)

使用道具 舉報(bào)

15#
ID:89072 發(fā)表于 2021-12-7 18:39 | 只看該作者
npn 發(fā)表于 2021-12-7 18:16
你這代碼都是東拼西湊來的,框架邏輯太亂,根本沒法改,只能從頭寫,并進(jìn)行一些優(yōu)化。

不亂的,整體的框架是在Modbus的程序上增加的
回復(fù)

使用道具 舉報(bào)

16#
ID:89072 發(fā)表于 2021-12-7 19:54 | 只看該作者
Modbus程序電路圖.7z (3.08 MB, 下載次數(shù): 10)
程序和電路圖,開源了,Modbus程序
留給有需要的朋友吧,記得解決了定時(shí)器問題告訴我怎么處理的就行,共同學(xué)習(xí),共同進(jìn)步

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

17#
ID:624769 發(fā)表于 2021-12-7 20:40 | 只看該作者
說實(shí)話,看了半天沒看明白你有什么問題,以及你想要做什么, 關(guān)于你的程序,說實(shí)話,年紀(jì)大了,那么長一篇代碼,還不是自己要用的,真么沒有太大耐心分析,就跟你說說浮在表面上的問題吧。
你反復(fù)說Modbus怎么怎么, Modbus 不是通信協(xié)議么? 有什么能用不能用的說法? 要用到 Modbus 協(xié)議,一般是通過串口。不管是485也好,232也好,到了單片機(jī)這邊,能做的只有 Uart.  你貼的代碼也只是部分,我也沒精力完全看,但是,如果你用的是硬件Uart 你 interrupt 4 開了么?  然后,如果用的硬件Uart 肯定需要定時(shí)器做波特率發(fā)生器吧? 那么一般是要用定時(shí)器1的吧? TMOD也要設(shè)置為 0x20 的吧? 那么,你又說兩個(gè)定時(shí)器一起使用,其中包括了Uart 的定時(shí)器1么? 要知道定時(shí)器1已經(jīng)被用作波特率發(fā)生器了,除非拆分定時(shí)器0,不然你無法把定時(shí)器1用來做別的事。

接著在說定時(shí)器0,如果你要把定時(shí)器0設(shè)置為16位定時(shí)器,就好像前面IPH的問題,你不能直接去 TMOD = 0x01; 你要考慮你的 TMOD = 0x20;的問題,所以,要么,你干脆點(diǎn), 一個(gè) TMOD = 0x21;    要么,設(shè)置定時(shí)器的時(shí)候,  分別用  TMOD |= 0x20;  TMOD |= 0x01;   那么才不會(huì)影響設(shè)置。類似的問題,應(yīng)該有不少,你最好仔細(xì)捋一遍,比如: TMOD 你全文搜索一下,到底多少地方設(shè)置了? 有沒有覆蓋了之前的設(shè)置,等等。

暫時(shí)想到這些,就寫這些。 其實(shí),你的代碼,真的,怎么看都是東拼西湊的,因?yàn)閷哟涡韵到y(tǒng)性,完全沒有。
回復(fù)

使用道具 舉報(bào)

18#
ID:89072 發(fā)表于 2021-12-7 20:58 | 只看該作者
188610329 發(fā)表于 2021-12-7 20:40
說實(shí)話,看了半天沒看明白你有什么問題,以及你想要做什么, 關(guān)于你的程序,說實(shí)話,年紀(jì)大了,那么長一篇 ...

非常感謝您的回復(fù),程序就像您說得,我是使用的模塊編程的,都是單個(gè)調(diào)試并借鑒別人的,我自己只做了合并,再此感謝您的解答,我做的是一個(gè)遠(yuǎn)程485狀態(tài)監(jiān)控程序,監(jiān)控輸入的狀態(tài),并做觸屏顯示,本來感覺可以實(shí)現(xiàn),由于技術(shù)基礎(chǔ)確實(shí)有限,用PLC成本高,使用的數(shù)量又很多,所以調(diào)試了很久了才到論壇求助,再此感謝您的指點(diǎn),謝謝。
回復(fù)

使用道具 舉報(bào)

19#
ID:89072 發(fā)表于 2021-12-7 21:09 | 只看該作者
188610329 發(fā)表于 2021-12-7 20:40
說實(shí)話,看了半天沒看明白你有什么問題,以及你想要做什么, 關(guān)于你的程序,說實(shí)話,年紀(jì)大了,那么長一篇 ...


非常感謝前輩您的指點(diǎn),您說的“其中包括了Uart 的定時(shí)器1么?”我返回找到了,還是個(gè)人經(jīng)驗(yàn)不足,再此感謝您,確實(shí)是定時(shí)器1用了,我又重復(fù)使用了定時(shí)器1作為紅外定時(shí)器計(jì)時(shí)使用,非常感謝。
回復(fù)

使用道具 舉報(bào)

20#
ID:89072 發(fā)表于 2021-12-8 07:49 | 只看該作者
再次感謝 前輩(188610329 )經(jīng)過仔細(xì)檢查,確實(shí)是定時(shí)器在Modbus里面使用了定時(shí)器1和0,關(guān)于紅外程序需要使用定時(shí)器需要使用STC12的void PCA_isr() interrupt 7 using 1,PCA中斷定時(shí)器,由于我基礎(chǔ)沒打好,再此和各位學(xué)習(xí)中的朋友們做交流吧,有能力的可以一試,我也是半路開始學(xué)的,
Modbus程序完全可以使用,配合昆侖通態(tài)的上位軟件做控制與監(jiān)控沒問題,OLED自己可以取模軟件修改顯示的字,程序中有Modbus說明,地址使用的外部P2.0-P2.3的4個(gè)IO口做地址選擇控制,485使能使用的P3.2外部中斷0,增加自己的程序可以在APP.C中增加,我已做了部分測試, 其余的大家自己研究。
有不懂的可以交流,解決紅外定時(shí)器問題了幫忙告訴我一下。
回復(fù)

使用道具 舉報(bào)

21#
ID:624769 發(fā)表于 2021-12-8 18:20 | 只看該作者
hslcac 發(fā)表于 2021-12-8 07:49
再次感謝 前輩(188610329 )經(jīng)過仔細(xì)檢查,確實(shí)是定時(shí)器在Modbus里面使用了定時(shí)器1和0,關(guān)于紅外程序需要 ...

你紅外線,現(xiàn)在是什么問題? 沒有定時(shí)器么??

你單片機(jī)具體什么型號? 如果 STC12C5A系列的話, 是有獨(dú)立波特率發(fā)生器的,讓Uart使用 獨(dú)立波特率發(fā)生器的話,T1就解放出來,可以作為其他的定時(shí)器使用了。
回復(fù)

使用道具 舉報(bào)

22#
ID:89072 發(fā)表于 2021-12-10 17:38 | 只看該作者
188610329 發(fā)表于 2021-12-8 18:20
你紅外線,現(xiàn)在是什么問題? 沒有定時(shí)器么??

你單片機(jī)具體什么型號? 如果 STC12C5A系列的話, 是有 ...


感謝前輩的回復(fù),使用的紅外遙控做按鍵設(shè)置用,我現(xiàn)在紅外的定時(shí)器1的TMOD改為0x03后,發(fā)現(xiàn)單片機(jī)可以解碼手機(jī)遙控碼,并且很穩(wěn)定,我也沒再考慮修改程序,就是有時(shí)候上電后出現(xiàn)485延遲信號接收不到問題,您說的穿孔專用的定時(shí)器中斷,我會(huì)繼續(xù)查資料測試找辦法調(diào)試,現(xiàn)在運(yùn)行基本穩(wěn)定,時(shí)間又有限,所以有時(shí)間我會(huì)在優(yōu)化的,謝謝您。我是一個(gè)單片機(jī)愛好者,由于個(gè)人時(shí)間很少,平時(shí)都是回家后查資料學(xué)習(xí),沒有太多精力去學(xué)基礎(chǔ),只有自己做些小的板子,把單獨(dú)的程序調(diào)試好了(還是別人的成熟程序),做模塊化合并,遇到問題邊學(xué)邊做的,現(xiàn)已近不惑之年,工作壓力也大學(xué)習(xí)精力有限,有些簡單的問題前輩請見諒。
回復(fù)

使用道具 舉報(bào)

23#
ID:89072 發(fā)表于 2021-12-10 18:50 | 只看該作者
單片機(jī)使用的STC12C5A60S2
回復(fù)

使用道具 舉報(bào)

24#
ID:624769 發(fā)表于 2021-12-10 19:10 | 只看該作者
hslcac 發(fā)表于 2021-12-10 18:50
單片機(jī)使用的STC12C5A60S2

技術(shù)手冊, 第 283,284, 297 頁, 有關(guān)于 專用波特率發(fā)生器BRT 的使用說明。

2樓下載611頁的:http://www.torrancerestoration.com/bbs/dpj-96160-1.html

串口,使用BRT的話,就不會(huì)占用定時(shí)器T1了。
而且,BRT也只能給串口用,你串口不用BRT,這個(gè)資源也是白白浪費(fèi)的。
回復(fù)

使用道具 舉報(bào)

25#
ID:89072 發(fā)表于 2021-12-11 07:42 | 只看該作者
188610329 發(fā)表于 2021-12-10 19:10
技術(shù)手冊, 第 283,284, 297 頁, 有關(guān)于 專用波特率發(fā)生器BRT 的使用說明。

好的,謝謝您
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表