c - 困惑 - 代码可以编译,但微 Controller 端没有任何反应。我怀疑 ISR 中的某些内容可能是罪魁祸首

标签 c msp430 iar

我的任务是采用我的导师用汇编语言编写的功能程序并将其转换为 C 语言。该程序是为 TI MSP430G2553 编写的,并使用带有三个并排按钮的附加 4 位 LED 显示屏。显示屏应该开始空白。当按下右侧按钮时,“ECE-3362”将开始在显示屏上从右向左滚动。

据我所知,我的转换是“完整的”,并且代码编译时没有错误。但是,按钮没有任何可见效果,并且显示屏保持空白。

我确实收到了一些“整数转换导致截断”警告,但我不确定这对程序功能的影响。至多我会认为,如果我的常量定义的一部分被截断,这会导致显示显示错误的值。

我的代码中特别可疑的部分是最底部的 port2 中断服务例程(主要是 PB 和 P2_IFG 比较)。我没有完全理解我的讲师汇编版本中该部分的内容,因此翻译中可能丢失了一些重要的内容。

我对一般的汇编以及微 Controller 方面的 C 都是新手。我非常依赖我的导师的示例代码作为引用。我将把我的代码放在下面,如果有人想看的话,我手头上有我的教练的代码。

我知道规则规定不要发布整个文件,但据我所知,我可能会在程序的任何地方出现错误或更多错误。

我的代码:

#include  <msp430g2553.h>
//-----------------------------------------------------------------------------
// Definition of Constants
//-----------------------------------------------------------------------------

#define TIMER_A0_COUNT_1 2000     //2000
#define TIMER_A1_COUNT_1 50000   //50000

#define MAX_TIMER_COUNT 10       //10

#define LONG_DELAY (0xFFFF)          //65535

//definitions of segment positions 
#define SEG_A  (0x01u)   // 00000001  Port pin position P1.0
#define SEG_B  (0x02u)   // 00000010  Port pin position P1.1
#define SEG_C  (0x04u)   // 00000100  Port pin position P1.2
#define SEG_D  (0x08u)   // 00001000  Port pin position P1.3
#define SEG_E  (0x10u)   // 00010000  Port pin position P1.4
#define SEG_F  (0x20u)   // 00100000  Port pin position P1.5
#define SEG_G  (0x40u)   // 01000000  Port pin position P1.6
#define SEG_DP (0x80u)   // 10000000  Port pin position P1.7

//since inverted pattern is needed for the display, this defines inverse pattern
#define SEG_A_N           ~SEG_A  // Port pin position P1.0
#define SEG_B_N           ~SEG_B  // Port pin position P1.1
#define SEG_C_N           ~SEG_C  // Port pin position P1.2
#define SEG_D_N           ~SEG_D  // Port pin position P1.3
#define SEG_E_N           ~SEG_E  // Port pin position P1.4
#define SEG_F_N           ~SEG_F  // Port pin position P1.5
#define SEG_G_N           ~SEG_G  // Port pin position P1.6
#define SEG_DP_N          ~SEG_DP // Port pin position P1.7

//NOTE: display board requires INVERSE of these patterns due to Active LOW
#define DIG_3  (0x01u)    //   00000001  Port pin position P2.0 (MSdigit)
#define DIG_2  (0x02u)    //   00000010  Port pin position P2.1
#define DIG_1  (0x04u)    //   00000100  Port pin position P2.2
#define DIG_0  (0x08u)    //   00001000  Port pin position P2.3(LSdigit)
#define DP_COM (0x10u)    //   00010000  Port pin position P2.4

//since inverted pattern is needed for the display, this defines inverse pattern
#define DIG_3_N      ~DIG_3  // Port pin position P2.0 (MSdigit)
#define DIG_2_N      ~DIG_2  // Port pin position P2.1
#define DIG_1_N      ~DIG_1  // Port pin position P2.2
#define DIG_0_N      ~DIG_0  // Port pin position P2.3(LSdigit)
#define DP_COM_N     ~DP_COM // Port pin position P2.4


//Pushbutton assignments CORRECTED to compensate for board layout swap
#define PB_0  (0x20u)     //  00100000  Port pin position P2.5  RightMost button
#define PB_1  (0x80u)     //  10000000  Port pin position P2.7  Middle button
#define PB_2  (0x40u)     //  01000000  Port pin position P2.6  LeftMost button

#define SEG_PORT  P1OUT
#define DIG_PORT  P2OUT
#define PB_PORT   P2IN

//NOTE: display bd requires the INVERSE of these patterns due to Active LOW
#define ONE                (0x06u) // 00000110
#define TWO                (0x5Bu) // 01011011
#define THREE              (0x4Fu) // 01001111
#define FOUR               (0x66u) // 01100110
#define FIVE               (0x6Du) // 01101101
#define SIX                (0x7Du) // 01111101
#define SEVEN              (0x03u) // 00000111
#define EIGHT              (0x7Fu) // 01111111
#define NINE               (0x67u) // 01100111
#define ZERO               (0x3Fu) // 00111111

//since inverted pattern is needed for the display, this defines inverse pattern
#define ONE_N        (~0x06u)       // ~00000110
#define TWO_N        (~0x5Bu)       // ~01011011
#define THREE_N      (~0x4Fu)       // ~01001111
#define FOUR_N       (~0x66u)       // ~01100110
#define FIVE_N       (~0x6Du)       // ~01101101
#define SIX_N        (~0x7Du)       // ~01111101
#define SEVEN_N      (~0x03u)       // ~00000111
#define EIGHT_N      (~0x7Fu)       // ~01111111
#define NINE_N       (~0x67u)       // ~01100111
#define ZERO_N       (~0x3Fu)       // ~00111111

//other figures for scrolling display
#define E_N          (~0x79u)    //  ~01111001
#define C_N          (~0x39u)    //  ~00111001
#define DASH_N       (~0x40u)    //  ~01000000
#define BLANK_N      (~0x00u)    //  ~00000000



//------------------------------------------------------------------------------
// Definition of Variables
//------------------------------------------------------------------------------

int DisplayValue  =  0;         // contains 4 digit value to display in BCD format
                                // BCDdig3 | BCDdig2  | BCDdig1  | BCDdig0
                                // xxxx      xxxx       xxxx       xxxx

char CurrentDigitPos  =  0;     // global variable used by WriteDigitToDisplay ISR
                                // holds digit position of current digit to write

char CurrentDigitValue = 0;     // global variable used by WriteDigitToDisplay ISR
                                // holds digit value of next digit to write    
char StartFlag     =   0;       // Boolean state flags
char PauseFlag     =   0;
char ContinueFlag  =   0;
char ScrollingStateFlag  =  0;

char PB_0_Mode       =   0;
char PB_1_Mode       =   0;
char PB_2_Mode       =   0;

char Hundred_mS      =   0;
char TotalINTCount1  =   0;

int PatternsToScroll[12] = {0x0000, 0x0006, 0x0065, 0x0656, 0x6561, 0x5613, 
0x6133, 0x1334, 0x3342, 0x3420, 0x4200, 0x2000};

char PatternsIndex = 0;
int CurrentPattern = 0;
char PatternsLeft = 12;

char SegPatterns[7] = {BLANK_N, DASH_N, TWO_N, THREE_N, SIX_N, C_N, E_N};

//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
void WriteNextDigitToDisplay(int DisplayValue, char CurrentDigitPos, char CurrentDigitValue)
{
  int DisplayValueCopy = 0; // initialize function variable

  DIG_PORT |= DIG_0+DIG_1+DIG_2+DIG_3+DP_COM; // eliminate ghosting

  if ((CurrentDigitPos - 0) == 0)
  {
    DisplayValueCopy = DisplayValue;
    DisplayValueCopy &= 0x000F;
    SEG_PORT = SegPatterns[DisplayValueCopy];
    DIG_PORT = DIG_0_N;
    CurrentDigitPos++;
  }

  if ((CurrentDigitPos - 1) == 0)
  {
    DisplayValueCopy = DisplayValue;
    DisplayValueCopy &= 0x00F0;
    DisplayValueCopy >>=4;               //rra 4 times to get val into LSnibble
    SEG_PORT = SegPatterns[DisplayValueCopy];
    DIG_PORT = DIG_1_N;
    CurrentDigitPos++;
  }

  if ((CurrentDigitPos - 2) == 0)
  {
    DisplayValueCopy = DisplayValue;
    DisplayValueCopy &= 0x0F00;
    DisplayValueCopy = __swap_bytes(DisplayValueCopy);
    SEG_PORT = SegPatterns[DisplayValueCopy];
    DIG_PORT = DIG_2_N;
    CurrentDigitPos++;
  }

  if ((CurrentDigitPos - 3) == 0)
  {
    DisplayValueCopy = DisplayValue;
    DisplayValueCopy &= 0xF000;
    DisplayValueCopy = __swap_bytes(DisplayValueCopy);
    DisplayValueCopy >>=4;
    SEG_PORT = SegPatterns[DisplayValueCopy];
    DIG_PORT = DIG_3_N;
    CurrentDigitPos++;
  }

  if ((CurrentDigitPos - 4) == 0)
  {
    CurrentDigitPos = 0;
  }
}

void delay()
{
  for (int i = 0; i < LONG_DELAY; i++);
}

int main( void )
{
  //---------------------------------------------------------------------------
  // Setup
  //---------------------------------------------------------------------------

  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  // Setup Port 1 (all outputs for segment display)
  P1DIR = SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G + SEG_DP;

  // Setup Port 2 
  P2DIR = 0x1F; // (00011111 : 3MSbits as inputs (pushbuttons) 5LSbits as outputs)
  P2OUT = PB_0 + PB_1 + PB_2;  // 11100000 or 0xE0 defines pushbutton positions
  P2REN |= PB_0 + PB_1 + PB_2; // turn on internal pull-up for the pushbuttons

  // Activate the General Purpose Digital I/O mode for P2.6 and P2.7
  P2SEL &= ~PB_1 + ~PB_2;     

  // Setup Port 2 interrupts for the pushbuttons
  P2IE |= PB_0 + PB_1 + PB_2;
  P2IES |= PB_0 + PB_1 + PB_2;

  // Turn off all the segments and digits
  SEG_PORT = 0xFF;
  DIG_PORT = 0xFF;

  // SetupCalibratedClock       
  // Set up the clock (calibrated mode at 1 MHz)
  // Get the calibrated data for the DCO clock
  // Set DCO to 1 MHz:  (this directly from TI Family Guide page283 and 284
          DCOCTL = 0;                // Select lowest DCOx  and MODx settings
          BCSCTL1 = CALBC1_1MHZ;     // Set range
          DCOCTL = CALDCO_1MHZ;      // Set DCO step + modulation     

  // Set up Timers

  // TimerA0
  TA0CCR0 = TIMER_A0_COUNT_1;              // load a count "up to"value into timer
  TA0CTL = TASSEL_2+ID_3 + MC_1;        // SMCLK, input div = 8, upmode
  TA0CCTL0 = CCIE;                        //  interrupt enabled for Timer0

  // TimerA1
  TA1CCR0 = TIMER_A1_COUNT_1;              // load a count "up to"value into timer
  TA1CTL = TASSEL_2+ID_3 + MC_1;        // SMCLK, input div = 8, upmode
  TA1CCTL0 = CCIE;                        //  interrupt enabled for Timer1 

  // Start of main program   

  // Initialize Boolean state flags and some other variables
            StartFlag = 0;
            PauseFlag = 0;
            ContinueFlag = 0;
            ScrollingStateFlag  = 0;
            PB_0_Mode = 0;      
            PB_1_Mode = 0; 
            PB_2_Mode = 0;   

            DisplayValue = 0;  


  // Clear Interrupt Flags
           P1IFG = 0;    // clear the Int flag register for Port 1 
           P2IFG = 0;    // clear the Int flag register for Port 2 

  // Enable General Interrupts
            _BIS_SR(GIE);         // enable the general interrupts bit   

  //----------------------------------------------------------------------------
  // Top of main program loop structure
  //----------------------------------------------------------------------------  

    while(1)  // forever loop
    {

      // test the Pushbutton mode Boolean variables to see what to do 
      if ((PB_0_Mode - 1) == 0) // (START CONDITION)
      {
        // Rightmost button (START)
        PB_0_Mode = 0;
        ScrollingStateFlag = 1; // make it TRUE
        PatternsIndex = 0; // beginning of pattern array
        PatternsLeft = 12;
        CurrentPattern = PatternsToScroll[PatternsIndex]; // might be redundant
      }

      if ((PB_1_Mode - 1) == 0) // (CONTINUE CONDITION)
      {
        // Middle button (CONTINUE)
        PB_1_Mode = 0;
        ScrollingStateFlag = 1; // make it TRUE
      }

      if ((PB_2_Mode - 1) == 0) // (PAUSE CONDITION)
      {
        // Leftmost button (PAUSE)
        PB_2_Mode = 0;
        ScrollingStateFlag = 0; // make it FALSE
      }

      else
      {
        if ((ScrollingStateFlag - 1) == 0)
        {
         CurrentPattern = PatternsToScroll[PatternsIndex];
         DisplayValue = CurrentPattern; // save pattern array element
         PatternsIndex++;               // move to next element
         PatternsLeft--;                // one less pattern to display
         if ((PatternsLeft - 0) == 0)   // done all the patterns --> reset variables
         {
           PatternsIndex = 0;
           CurrentPattern = PatternsToScroll[PatternsIndex]; // might be redundant
           PatternsLeft = 12;
         }
         delay();   // update the scrolling slowly
         delay();        
        }
      }
    }





            return 0;
} // end of MAIN

//------------------------------------------------------------------------------
//           Subroutines
//------------------------------------------------------------------------------

//-------------------------------------------------------------------------------
// WriteNextDigitToDisplay
//  passed in - DisplayValue, CurrentDigitPos 
//  returned - nothing
//  accomplishes - Writes next digit to the expansion bd display
//  uses: R15, global variable CurrentDigitPos, CurrentDigitValue
//-------------------------------------------------------------------------------

//-------------------------------------------------------------------------------
//          Interrupt Service Routines
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Interrupt Service Routine for Timer_A 1
//  Passed in: nothing
//  Activated every time TimerA_1 times out
//  Updates global variable TotalINTCount1 to keep track of number of TimerA_1 
//   interrupt events
//  Uses: nothing except modifies global variable TotalINTCount
//  For this example, set up to trigger every 100 mS
//-------------------------------------------------------------------------------
//Timer0_A0 ISR
#pragma vector=TIMER0_A0_VECTOR   // this line tells the C compiler to put
                                  // the start address of the following ISR
                                  // into the Interupt Vector table

__interrupt void Timer_A0_ISR (void)   // required syntax for first line of ISR
{
  WriteNextDigitToDisplay(DisplayValue, CurrentDigitPos, CurrentDigitValue);
}

//Timer0_A1 ISR
#pragma vector=TIMER1_A1_VECTOR   // this line tells the C compiler to put
                                  // the start address of the following ISR
                                  // into the Interupt Vector table

__interrupt void Timer_A1_ISR (void)   // required syntax for first line of ISR
{
  Hundred_mS++;
  TotalINTCount1++;
}

// Port2_ISR
//  passed in - nothing
//  returned - nothing
//  accomplishes - updates global Boolean variables for Pushbutton status
//  uses: nothing
//-------------------------------------------------------------------------------
//Port2_ISR
    // if we get to here, an interrupt occurred on the Port 2
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  if ((PB_0 & P2IFG) == 1)
  {
    PB_0_Mode |= 1;
    PB_1_Mode &= ~1;
    PB_2_Mode &= ~1;
  }

  if ((PB_1 & P2IFG) == 1)
  {
    PB_0_Mode &= ~1;
    PB_1_Mode |= 1;
    PB_2_Mode &= ~1;
  }

  if ((PB_2 & P2IFG) == 1)
  {
    PB_0_Mode &= ~1;
    PB_1_Mode &= ~1;
    PB_2_Mode |= 1;
  }

  P2IFG = 0;
}

由于字符限制,无法发布讲师的完整代码。这是他的端口 2 ISR:

; Port2_ISR
;  passed in - nothing
;  returned - nothing
;  accomplishes - updates global Boolean variables for Pushbutton status
;  uses: nothing
;-------------------------------------------------------------------------------
Port2_ISR
    ; if we get to here, an interrupt occurred on the Port 2
    bit.b  #PB_0, &P2IFG   ; PB_0 Pushbutton?  (if 1 it is pressed)
    jnz  PB_0_Case        ; it is PB_0
    ;no so try the next case

    bit.b  #PB_1, &P2IFG   ; PB_1 Pushbutton?  (if 1 it is pressed)
    jnz  PB_1_Case        ; it is PB_1
    ;no so try the next case

    bit.b  #PB_2, &P2IFG   ; PB_2 Pushbutton?  (if 1 it is pressed)
    jnz  PB_2_Case        ; it is PB_2
    jmp  DoneWithPort_2_ISR       ; no, so don't do anything

PB_0_Case
    bis.b  #1,  &PB_0_Mode 
    bic.b  #1,  &PB_1_Mode   ;clear other modes
    bic.b  #1,  &PB_2_Mode        
    jmp DoneWithPort_2_ISR

PB_1_Case
    bis.b  #1,  &PB_1_Mode
    bic.b  #1,  &PB_0_Mode   ;clear other modes
    bic.b  #1,  &PB_2_Mode        
    jmp DoneWithPort_2_ISR    

PB_2_Case
    bis.b  #1,  &PB_2_Mode
    bic.b  #1,  &PB_1_Mode   ;clear other modes
    bic.b  #1,  &PB_0_Mode        
    jmp DoneWithPort_2_ISR    

DoneWithPort_2_ISR   
    clr.b &P2IFG    ; clear the flag so system is ready for another interrupt

    reti         ; return from interrupt
;-------------------------------------------------------------------------------
;  end of Port2_ISR
;-------------------------------------------------------------------------------


;-------------------------------------------------------------------------------

最佳答案

您已将所有 PB_N_MODE 设置为 0,并检查这些值减去 1 是否等于 0,您不能将它们设置为 1 或者检查它们是否等于 -1 吗?

PB_1_MODE = 1
PB_2_MODE = 1
...

关于c - 困惑 - 代码可以编译,但微 Controller 端没有任何反应。我怀疑 ISR 中的某些内容可能是罪魁祸首,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55739952/

相关文章:

c - 在 STM32L0 上的 IAR 中初始化 Eeprom

arm - 在没有 IAR 的情况下将 IAR 输出写入 ARM 芯片

c - C语言中如何找到数组中最大值的位置

无法从读取文件中获取准确的十六进制值

c - pthreads 内存泄漏

c - K60 系列 GPIO 键盘(C 语言)

c++ - JNA 指针到指针

timer - MSP 430G2553 使用 Timer_A 在比较模式下进行采样

cmake - 如何通过编译标志来进行初始编译器测试?

c++ - 无法打开源文件 "limits"