我正在尝试调试我为 NXP LPC1850 评估板编写的一些软件。目前,当我停止我的代码时,我看不到它在我的 C 代码中的位置,但我可以在反汇编程序窗口中看到。
它挂在的行位于地址 0x40。指令是 BN 。我在 ARM Information Center 上查找过它,但我对汇编程序一无所知,恐怕即使在阅读之后,它对我来说也毫无意义。
0x0: 0x9ff0 LDR R7, [SP, #0x3c0]
0x2: 0x1008 ASRS R0, R1, #32
0x4: 0x2bad CMP R3, #173 ; 0xad
0x6: 0x1040 ASRS R0, R0, #1
0x8: 0x0041 LSLS R1, R0, #1
0xa: 0x1040 ASRS R0, R0, #1
0xc: 0x0043 LSLS R3, R0, #1
0xe: 0x1040 ASRS R0, R0, #1
0x10: 0x0045 LSLS R5, R0, #1
0x12: 0x1040 ASRS R0, R0, #1
0x14: 0x0047 LSLS R7, R0, #1
0x16: 0x1040 ASRS R0, R0, #1
0x18: 0x0049 LSLS R1, R1, #1
0x1a: 0x1040 ASRS R0, R0, #1
0x1c: 0x0000 MOVS R0, R0
0x1e: 0x0000 MOVS R0, R0
0x20: 0x0000 MOVS R0, R0
0x22: 0x0000 MOVS R0, R0
0x24: 0x0000 MOVS R0, R0
0x26: 0x0000 MOVS R0, R0
0x28: 0x0000 MOVS R0, R0
0x2a: 0x0000 MOVS R0, R0
0x2c: 0x004b LSLS R3, R1, #1
0x2e: 0x1040 ASRS R0, R0, #1
0x30: 0x004d LSLS R5, R1, #1
0x32: 0x1040 ASRS R0, R0, #1
0x34: 0x0000 MOVS R0, R0
0x36: 0x0000 MOVS R0, R0
0x38: 0x004f LSLS R7, R1, #1
0x3a: 0x1040 ASRS R0, R0, #1
0x3c: 0x1645 ASRS R5, R0, #25
0x3e: 0x1040 ASRS R0, R0, #1
0x40: 0xe7fe B.N 0x40
0x42: 0xe7fe B.N 0x42
0x44: 0xe7fe B.N 0x44
0x46: 0xe7fe B.N 0x46
0x48: 0xe7fe B.N 0x48
0x4a: 0xe7fe B.N 0x4a
0x4c: 0xe7fe B.N 0x4c
0x4e: 0xe7fe B.N 0x4e
0x50: 0x0000 MOVS R0, R0
0x52: 0x0000 MOVS R0, R0
0x54: 0x0000 MOVS R0, R0
0x56: 0x0000 MOVS R0, R0
0x58: 0x0000 MOVS R0, R0
0x5a: 0x0000 MOVS R0, R0
0x5c: 0x0000 MOVS R0, R0
0x5e: 0x0000 MOVS R0, R0
如果有人能解释发生了什么以及为什么程序在那时挂起,我将非常感激。
编辑:在下面添加了 C 代码
#include "NXP\iolpc4350.h"
#include "stdint.h"
#include "modules\i2c_drv.h"
#include "modules\drv_nvic.h"
#define IRC_FREQ 12000000
#define XTAL_FREQ 12000000
//nt32_t ClockFrequency;
uint32_t I2C0_PCLK;
unsigned char Data[2];
#define MULTF 15
#define PCA9502_ADDR 0x4D
volatile uint8_t flag0=0;
#define flTick ( flag0 )
#define flTickSet() ( flag0 = 0xFF )
#define flTickClear() ( flag0 = 0x00 )
/*************************************************************************
* Function Name: InitClock
* Parameters: none
*
* Return: none
*
* Description: Initialize PLL and clock dividers. FCCO = 320MHz,
* PLL1_OUT = 160MHz
*
*************************************************************************/
void InitClock(void)
{
/* 1. Init XTAL OSC */
CGU_XTAL_OSC_CTRL_bit.HF = 0; /* Xtal.freq is between 1MHz and 15MHZ */
CGU_XTAL_OSC_CTRL_bit.BYPASS = 0; /* Xtal.osc is connected */
CGU_XTAL_OSC_CTRL_bit.ENABLE = 0; /* Xtal.osc is enabled */
/* 2. Wait for OSC ready > 2ms */
for(volatile uint32_t j = 20000; j; j--);
/* 3. Switch to OSC clk */
/* BASE_M4_CLK */
CGU_BASE_M4_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_APB1_CLK */
CGU_BASE_APB1_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_APB3_CLK */
CGU_BASE_APB3_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_SPIFI_CLK */
CGU_BASE_SPIFI_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* 4. Init PLL1 - In clk - OSC (12MHz)
N = 3, M = 80, P = 1 VCO - 320MHz, PLL1 OUT - 160MHz */
CGU_PLL1_CTRL_bit.PD = 1; /* Power down PLL1 */
CGU_PLL1_CTRL_bit.BYPASS = 0; /* CCO clock sent to post-dividers */
CGU_PLL1_CTRL_bit.DIRECT = 0; /* Direct CCO output disabled */
CGU_PLL1_CTRL_bit.FBSEL = 0; /* CCO output as feedback divider */
CGU_PLL1_CTRL_bit.PSEL = 1-1; /* Post divider P = 1 */
CGU_PLL1_CTRL_bit.NSEL = 3-1; /* N = 3 */
CGU_PLL1_CTRL_bit.MSEL = 80-1; /* M = 80 */
CGU_PLL1_CTRL_bit.CLK_SEL = 6; /* Source is XTAL osc. */
CGU_PLL1_CTRL_bit.AUTOBLOCK = 1; /* Autoblock during freq.change enabled */
/* 5. Enable PLL1 */
CGU_PLL1_CTRL_bit.PD = 0; /* Power up (enable) PLL1 */
/* 5. Wait for the PLL1 to achieve lock */
while(!CGU_PLL1_STAT_bit.LOCK);
/* 6. Dividers */
/* IDIVA - /4 input 160MHz, output 40MHz */
CGU_IDIVA_CTRL_bit.AUTOBLOCK = 1; /* Autoblock during freq.change enabled */
CGU_IDIVA_CTRL_bit.IDIV = 4-1; /* IDIV = 4 */
CGU_IDIVA_CTRL_bit.CLK_SEL = 9; /* Source is PLL1 */
CGU_IDIVA_CTRL_bit.PD = 0; /* Enable IDIVA */
/* 7. Init Clock output stages */
/* BASE_M4_CLK, APB0, APB2 - 160MHz */
CGU_BASE_M4_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (9ul << 24) /* Source is PLL1 */
;
/* BASE_APB1_CLK - 160MHz*/
CGU_BASE_APB1_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (9ul << 24) /* Source is PLL1 */
;
/* BASE_SPIFI_CLK - 40MHz */
CGU_BASE_SPIFI_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (12ul << 24) /* Source is IDIVA */
;
/* Enable M4 Bus clock */
CCU1_CLK_M4_BUS_CFG_bit.RUN = 1;
/* Enable APB 1 Bus clock */
CCU1_CLK_APB1_BUS_CFG_bit.RUN = 1;
/* Enable SCU clock */
CCU1_CLK_M4_SCU_CFG_bit.RUN = 1;
/* Set I2C0 module frequency = APB1 freq */
I2C0_PCLK = 160000000;
}
/*************************************************************************
* Function Name: RIT_IRQHandler
* Parameters: none
*
* Return: none
*
* Description: Repetitive interrupt timer handler
*
*************************************************************************/
void RITIMER_IRQHandler(void)
{
flTickSet();
/* Clear interrupt */
RIT_CTRL_bit.RITINT = 1;
NVIC_ClearPendingIRQ(NVIC_RITIMER);
}
/*************************************************************************
* Function Name: RIT_Init
* Parameters: none
*
* Return: none
*
* Description: Initialization of repetitive interrupt timer
*
*************************************************************************/
void RITIMER_Init(void)
{
/* Value for 0.25s timer interrupt @ 180MHz timer clock */
RIT_COUNTER = 0;
RIT_COMPVAL = 0x2AEA540;
RIT_CTRL_bit.RITEN = 1;
RIT_CTRL_bit.RITENCLR = 1;
/* Enable interrupt */
NVIC_EnableIRQ(NVIC_RITIMER);
NVIC_SetPriority(NVIC_RITIMER, 16);
}
/*************************************************************************
* Function Name: main
* Parameters: none
*
* Return: none
*
* Description: main
*
*************************************************************************/
int main()
{
// Configures Clock Generation Unit
InitClock();
// Force a RESET to Cortex-M0
RGU_RESET_CTRL1 = ~RGU_RESET_ACTIVE_STATUS1 | RGU_RESET_CTRL1_M0APP_RST;
// Configures Repetitve Interrupt Timer
RITIMER_Init();
// Configure the onboard LED - GPIO4.1
GPIO_CLR4 = 1 << 1;
GPIO_DIR4 |= 1 << 1;
// Init I2C
I2C_InitMaster(400000);
// Everything below this line I have added in myself - Mitchell
/* Configure PC_11 and PC_12 to serve as
GPIO6[10] and GPIO6[11] to act as data select
for SPP0_SSEL multiplexer
1. Set as outputs
2. Choose INTLCD_SSEL (option 0) as output by clearing both outputs
3. Configure both pins as GPIO
*/
// 1
GPIO_DIR6 |= 0x0C;
// 2
GPIO_PIN6 &= ~0x0C;;
// 3
SCU_SFSPC_11_bit.MODE = 4;
SCU_SFSPC_12_bit.MODE = 4;
// Set LCD_RST to reset the LCD
RGU_RESET_CTRL0 |= RGU_RESET_CTRL0_LCD_RST;
// LCD_RST autoclears when complete
// wait until this done before moving on
while(RGU_RESET_STATUS1_bit.LCD_RST == 1);
/* SPI slave select is an active low signal.
This means that to communicate with the onboard LCD,
SSP0_SSEL must be cleared
*/
while(1)
{
}
}