欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 同時使用單片機外部中斷0,1與定時器中斷0,1的程序問題 [打印本頁]

作者: hslcac    時間: 2021-12-7 10:05
標題: 同時使用單片機外部中斷0,1與定時器中斷0,1的程序問題
在調試485控制時,用到了外部中斷0和外部中斷1,使用的別人的Modbus RTU程序,自己又需要使用紅外設置,作為按鍵使用,由于基礎不好,現在卡在兩個定時器同時使用時,無法Modbus通訊,設置了外部中斷1優先級為0,當設置定時器1的工作模式2時
單片機源程序如下:
void timer_init(void)//定時器初始化
{

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

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

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

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

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



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

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

這是T1與T0的定義

Modbus.rar

10.25 KB, 下載次數: 9


作者: npn    時間: 2021-12-7 10:59
你用了外部中斷0、1,EX0=1; 和 EX1=1;  以及中斷入口哪里去了?
作者: hslcac    時間: 2021-12-7 11:11
npn 發表于 2021-12-7 10:59
你用了外部中斷0、1,EX0=1; 和 EX1=1;  以及中斷入口哪里去了?

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

bit irpro_ok,irok;
sbit IR=P3^3;  //紅外接口標志
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[]="                      ";

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

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

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

                }

}

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

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

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


}

/*------------------------------------------------
                  鍵值處理
注:分解顯示轉換值列表

------------------------------------------------*/
void Ir_work(void)//紅外鍵值散轉程序
{
        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];  //處理數據碼并顯示
        TimeNum[12] = TabA[IRcord[2]%16];
        TimeNum[14] = TabA[IRcord[3]/16];  //處理數據反碼并顯示
        TimeNum[15] = TabA[IRcord[3]%16];
        TimeNum[17] = TabA[IRcord[4]/16];  //處理數據反碼并顯示
        TimeNum[18] = TabA[IRcord[4]%16];
        TimeNum[20] = TabA[IRcord[5]/16];  //處理數據反碼并顯示
        TimeNum[21] = TabA[IRcord[5]%16];
        irpro_ok=0;//處理完成標志
  }

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

//            PutStr(1,0,TimeNum);//顯示處理過后的碼值
           switch(IRcord[2])//判斷第三個數碼值
         {
                        case 0x0d:OLED_ShowNum(72,6,46,4,16);break;//o
                        case 0x0c:OLED_ShowNum(0,104,RegBuf_HOLD[0],4,16);break;//1 顯示相應的按鍵值
                        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;//處理完成標志                                       
}

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

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


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

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

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

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

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

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

}


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

//                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();                                   //串口數據幀檢查處理
        TEST1();
        //......
       //繼續添加應用程序代碼...
         LED=1;

/******************************
功能:讀寄存器
調用:RegBuf_Input[0],0為寄存器地址對應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);

/******************************
功能:讀寫寄存器
調用:RegBuf_HOLD[0],0為寄存器地址對應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)                        //如果接收好了進行紅外處理
                  {   
         
                   Ircordpro();
                   irok=0;
                  }

                if(irpro_ok)                   //如果處理好后進行工作處理,如按對應的按鍵后顯示對應的數字等
                  {
                   Ir_work();
                   Ir_towork();
                  }



    }
}



開始以為時紅外遙控程序問題,我都放在主程序里面調試了
作者: hslcac    時間: 2021-12-7 11:13
Modbus 程序與紅外程序單獨調試都沒問題,但是放在一起就會沖突
作者: suzhao2008    時間: 2021-12-7 11:18
UART 也用中斷

作者: SKYLAR123    時間: 2021-12-7 11:29
不明白你想做什么,TMOD =0x30;定時器/計數器1停止工作,此時無效,TMOD =0x20,定時器/計數器1八位自動重載計數,你想兩個定時器同時使用TMOD=0X20;//定時器1工作在8位自動重載,TMOD |=0X01;//定時器0工作在模式1,16位,Modbus RTU應該是你串口接收停止比如超過10ms,認為接收完畢,進行數據處理,可是你定時器1來給計時的話,你設定時間是多少,沒有預設值,
void Timer1Init(void)                //10毫秒@11.0592MHz
{
        AUXR &= 0xBF;                //定時器時鐘12T模式
        TMOD &= 0x0F;                //設置定時器模式
        TL1 = 0x00;                //設置定時初始值
        TH1 = 0xDC;                //設置定時初始值
        TF1 = 0;                //清除TF1標志
        TR1 = 1;                //定時器1開始計時
}
作者: hslcac    時間: 2021-12-7 12:30
SKYLAR123 發表于 2021-12-7 11:29
不明白你想做什么,TMOD =0x30;定時器/計數器1停止工作,此時無效,TMOD =0x20,定時器/計數器1八位自動重 ...
  1. /*************************************
  2.                 01 (0x01)        讀線圈
  3.         02 (0x02)        讀離散量輸入
  4.         03 (0x03)        讀保持寄存器
  5.         04(0x04)         讀輸入寄存器
  6.         05 (0x05)        寫單個線圈
  7.         06 (0x06)        寫單個寄存器
  8.         15 (0x0F)        寫多個線圈
  9.         16 (0x10)        寫多個寄存器
  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;  //紅外接口標志
  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.                   定時器1中斷處理
  29. void tm1_isr() interrupt 1
  30. ------------------------------------------------*/
  31. void tim1_isr()interrupt 3  //定時中斷
  32. {
  33.         irtime++;

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

  44.    if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼,9ms+4.5ms
  45.             i=0;
  46.                     irdata[i]=irtime;//存儲每個電平的持續時間,用于以后判斷是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.                 定時器0初始化
  63. ------------------------------------------------*/
  64. void timer_init(void)//定時器初始化
  65. {

  66. //    IPH |= 0x01;
  67. //    PT1=1;
  68. //IP = 0x08;
  69. //IPH = 0x08;
  70.         TMOD =0x30;/////////設置工作方式2
  71.         TH1=0x00; //重載值
  72.         TL1=0x00; //初始化值
  73.         EA=1;       
  74.         ET1=1;//開總中斷;開定時器中斷
  75.         TR1=1;////////啟動計數器
  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下降沿觸發,INT0 (P3.3)
  87.         EX1 = 1;   //使能外部中斷
  88.         EA = 1;    //開總中斷


  89. }

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

  93. ------------------------------------------------*/
  94. void Ir_work(void)//紅外鍵值散轉程序
  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];  //處理數據碼并顯示
  101.         TimeNum[12] = TabA[IRcord[2]%16];
  102.         TimeNum[14] = TabA[IRcord[3]/16];  //處理數據反碼并顯示
  103.         TimeNum[15] = TabA[IRcord[3]%16];
  104.         TimeNum[17] = TabA[IRcord[4]/16];  //處理數據反碼并顯示
  105.         TimeNum[18] = TabA[IRcord[4]%16];
  106.         TimeNum[20] = TabA[IRcord[5]/16];  //處理數據反碼并顯示
  107.         TimeNum[21] = TabA[IRcord[5]%16];
  108.         irpro_ok=0;//處理完成標志
  109.   }

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

  113. //            PutStr(1,0,TimeNum);//顯示處理過后的碼值
  114.            switch(IRcord[2])//判斷第三個數碼值
  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 顯示相應的按鍵值
  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;//處理完成標志                                       
  143. }

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

  151.   k=1;
  152.   for(i=0;i<4;i++)      //處理4個字節
  153.      {
  154.       for(j=1;j<=8;j++) //處理1個字節8位
  155.          {
  156.           cord=irdata[k];
  157.           if(cord>7)//大于某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
  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;//處理完畢標志位置1
  170. }


  171. /******************************************************************
  172. 功能: 初始化
  173. 輸入:        站號設置
  174. 輸出: 無
  175. 版本: V15.09.0
  176. 作者: 大姆指測控 - 姚工,   QQ:657874307
  177. 修改日期: 2015-09
  178. 說明:,根據P2口低四位編碼開關的設置,修改從站地址1-32位,默認都為0則實際地址為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接撥碼開關,用來設置4位站號 1111 0000
  186.     temp&=0x0f;     //1111 0000&0000 1111 temp = 0000 0000

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

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

  210.     //先寫相應的函數,取得系統參數....
  211.     //以下例程使用固定值:19200 ,無校驗,
  212.     //站號 =撥碼開關設定1-32
  213.     UartInit(19200, NONE_PARITY);                //串口初始化[須要確定好波特率和校驗值]
  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();                                                        //系統初始化

  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();                                   //串口數據幀檢查處理
  239.         TEST1();
  240.         //......
  241.        //繼續添加應用程序代碼...
  242.          LED=1;

  243. /******************************
  244. 功能:讀寄存器
  245. 調用:RegBuf_Input[0],0為寄存器地址對應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. 調用:RegBuf_HOLD[0],0為寄存器地址對應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)                        //如果接收好了進行紅外處理
  275.                   {   
  276.          
  277.                    Ircordpro();
  278.                    irok=0;
  279.                   }

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



  285.     }
  286. }
復制代碼

我設置測試的,就算設置TOMD=0x30;modbus也會出現不能用,
作者: hslcac    時間: 2021-12-7 16:39
外部中斷1設置優先級0,,定時器1是不是也需要設置優先級1?
作者: hslcac    時間: 2021-12-7 16:50
本帖最后由 hslcac 于 2021-12-7 16:56 編輯


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


作者: 188610329    時間: 2021-12-7 16:59
當你設置 IP = 0x04的時候

你前面寫的 IP = 0x08 就自動無效了,

這個道理你懂得吧?
作者: hslcac    時間: 2021-12-7 17:41
188610329 發表于 2021-12-7 16:59
當你設置 IP = 0x04的時候

你前面寫的 IP = 0x08 就自動無效了,


明白了非常感謝

作者: hslcac    時間: 2021-12-7 17:41
審核通過的慢,發的程序重復了
作者: npn    時間: 2021-12-7 18:16
你這代碼都是東拼西湊來的,框架邏輯太亂,根本沒法改,只能從頭寫,并進行一些優化。
作者: hslcac    時間: 2021-12-7 18:18

調試不過啊,解碼顯示:0000 0000 7E3A

作者: hslcac    時間: 2021-12-7 18:39
npn 發表于 2021-12-7 18:16
你這代碼都是東拼西湊來的,框架邏輯太亂,根本沒法改,只能從頭寫,并進行一些優化。

不亂的,整體的框架是在Modbus的程序上增加的
作者: hslcac    時間: 2021-12-7 19:54
Modbus程序電路圖.7z (3.08 MB, 下載次數: 10)
程序和電路圖,開源了,Modbus程序
留給有需要的朋友吧,記得解決了定時器問題告訴我怎么處理的就行,共同學習,共同進步

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

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

暫時想到這些,就寫這些。 其實,你的代碼,真的,怎么看都是東拼西湊的,因為層次性系統性,完全沒有。

作者: hslcac    時間: 2021-12-7 20:58
188610329 發表于 2021-12-7 20:40
說實話,看了半天沒看明白你有什么問題,以及你想要做什么, 關于你的程序,說實話,年紀大了,那么長一篇 ...

非常感謝您的回復,程序就像您說得,我是使用的模塊編程的,都是單個調試并借鑒別人的,我自己只做了合并,再此感謝您的解答,我做的是一個遠程485狀態監控程序,監控輸入的狀態,并做觸屏顯示,本來感覺可以實現,由于技術基礎確實有限,用PLC成本高,使用的數量又很多,所以調試了很久了才到論壇求助,再此感謝您的指點,謝謝。
作者: hslcac    時間: 2021-12-7 21:09
188610329 發表于 2021-12-7 20:40
說實話,看了半天沒看明白你有什么問題,以及你想要做什么, 關于你的程序,說實話,年紀大了,那么長一篇 ...


非常感謝前輩您的指點,您說的“其中包括了Uart 的定時器1么?”我返回找到了,還是個人經驗不足,再此感謝您,確實是定時器1用了,我又重復使用了定時器1作為紅外定時器計時使用,非常感謝。

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

你紅外線,現在是什么問題? 沒有定時器么??

你單片機具體什么型號? 如果 STC12C5A系列的話, 是有獨立波特率發生器的,讓Uart使用 獨立波特率發生器的話,T1就解放出來,可以作為其他的定時器使用了。
作者: hslcac    時間: 2021-12-10 17:38
188610329 發表于 2021-12-8 18:20
你紅外線,現在是什么問題? 沒有定時器么??

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


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

作者: hslcac    時間: 2021-12-10 18:50
單片機使用的STC12C5A60S2
作者: 188610329    時間: 2021-12-10 19:10
hslcac 發表于 2021-12-10 18:50
單片機使用的STC12C5A60S2

技術手冊, 第 283,284, 297 頁, 有關于 專用波特率發生器BRT 的使用說明。

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

串口,使用BRT的話,就不會占用定時器T1了。
而且,BRT也只能給串口用,你串口不用BRT,這個資源也是白白浪費的。

作者: hslcac    時間: 2021-12-11 07:42
188610329 發表于 2021-12-10 19:10
技術手冊, 第 283,284, 297 頁, 有關于 專用波特率發生器BRT 的使用說明。

好的,謝謝您




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1