This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F419 用 I/O 翻轉電平寫時序的延遲問題?




MSP430F419 用 I/O 翻轉電平寫時序的延遲問題?


我是用MSP430F419發送資料給HT1621 , 讓段碼LCD顯示


#下圖示HT1621的其中一個模式

HT1621命令模式  

WR是由低電平變為高電平時取DATA的資料

      __                                                                                                                                                       ______
CS      |                                                                                                                                                    |
           |__________________________________________________________________________|
     ______      __       __       __        __       __        __       __       __       __       __        __       __    
                |     |     |     |     |     |     |     |     |     |     |     |     |     |    |     |     |    |     |     |     |     |     |     |     |  
 WR         |__|      |__|      |__|      |__|      |__|      |__|      |__|     |__|      |__|     |__|      |__|      |__|      |_______
 
         ____      __                          _________________________________________________________________  
                 |    |     |                        |                                                                                                    |
DATA        |__|     |____________|__________________________________________________|
 
                         1        0         0    |-- C8        C7      C6      C5      C4       C3      C2       C1     C0 --|
                                                                                            要發送的命令碼

       _______      __       __       ____
                     |     |    |     |    |     |  
  WR             |__|     |__|     |__|
                     |----|----|
                        t1  t2

                   T = t1 + t2


F = 1/T = 1/t1+t2 = 1/5us+5us = 1/10us= 100KHz ,  我要讓WR位的頻率在100kHz , 這樣寫入頻率可以在100KHz , 所以我t1與t2用延遲5us


我運用 _NOP(); 做 t1 = t2 的延遲5us , 我MCLK=2MHz , 用示波器去查看當P1.0由高電平變成低電平的時間是否為5us , 如下程式碼

void delay_5us(void)  
{   
  P1OUT=0x01;  
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  P1OUT=0x00;
}

上列程式實際測試為5us


#下面是我寫的HT1621命令模式程式碼

void HT1621Cmd(uchar CmdValue)
{
  uchar i;
  uchar value = COMMAND_ID;  //COMMAND_ID=0x80;
  CS_OFF;         //CS=0
  delay_5us();   
  for( i = 0; i < 12;  i++ )
   {
     if(i==3)
         value = CmdValue;
     WR_OFF;
     delay_5us();
     if((value&0x80)==0)
      {
        DATA_OFF;
        delay_5us();
      }  
     else
      {
       DATA_ON;
       delay_5us();
      }       
     WR_ON;
     delay_5us();
     value<<=1;
   }
   CS_ON;         //CS=1
   delay_5us();  
}



我有接示波器去看 WR 與 DATA 整個時序的對應沒有問題 , 但是t1與t2的時間不是5us , 而是 t1 = 14us , t2 = 20us , 請問為什麼不是5us呢?

因為我之後有要寫I2C介面 , 如果用 I/O 翻轉電平方式模擬 I2C 時序 , 上面延遲時間方式(如delay_5us)依需求設定好延遲時間 , 但實際帶入時序運用時,實際延遲時間卻不同 , 這樣就不能達到自己需求的 I2C 寫入頻率,也會遇到上面延遲問題,希望能解決此問題.

麻煩大家看一下,是哪裡有問題呢? 謝謝




  • 建议看一下编译过程生成的汇编代码,看看翻转io器件都干了什么,就知道原因了。

  • dirtwillfly  您好

    請問是在調試介面下點選 view / disassembly 嗎?

    如果是這個我有用單步執行方式查看每步執行流程
     
    下面是HT1621Cmd程式段 , 我從disassembly內複製過來


    void HT1621Cmd(uchar CmdValue)
    {
    HT1621Cmd:
     001228    120A               push.w  R10
     00122A    120B               push.w  R11
     00122C    1208               push.w  R8
     00122E    4C4A               mov.b   R12,R10
      uchar value = COMMAND_ID;
     001230    4078 0080          mov.b   #0x80,R8
      CS_OFF;         //CS=0
     001234    C2F2 0021          bic.b   #0x8,&P1OUT
      delay_5us();   
     001238    12B0 1324          call    #delay_5us
      for( i = 0; i < 12;  i++ )
     00123C    434B               clr.b   R11
     00123E    3C0A               jmp     0x1254
           DATA_ON;     
     001240    D3D2 0021          bis.b   #0x1,&P1OUT
           delay_5us();
     001244    12B0 1324          call    #delay_5us
         WR_ON;
     001248    D3E2 0021          bis.b   #0x2,&P1OUT
         delay_5us();
     00124C    12B0 1324          call    #delay_5us
         value<<=1;
     001250    5848               rla.b   R8
      for( i = 0; i < 12;  i++ )
     001252    535B               inc.b   R11
      for( i = 0; i < 12;  i++ )
     001254    907B 000C          cmp.b   #0xC,R11
     001258    2C0F               jc      0x1278
         if(i==3)
     00125A    907B 0003          cmp.b   #0x3,R11
     00125E    2001               jne     0x1262
             value = CmdValue;
     001260    4A48               mov.b   R10,R8
         WR_OFF;
     001262    C3E2 0021          bic.b   #0x2,&P1OUT
        delay_5us();
     001266    12B0 1324          call    #delay_5us
         if((value&0x80)==0)  //0x80作為取得一整個位元組的最高位元之運算值
     00126A    9348               tst.b   R8
     00126C    3BE9               jl      0x1240
           DATA_OFF;    
     00126E    C3D2 0021          bic.b   #0x1,&P1OUT
           delay_5us();
     001272    12B0 1324          call    #delay_5us
     001276    3FE8               jmp     0x1248
       CS_ON;         //CS=1
     001278    D2F2 0021          bis.b   #0x8,&P1OUT
       delay_5us();  
     00127C    12B0 1324          call    #delay_5us
    }
     
    --------------------------------------------------------------------------------------

    下面是delay_5us()程式段 , 我從disassembly內複製過來

    {
    __exit:
     001312    8321               decd.w  SP
     001314    4C0A               mov.w   R12,R10
        p.mStatus = status;
     001316    4A81 0000          mov.w   R10,0x0(SP)
        __DebugBreak(__Debug__Exit, &p);
     00131A    410D               mov.w   SP,R13
     00131C    435C               mov.b   #0x1,R12
     00131E    12B0 134A          call    #__DebugBreak
     001322    3FF9               jmp     0x1316
      _NOP();
    delay_5us:
     001324    4303               nop
      _NOP();
     001326    4303               nop
      _NOP();
     001328    4303               nop
      _NOP();
     00132A    4303               nop
      _NOP();
     00132C    4303               nop
      _NOP();  //6個NOP
     00132E    4303               nop
    }

    ----------------------------------------------------------------------------------

    從上面兩段匯編程式段 , 我查看下列這些I/O口對應的匯編代碼如下

    CS_ON     //P1.3輸出高電平  對應  ==>  bis.b   #0x8,&P1OUT  ==>  對應 C 語言  #define CS_ON       P1OUT |=0x08
    CS_OFF    //P1.3輸出低電平  對應  ==>  bic.b   #0x8,&P1OUT  ==>  對應 C 語言  #define CS_OFF      P1OUT &=~(0x08)
    DATA_ON   //P1.0輸出高電平  對應  ==>  bis.b   #0x1,&P1OUT  ==>  對應 C 語言  #define DATA_ON     P1OUT |=0x01
    DATA_OFF  //P1.0輸出低電平  對應  ==>  bic.b   #0x1,&P1OUT  ==>  對應 C 語言  #define DATA_OFF    P1OUT &=~(0x01)
    WR_ON     //P1.1輸出高電平  對應  ==>  bis.b   #0x2,&P1OUT  ==>  對應 C 語言  #define WR_ON       P1OUT |=0x02
    WR_OFF    //P1.1輸出低電平  對應  ==>  bic.b   #0x2,&P1OUT  ==>  對應 C 語言  #define WR_OFF      P1OUT &=~(0x02)

    由於我不會匯編語言,我查了下面這兩個指令的意思

    bis 是做OR運算
    bic 先做NOT運算再做AND運算

    這與我用C語言寫的意思一樣 , 另外在單步執行時進入delay_5us後 , 去執行6個NOP後就跳出 , 感覺程式沒有做其他的事,I/O的翻轉也正常,再請dirtwillfly,您看一下是什麼問題,或是建議,謝謝您

  • 之前没仔细看你的程序。你要求的是t1要5uS,也就是WR的下降沿和上升沿之间是5uS。

    但你看:

    WR_OFF;
         delay_5us();
         if((value&0x80)==0) 
          { 
            DATA_OFF; 
            delay_5us();
          }  
         else 
          {
           DATA_ON;
           delay_5us();
          }       
         WR_ON;

    WR_OFF下降沿之后,先延时5us,然后在if else语句里又延时5us,所有等WR_ON的时候,至少延时了10uS。

  • dirtwillfly  您好

    謝謝您幫忙 , 我delay確實有多加 , 但是我這邊把delay_5us都刪掉 , 如下圖黃色部分都刪掉

    黃色部分刪掉後我測量WR如下圖t1與t2時間

    MCLK = 2MHz下 , t1 = 8.8us ,t2 = 6.8us , 仍無法達到我所需求的5us , 請問是MCLK速度不夠快嗎?


    我有試著將MCLK改為4.9MHz , 在黃色部分也刪掉的情況下 , 實測發現t1 = 3.6us ,t2 = 2.8us , 比我需求的5us還要快

    請問這樣的結果是不是表示原先的MCLK速度不夠快呢? 再請您看一下 , 謝謝您

  • 是的。mclk不够快

  • dirtwillfly  您好

    謝謝您幫忙 , 謝謝!