NXP恩智浦单片机Keil5环境下编程

  • 一、编程环境
    • 1、硬件环境
    • 2、软件环境
  • 二、创建点亮LED例程
    • 1、硬件说明
    • 2、创建工程
    • 3、参考官方例程完成编程
  • 三、代码说明
    • 1、keil_startup_lpc5411x.s
    • 2、sysint.c
    • 3、main.c

前言 : 无聊之余,突然想起来本人当初立志边学习边笔记的豪言壮语。手上正在操作恩智浦公司的LPC54114单片机,作这篇学习笔记让自己再次学习一下,也希望能给如当初的我那般四处搜寻资料学习的同学们一点帮助。水平有限,有不足之处望看官不吝指正!!谢谢。

一、编程环境

1、硬件环境

OM13089: LPCXpresso54114电路板 :搭载 以Arm® Cortex®M4为核心且带有256KB flash和192KB SRAM的LPC54114单片机

2、软件环境

(1)、Windows10 专业版 20H2
(2)、集成开发环境 Keil V5.31.0.0
(3)、代码参考 官方板级支持包 LPC5411X Xpresso54114 Keil Iar v3.00.001_35
(4)、Keil LPC54114软件包

PS: 相关芯片资料和开发板资料原理图等都可以去恩智浦官网找到。

二、创建点亮LED例程

说点题外话,不知道是否有习惯用STM32的同学,ST的STM32CubeMX工具在构建工程的时候确实有很多方便,而且其图形化的界面也挺直观的。这是有助于提高生产效率的, 但是对初学者来说个人并不推荐这种方法。个人观点,单片机编程入门除了要具有一定基本的C语言编程能力以外,对目标单片机架构了解也尤为重要。
个人接触过ST的STM32,STM8,NXP的LPC54xxx,LPC13xx,TI的MSP430,Atmel的Atmage64,以及入门的第一款单片机STC51单片机等等,不管是8位,16位,32位,还是ARM,AVR,C51,MSP,PIC。预定功能的实现,归根结底都是对芯片正确寄存器的填写。
现在像Keil5这样的IDE基本都有提供针对芯片的软件包支持,这些软件包都对特定芯片的模块功能进行了抽象,使用者不需要像使用C51那样直接操作寄存器,按照正确流程调用功能函数就行了,这对生产者来说无疑对提高生产效率卓有成效,但是对初学者来说,把示例代码复制过来,按照教程删删改改功能就实现了,目的如果是应付作业确实省事,却没啥意义。
以上并不是要教人怎么做事, 只是作者一点碎碎念,有捷径不用非要死磕那是SB,哈哈,进入正题。

1、硬件说明


官方开发板带有一颗RGBLED灯原理图LPCX5411x-Schematic.pdf如上图所示。本例使用Red灯来做演示。有兴趣的同学也可以用PWM做RGB调色,应该有点意思。

2、创建工程

1> 打开 Keil5 编程环境, 创建新工程命名为"BlueLed",选择目标设备"LPC54114J256BD64:M4"。

2>在manage run-time environment设置, 这里的用法是个人习惯, 读者可以自行选择。

3> 打开 Manage Project Items 根据自己习惯修改条目

4> 工程 C/C++ 设置

5> 新建 main.c 工程主体文件, 红标了主要的功能文件

6> 工程创建环节到此结束。 工程编译通过连接一下开发板。



3、参考官方例程完成编程

1> 打开 <lpc5411x_xpresso54114_keil_iar_v3.01.000\lpc5411x\prj_xpresso54114\keil\periph_blinky\periph_blinky.uvprojx>官方闪灯示例程序
2> main.c 完成代码如下

#include "chip.h"


#define RED_LED_PORT                0
#define RED_LED_PIN                 29

#define TICKRATE_HZ                 10


typedef enum
{
    TURN_ON,
    TURN_OFF,
} LED_STATES;


int main(void)
{
    // 更新系统时钟
    SystemCoreClockUpdate();
    
    // 使能 IOCON 时钟
    Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
    
    // 使能 Systic
    SysTick_Config(SystemCoreClock / TICKRATE_HZ);
    
    // 初始化 RED_LED 引脚
    Chip_GPIO_Init(LPC_GPIO);
    Chip_GPIO_SetPinDIROutput(LPC_GPIO, RED_LED_PORT, RED_LED_PIN);
    Chip_GPIO_SetPinState(LPC_GPIO, RED_LED_PORT, RED_LED_PIN, TURN_ON);

    while (1)
    {
		__WFI();
    }
}

void SysTick_Handler(void)
{
    // 切换 LED 状态 
	Chip_GPIO_SetPinToggle(LPC_GPIO, RED_LED_PORT, RED_LED_PIN);
}

三、代码说明

1、keil_startup_lpc5411x.s

keil_startup_lpc5411x.s汇编语言源程序 是系统的启动文件。主要包括关于堆和栈的初始化配置(初学者对堆和栈的概念可能不清楚,请自行百度学习一下), 中断向量表的配置以及将程序引导到main()函数(调用 Reset Handler)

(1)、堆和栈的初始化

; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000200

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000100

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

上述汇编代码可见,系统默认分配了512(0x200)字节栈空间用于程序运行时存放函数值和局部变量。默认分配256(0x100)字节的堆空间用于存放全局、静态变量,以及动态分配空间(Malloc()等函数)

(2)、中断向量表的配置

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler

                DCD     NMI_Handler
                DCD     HardFault_Handler
                DCD     MemManage_Handler
                DCD     BusFault_Handler
                DCD     UsageFault_Handler
__vector_table_0x1c
                DCD     0                         ; Checksum of the first 7 words
                DCD     0
                DCD     0                         ; Enhanced image marker, set to 0x0 for legacy boot
                DCD     0                         ; Pointer to enhanced boot block, set to 0x0 for legacy boot
                DCD     SVC_Handler
                DCD     DebugMon_Handler
                DCD     0
                DCD     PendSV_Handler
                DCD     SysTick_Handler

                ; External Interrupts
                DCD     WDT_BOD_IRQHandler        ; Watchdog Ored with BOD
                DCD     DMA_IRQHandler            ; DMA Controller
                DCD     GINT0_IRQHandler          ; GPIO Group0 Interrupt
                DCD     GINT1_IRQHandler          ; GPIO Group1 Interrupt
                DCD     PIN_INT0_IRQHandler       ; PIO INT0
                DCD     PIN_INT1_IRQHandler       ; PIO INT1
                DCD     PIN_INT2_IRQHandler       ; PIO INT2
                DCD     PIN_INT3_IRQHandler       ; PIO INT3
                DCD     UTICK_IRQHandler          ; UTICK timer
                DCD     MRT_IRQHandler            ; Multi-Rate Timer
                DCD     CT32B0_IRQHandler         ; CT32B0
                DCD     CT32B1_IRQHandler         ; CT32B1
                DCD     SCT0_IRQHandler           ; Smart Counter Timer 
                DCD     CT32B3_IRQHandler         ; CT32B3
                DCD     FLEXCOMM0_IRQHandler      ; FLEXCOMM0
                DCD     FLEXCOMM1_IRQHandler      ; FLEXCOMM1
                DCD     FLEXCOMM2_IRQHandler      ; FLEXCOMM2
                DCD     FLEXCOMM3_IRQHandler      ; FLEXCOMM3
                DCD     FLEXCOMM4_IRQHandler      ; FLEXCOMM4
                DCD     FLEXCOMM5_IRQHandler      ; FLEXCOMM5
                DCD     FLEXCOMM6_IRQHandler      ; FLEXCOMM6
                DCD     FLEXCOMM7_IRQHandler      ; FLEXCOMM7
                DCD     ADC_SEQA_IRQHandler       ; ADC0 A sequence (A/D Converter) interrupt
                DCD     ADC_SEQB_IRQHandler       ; ADC0 B sequence (A/D Converter) interrupt
                DCD     ADC_THCMP_IRQHandler      ; ADC THCMP and OVERRUN ORed
                DCD     DMIC_IRQHandler           ; Digital MIC
                DCD     HWVAD_IRQHandler          ; Voice Activity detect
                DCD     USB_NEEDCLK_IRQHandler    ; USB NeedCLK
                DCD     USB_IRQHandler            ; USB
                DCD     RTC_IRQHandler            ; RTC Timer
                DCD     IOH_IRQHandler            ; Reserved
                DCD     MAILBOX_IRQHandler        ; Mailbox 
                DCD     PIN_INT4_IRQHandler       ; PIO INT4
                DCD     PIN_INT5_IRQHandler       ; PIO INT5
                DCD     PIN_INT6_IRQHandler       ; PIO INT6
                DCD     PIN_INT7_IRQHandler       ; PIO INT7
                DCD     CT32B2_IRQHandler         ; CT32B2
                DCD     CT32B4_IRQHandler         ; CT32B4
                DCD     Reserved_IRQHandler       ; Reserved
                DCD     SPIFI_IRQHandler          ; Reserved

单片机不可屏蔽中断和可屏蔽中断都在这了

(2)、进入主程序

normal_boot
                LDR     r0, =SystemInit
                BLX     r0
                LDR     r0, =__main
                BX      r0
                ENDP

前面还有一系列关于芯片的操作有兴趣可以去相关汇编代码, 工程开始运行到这里进行系统的FPU初始化以及系统时钟配置(sysint.c)后进入用户主程序(main())

2、sysint.c

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浮点运算单元、设置系统时钟。

3、main.c

使用SystemCoreClockUpdate()函数更新全局变量SystemCoreClock的值, 由于本例使用GPIO输出功能需要使能IOCON ,并使用Systic定时器提供闪烁定时服务。

红灯闪烁就到这里完成了

更多推荐

NXP恩智浦单片机Keil5环境下编程