TA的每日心情 | 开心 2017-1-11 04:03 |
---|
签到天数: 3 天 连续签到: 1 天 [LV.2]偶尔看看I
|
前言
为了使用PmodRF2
我先试用MCU来驱动PmodRF2
使用的LPC 54102, 板卡配备Pmod接口。
这里记录使用lpcxpresso开发的过程。
主体
安装好lpcxpresso IDE开发环境
其次
导入
下载好LPC54102的固件包不用解压
lpcopen_v2_00_lpcxpresso_nxp_lpcxpress_54102.zip
然后select all
然后
如图选择peripheral——blinky
和下方的start here pannel中的build
build完成之后,我们要进行Debug。同样在下方的start here pannel选debug即可。前提是安装好驱动。
构建 好之后进入 分析启动过程。
启动记录
cr_startup_lpc5410x.c文件
不管其他的。
直接进入
<span style="font-size: 16px;">__attribute__ ((section(".after_vectors.reset")))void ResetISR(void) {#endif // If this is not the CM0+ core...#if !defined (CORE_M0PLUS) // If this is not a slave project...#if !defined (__MULTICORE_M0SLAVE) && \ !defined (__MULTICORE_M4SLAVE) // Optionally enable RAM banks that may be off by default at reset#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0; // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4);#endif#endif#endif // // Copy the data sections from flash to SRAM. // unsigned int LoadAddr, ExeAddr, SectionLen; unsigned int *SectionTableAddr; // Load base address of Global Section Table SectionTableAddr = &__data_section_table; // Copy the data sections from flash to SRAM. while (SectionTableAddr < &__data_section_table_end) { LoadAddr = *SectionTableAddr++; ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; data_init(LoadAddr, ExeAddr, SectionLen); } // At this point, SectionTableAddr = &__bss_section_table; // Zero fill the bss segment while (SectionTableAddr < &__bss_section_table_end) { ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; bss_init(ExeAddr, SectionLen); }#if !defined (__USE_LPCOPEN)// LPCOpen init code deals with FP and VTOR initialisation#if defined (__VFP_FP__) && !defined (__SOFTFP__) /* * Code to enable the Cortex-M4 FPU only included * if appropriate build options have been selected. * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) */ // CPACR is located at address 0xE000ED88 asm("LDR.W R0, =0xE000ED88"); // Read CPACR asm("LDR R1, [R0]"); // Set bits 20-23 to enable CP10 and CP11 coprocessors asm(" ORR R1, R1, #(0xF << 20)"); // Write back the modified value to the CPACR asm("STR R1, [R0]");#endif // (__VFP_FP__) && !(__SOFTFP__) // ****************************** // Check to see if we are running the code from a non-zero // address (eg RAM, external flash), in which case we need // to modify the VTOR register to tell the CPU that the // vector table is located at a non-0x0 address. // Note that we do not use the CMSIS register access mechanism, // as there is no guarantee that the project has been configured // to use CMSIS. unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) { // CMSIS : SCB->VTOR = <address of vector table> *pSCB_VTOR = (unsigned int) g_pfnVectors; }#endif#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) SystemInit();#endif#if defined (__cplusplus) // // Call C++ library initialisation // __libc_init_array();#endif#if defined (__REDLIB__) // Call the Redlib library, which in turn calls main() __main();#else main();#endif // // main() shouldn't return, but if it does, we'll just enter an infinite loop // while (1) { ; }}</span>这个代码是启动reset后启动的代码。
最后是while(1) infinite loop
// If this is not the CM0+ core...#if !defined (CORE_M0PLUS) // If this is not a slave project...#if !defined (__MULTICORE_M0SLAVE) && \ !defined (__MULTICORE_M4SLAVE) // Optionally enable RAM banks that may be off by default at reset#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0; // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4);#endif#endif#endif // // Copy the data sections from flash to SRAM. // unsigned int LoadAddr, ExeAddr, SectionLen; unsigned int *SectionTableAddr; // Load base address of Global Section Table SectionTableAddr = &__data_section_table; // Copy the data sections from flash to SRAM. while (SectionTableAddr < &__data_section_table_end) { LoadAddr = *SectionTableAddr++; ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; data_init(LoadAddr, ExeAddr, SectionLen); } // At this point, SectionTableAddr = &__bss_section_table; // Zero fill the bss segment while (SectionTableAddr < &__bss_section_table_end) { ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; bss_init(ExeAddr, SectionLen); }这段代码复制程序到sram
注意这个开sram2
Table 51. AHB Clock Control register 0 (AHBCLKCTRL0, address 0x4000 00C0) bit description
bit | symbol
| descrip | reset value | 0 | - | Reserved. This read-only bit cannot be cleared | . 1 | 1 | rom | Enables the clock for the Boot ROM. 0 = Disable; 1 = Enable | . 1 | 2 | - | Reserved. Read value is undefined, only zero should be written | . 0 | 3 | sram1
| Enables the clock for SRAM1. 0 = Disable; 1 = Enable | 1 | 4 | sram2 | Enables the clock for SRAM2. 0 = Disable; 1 = Enable | 0 | 然后就是初始化了。
#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)SystemInit();#endif/* Set up and initialize hardware prior to call to main */void SystemInit(void){#if defined(__CODE_RED) extern void(*const g_pfnVectors[]) (void); SCB->VTOR = (uint32_t) &g_pfnVectors;#else extern void *__Vectors; SCB->VTOR = (uint32_t) &__Vectors;#endif#if defined(CORE_M4)#if defined(__FPU_PRESENT) && __FPU_PRESENT == 1 fpuInit();#endif#endif#if !defined(__MULTICORE_M0SLAVE) && !defined(__MULTICORE_M4SLAVE)#if defined(NO_BOARD_LIB) /* Chip specific SystemInit */ Chip_SystemInit();#else /* Board specific SystemInit */ Board_SystemInit();#endif#endif} 前边向量表和FPU初始化不管
按F3就好,看这里
/* Sets up system pin muxing */void Board_SetupMuxing(void){ /* Enable IOCON clock */ Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON); Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); /* Bridge SSEL requires detection to set state correctly */ ConfigureBridgeSSEL(); /* IOCON clock left on, this is needed if CLKIN is used. */}/* Set up and initialize clocking prior to call to main */void Board_SetupClocking(void){ /* The IRC is always the first clock source even if CLK_IN is used later. Once CLK_IN is selected as the clock source. We can turned off the IRC later. Turn on the IRC by clearing the power down bit */ Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_IRC_OSC | SYSCON_PDRUNCFG_PD_IRC);#if BOARD_USECLKINSRC == (0) /* Setup PLL based on (internal) IRC clocking */ Chip_SetupIrcClocking(BOARD_MAINCLOCKRATE);#else /* Setup PLL based on (external) CLKIN clocking */ Chip_SetupExtInClocking(BOARD_MAINCLOCKRATE);#endif /* Select the CLKOUT clocking source */ Chip_Clock_SetCLKOUTSource(SYSCON_CLKOUTSRC_MAINCLK, 1);}/* Set up and initialize hardware prior to call to main */void Board_SystemInit(void){ /* Setup system clocking and muxing */ Board_SetupMuxing(); Board_SetupClocking();} 先配置ICON
再看
void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T *pinArray, uint32_t arrayLength){ uint32_t ix; for (ix = 0; ix < arrayLength; ix++ ) { Chip_IOCON_PinMuxSet(pIOCON, pinArray[ix].port, pinArray[ix].pin, pinArray[ix].modefunc); }}这里
这里call它使用
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
LPC_IOCON是 ((LPC_IOCON_T *) 0x4001C000UL)这个可查datasheet
再看PINMUXING 数据
STATIC const PINMUX_GRP_T pinmuxing[] = { /* UART0 */ {0, 0, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART0 RX */ {0, 1, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART0 TX */ /* UART1 */ {0, 5, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART1 RX */ {0, 25, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART1 CTS */ {1, 10, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART1 TX */ {1, 11, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART1 RTS */ /* UART3 */ {1, 12, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART3 TX */ {1, 13, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* UART3 RX */ /* SPI0 (bridge) */ {0, 12, (IOCON_FUNC1 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* BRIDGE_MOSI (SPI MOSI) */ {0, 13, (IOCON_FUNC1 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* BRIDGE_MISO (MISO) */ /* 0, 14 BRIDGE_SSEL is configured in ConfigureBridgeSSEL() */ {1, 3, (IOCON_FUNC5 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* BRIDGE_SCK (SCK) */ {0, 19, (IOCON_FUNC0 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)}, /* BRIDGE_INTR (GPIO) */ {0, 20, (IOCON_FUNC0 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* BRIDGE_GPIO (GPIO) */ /* SPI1 (master) */ {1, 6, (IOCON_FUNC2 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* SPI1_SCK */ {1, 7, (IOCON_FUNC2 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* SPI1_MOSI */ {1, 14, (IOCON_FUNC4 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* SPI1_MISO */ {1, 15, (IOCON_FUNC4 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* SPI1_SSEL0 */ /* I2C0 standard/fast (master) */ {0, 23, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_STDI2C_EN)}, /* I2C0_SCL (SCL) */ {0, 24, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_STDI2C_EN)}, /* I2C0_SDA-WAKEUP (SDA) */ /* I2C1 standard/fast (bridge) */ {0, 27, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_STDI2C_EN)}, /* BRIDGE_SCL (SCL) */ {0, 28, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_STDI2C_EN)}, /* BRIDGE_SDA (SDA) */ /* ADC inputs */ {1, 0, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC3 */ {1, 1, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC4 */ {1, 2, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC5 */ {1, 4, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC7 */ {1, 5, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC8 */ {1, 8, (IOCON_FUNC0 | IOCON_MODE_INACT)}, /* ADC11 */ /* Misc */ {0, 2, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* ARDUINO_INT */ {0, 3, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B1_MAT3 */ {0, 6, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B0_MAT1 */ {0, 7, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B0_MAT2 */ {0, 8, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B0_MAT3 */ {0, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* DMIC_DATA */ {0, 10, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* BTLE_CONN */ {0, 11, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* DMIC_CLKIN */ {0, 21, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CLKOUT-CT32B3_MAT0 */ {0, 26, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* I2C1_SDA-CT32B0_CAP3 */ {1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* BTLE_CMD_DAT */ {1, 16, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B0_MAT0 */ {1, 17, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* IR_LEARN_EN */#if 0 /* Debugger signals, do not touch */ {0, 15, (IOCON_FUNC2 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* SWO */ {0, 16, (IOCON_FUNC5 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* SWCLK_TCK */ {0, 17, (IOCON_FUNC5 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* SWDIO */#endif /* Sensor related */ {0, 4, (IOCON_FUNC0 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* GYR_INT1 (GPIO input) */ {0, 18, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN)}, /* CT32B0_MAT0-ACCL_INT1 */ {0, 22, (IOCON_FUNC0 | IOCON_MODE_PULLDOWN | IOCON_DIGITAL_EN)},/* MAG_DRDY_INT (GPIO input) */ /* LEDs on P0.29, P0.30, and P0.31 are set as part of Board_LED_Init(), left in GPIO state */};再看这个
/** * @brief Array of IOCON pin definitions passed to Chip_IOCON_SetPinMuxing() must be in this format */typedef struct { uint32_t port : 8; /* Pin port */ uint32_t pin : 8; /* Pin number */ uint32_t modefunc : 16; /* Function and mode */} PINMUX_GRP_T;来看看这个
单元你研究研究看懂这些结构抽象。
主要是C 的数据结构知识。 |
|