LPC1700系列编程基础

LPC1700系列编程基础

在这里插入图片描述

1. 开发环境搭建

在开始LPC1700系列的编程之前,首先需要搭建一个合适的开发环境。LPC1700系列基于ARM Cortex-M3内核,常见的开发环境包括Keil uVision和LPCXpresso。本节将详细介绍如何搭建这些开发环境。

1.1 Keil uVision开发环境搭建

Keil uVision是一款广泛使用的集成开发环境(IDE),支持多种ARM内核的单片机开发。以下是搭建Keil uVision开发环境的步骤:

  1. 下载并安装Keil uVision

    • 访问Keil官网(https://www2.keil.com/)下载最新版本的Keil uVision。
    • 按照安装向导的提示完成安装。
  2. 安装LPC1700系列支持包

    • 打开Keil uVision。
    • 选择Project -> New uVision Project
    • 在弹出的对话框中选择LPC1700系列的芯片型号,例如LPC1768。
    • 点击Next,选择ARM -> Cortex-M3 -> LPC17xx,然后点击Next
    • 选择Use default settings for Target,点击Finish
  3. 配置硬件调试工具

    • 选择Project -> Options for Target
    • Target选项卡中选择合适的调试工具,例如LPC-Link2。
    • Debug选项卡中选择Use -> CMSIS-DAP Debugger
  4. 创建项目文件

    • 在项目目录中创建一个新的文件夹,例如LPC1700_Project
    • 将必要的源文件和库文件添加到项目中。
    • 创建主程序文件main.c

1.2 LPCXpresso开发环境搭建

LPCXpresso是NXP官方提供的集成开发环境,专门为LPC系列单片机设计。以下是搭建LPCXpresso开发环境的步骤:

  1. 下载并安装LPCXpresso

    • 访问NXP官网(https://www.nxp.com/)下载LPCXpresso IDE。
    • 按照安装向导的提示完成安装。
  2. 安装LPC1700系列支持包

    • 打开LPCXpresso。
    • 选择File -> New -> LPCXpresso Project
    • 在弹出的对话框中选择LPC1768芯片型号,点击Next
    • 选择Use default settings for Target,点击Finish
  3. 配置硬件调试工具

    • 选择Project -> Properties
    • C/C++ Build选项卡中配置编译器设置。
    • Debug选项卡中选择合适的调试工具,例如LPC-Link2。
  4. 创建项目文件

    • 在项目目录中创建一个新的文件夹,例如LPC1700_Project
    • 将必要的源文件和库文件添加到项目中。
    • 创建主程序文件main.c

2. 基本硬件初始化

在开始编写应用程序之前,需要对LPC1700系列的硬件进行初始化。这包括时钟配置、GPIO初始化、中断配置等。本节将详细介绍这些初始化步骤。

2.1 时钟配置

LPC1700系列的时钟源可以是内部振荡器或外部晶振。以下是一个时钟配置的例子:

#include "LPC17xx.h" // 导入LPC1700系列的头文件

void SystemInit(void) {
    // 使能外部晶振
    LPC_SC->CCLKSEL = 0x00; // 选择外部晶振作为主时钟源
    LPC_SC->CCLKCFG = 0x07; // 设置主时钟分频因子
    LPC_SC->PLL0CON = 0x01; // 使能PLL0
    LPC_SC->PLL0CFG = 0x24; // 设置PLL0配置
    LPC_SC->PLL0CON = 0x03; // 连接PLL0
    LPC_SC->CCLKSEL = 0x01; // 选择PLL0输出作为系统时钟源
    LPC_SC->PLL0STAT = 0x03; // 确认PLL0状态
    LPC_SC->SYSOSCCTRL = 0x02; // 使能外部晶振
    LPC_SC->PDRUNCFG &= ~(1 << 5); // 使能外部晶振
    LPC_SC->CCLKCFG = 0x07; // 设置系统时钟分频因子
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    // 其他初始化代码
    while (1) {
        // 主程序
    }
}

2.2 GPIO初始化

LPC1700系列的GPIO(通用输入输出)接口可以用于控制外部设备。以下是一个GPIO初始化的例子:

#include "LPC17xx.h"

void GPIO_Init(void) {
    // 设置P0.0为输出模式
    LPC_PINCON->PINSEL0 &= ~(3 << 0); // 清除P0.0的位选择
    LPC_PINCON->PINSEL0 |= (0 << 0); // 设置P0.0为GPIO
    LPC_GPIO0->FIODIR |= (1 << 0); // 设置P0.0为输出
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO

    while (1) {
        LPC_GPIO0->FIOSET = (1 << 0); // 设置P0.0为高电平
        LPC_SC->PCON |= (1 << 0); // 使能电源管理
        LPC_SC->PCON &= ~(1 << 0); // 清除电源管理
        LPC_GPIO0->FIOCLR = (1 << 0); // 设置P0.0为低电平
    }
}

2.3 中断配置

LPC1700系列支持多种中断源,中断配置是实现复杂功能的重要步骤。以下是一个中断配置的例子:

#include "LPC17xx.h"
#include "NXP_LPC1700.h" // 导入LPC1700系列的库文件

void EINT3_IRQHandler(void) __attribute__((interrupt("IRQ"))); // 中断处理函数声明

void EINT3_IRQHandler(void) {
    // 中断处理代码
    LPC_SC->EXTINT = (1 << 3); // 清除外部中断3的状态
}

void NVIC_Init(void) {
    // 使能外部中断3
    LPC_SC->EXTMODE |= (1 << 3); // 设置外部中断3为边沿触发
    LPC_SC->EXTPOLAR &= ~(1 << 3); // 设置外部中断3为下降沿触发
    NVIC_EnableIRQ(EINT3_IRQn); // 使能外部中断3的中断
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC

    // 设置P0.3为输入模式
    LPC_PINCON->PINSEL6 &= ~(0x03 << 0); // 清除P0.3的位选择
    LPC_PINCON->PINSEL6 |= (0x01 << 0); // 设置P0.3为GPIO
    LPC_GPIO0->FIODIR &= ~(1 << 3); // 设置P0.3为输入

    while (1) {
        // 主程序
    }
}

3. 基本外设使用

LPC1700系列包含多种外设,如UART、I2C、SPI等。本节将详细介绍如何使用这些外设。

3.1 UART通信

UART(通用异步收发传输器)是常用的串行通信接口。以下是一个UART通信的例子:

#include "LPC17xx.h"

void UART_Init(void) {
    // 使能UART0的时钟
    LPC_SC->PCONP |= (1 << 3); // 使能UART0的时钟

    // 设置UART0的波特率
    LPC_UART0->LCR = 0x83; // 使能DLAB,设置8位数据,无校验,1位停止位
    LPC_UART0->DLL = 0x61; // 设置波特率分频低8位
    LPC_UART0->DLM = 0x00; // 设置波特率分频高8位
    LPC_UART0->LCR = 0x03; // 清除DLAB

    // 设置UART0的FIFO
    LPC_UART0->FCR = 0x07; // 使能FIFO,设置触发点为1个字节

    // 使能UART0的发送和接收
    LPC_UART0->IER = 0x03; // 使能发送和接收中断
}

void UART_SendChar(char ch) {
    while (!(LPC_UART0->LSR & 0x20)); // 等待发送缓冲区为空
    LPC_UART0->THR = ch; // 发送字符
}

void UART_SendString(char *str) {
    while (*str) {
        UART_SendChar(*str++);
    }
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    UART_Init(); // 初始化UART

    while (1) {
        UART_SendString("Hello, LPC1700!\r\n"); // 发送字符串
        LPC_SC->PCON |= (1 << 0); // 使能电源管理
        LPC_SC->PCON &= ~(1 << 0); // 清除电源管理
    }
}

3.2 I2C通信

I2C(内部集成电路总线)是一种用于短距离通信的串行总线。以下是一个I2C通信的例子:

#include "LPC17xx.h"

void I2C_Init(void) {
    // 使能I2C0的时钟
    LPC_SC->PCONP |= (1 << 24); // 使能I2C0的时钟

    // 设置I2C0的引脚
    LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & (~0x000000F0)) | 0x000000A0; // 设置P0.10和P0.11为I2C
    LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & (~0x000000F0)) | 0x000000A0; // 设置引脚模式为标准模式

    // 配置I2C0
    LPC_I2C0->CON = 0x00; // 设置为标准模式
    LPC_I2C0->SA = 0x5A; // 设置I2C地址
    LPC_I2C0->ADR = 0x00; // 清除从机地址
    LPC_I2C0->SCLH = 0x0F; // 设置SCL高周期
    LPC_I2C0->SCLL = 0x0F; // 设置SCL低周期
    LPC_I2C0->CON |= 0x40; // 使能I2C
}

void I2C_Write(uint8_t address, uint8_t reg, uint8_t data) {
    LPC_I2C0->CONCLR = 0x03; // 清除起始和停止条件
    LPC_I2C0->CONSET = 0x01; // 使能I2C起始条件

    // 等待I2C空闲
    while (LPC_I2C0->STAT != 0x08);

    // 发送从机地址(写模式)
    LPC_I2C0->DAT = (address << 1) | 0x00;
    while (LPC_I2C0->STAT != 0x18);

    // 发送寄存器地址
    LPC_I2C0->DAT = reg;
    while (LPC_I2C0->STAT != 0x28);

    // 发送数据
    LPC_I2C0->DAT = data;
    while (LPC_I2C0->STAT != 0x28);

    // 生成停止条件
    LPC_I2C0->CONCLR = 0x02; // 清除停止条件
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    I2C_Init(); // 初始化I2C

    while (1) {
        I2C_Write(0x50, 0x01, 0x55); // 写入数据到从机地址0x50的寄存器0x01
        LPC_SC->PCON |= (1 << 0); // 使能电源管理
        LPC_SC->PCON &= ~(1 << 0); // 清除电源管理
    }
}

3.3 SPI通信

SPI(串行外设接口)是一种全双工同步串行通信接口。以下是一个SPI通信的例子:

#include "LPC17xx.h"

void SPI_Init(void) {
    // 使能SPI0的时钟
    LPC_SC->PCONP |= (1 << 11); // 使能SPI0的时钟

    // 设置SPI0的引脚
    LPC_PINCON->PINSEL0 = (LPC_PINCON->PINSEL0 & (~0x0000000F)) | 0x0000000A; // 设置P0.0为MISO,P0.1为MOSI
    LPC_PINCON->PINSEL1 = (LPC_PINCON->PINSEL1 & (~0x0000000F)) | 0x00000002; // 设置P0.4为SCLK
    LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & (~0x0000000F)) | 0x00000000; // 设置P0.16为NSS

    // 配置SPI0
    LPC_SPI0->SPCR = 0x00; // 清除SPI控制寄存器
    LPC_SPI0->SPCR = 0x30; // 使能SPI主模式,设置数据长度为8位
    LPC_SPI0->SPCCR = 0x01; // 设置波特率分频因子
}

void SPI_Write(uint8_t data) {
    // 等待SPI空闲
    while (!(LPC_SPI0->SPSR & 0x20));

    // 发送数据
    LPC_SPI0->SPDR = data;

    // 等待数据传输完成
    while (!(LPC_SPI0->SPSR & 0x10));
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    SPI_Init(); // 初始化SPI

    while (1) {
        SPI_Write(0x55); // 发送数据0x55
        LPC_SC->PCON |= (1 << 0); // 使能电源管理
        LPC_SC->PCON &= ~(1 << 0); // 清除电源管理
    }
}

4. 中断处理

中断处理是嵌入式系统中重要的功能,可以实现对外部事件的快速响应。以下是一个中断处理的例子:

#include "LPC17xx.h"
#include "NXP_LPC1700.h"

void EINT3_IRQHandler(void) __attribute__((interrupt("IRQ"))); // 中断处理函数声明

void EINT3_IRQHandler(void) {
    // 中断处理代码
    LPC_SC->EXTINT = (1 << 3); // 清除外部中断3的状态
    LPC_GPIO0->FIOCLR = (1 << 0); // 设置P0.0为低电平
}

void NVIC_Init(void) {
    // 使能外部中断3
    LPC_SC->EXTMODE |= (1 << 3); // 设置外部中断3为边沿触发
    LPC_SC->EXTPOLAR &= ~(1 << 3); // 设置外部中断3为下降沿触发
    NVIC_EnableIRQ(EINT3_IRQn); // 使能外部中断3的中断
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC

    // 设置P0.3为输入模式
    LPC_PINCON->PINSEL6 &= ~(0x03 << 0); // 清除P0.3的位选择
    LPC_PINCON->PINSEL6 |= (0x01 << 0); // 设置P0.3为GPIO
    LPC_GPIO0->FIODIR &= ~(1 << 3); // 设置P0.3为输入

    while (1) {
        // 主程序
    }
}

5. 定时器使用

LPC1700系列包含多个定时器,可以用于产生定时中断或控制外部设备。以下是一个定时器的例子:

5.1 定时器初始化

在使用定时器之前,需要对其进行初始化。这包括使能定时器的时钟、配置定时器的预分频器和匹配寄存器等。以下是一个定时器0的初始化示例:

#include "LPC17xx.h"

void Timer_Init(void) {
    // 使能定时器0的时钟
    LPC_SC->PCONP |= (1 << 22); // 使能定时器0的时钟

    // 配置定时器0
    LPC_TIM0->TCR = 0x02; // 使能定时器复位
    LPC_TIM0->PR = 0x00; // 设置预分频器为0
    LPC_TIM0->MR0 = 100000; // 设置匹配寄存器0为100000个时钟周期
    LPC_TIM0->MCR = 0x04; // 设置中断模式为定时器匹配
    LPC_TIM0->TCR = 0x01; // 启动定时器
}

void Timer0_IRQHandler(void) {
    // 定时器0中断处理代码
    LPC_TIM0->IR = 0x01; // 清除定时器0中断标志
    LPC_GPIO0->FIOCLR = (1 << 0); // 设置P0.0为低电平
    LPC_GPIO0->FIOSET = (1 << 0); // 设置P0.0为高电平
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    Timer_Init(); // 初始化定时器0

    // 使能定时器0中断
    NVIC_EnableIRQ(TIMER0_IRQn);

    while (1) {
        // 主程序
    }
}

5.2 定时器中断配置

定时器中断配置是实现定时功能的关键步骤。以下是一个定时器0中断配置的示例:

#include "LPC17xx.h"

void Timer_Init(void) {
    // 使能定时器0的时钟
    LPC_SC->PCONP |= (1 << 22); // 使能定时器0的时钟

    // 配置定时器0
    LPC_TIM0->TCR = 0x02; // 使能定时器复位
    LPC_TIM0->PR = 0x00; // 设置预分频器为0
    LPC_TIM0->MR0 = 100000; // 设置匹配寄存器0为100000个时钟周期
    LPC_TIM0->MCR = 0x04; // 设置中断模式为定时器匹配
    LPC_TIM0->TCR = 0x01; // 启动定时器
}

void Timer0_IRQHandler(void) {
    // 定时器0中断处理代码
    LPC_TIM0->IR = 0x01; // 清除定时器0中断标志
    LPC_GPIO0->FIOCLR = (1 << 0); // 设置P0.0为低电平
    LPC_GPIO0->FIOSET = (1 << 0); // 设置P0.0为高电平
}

void NVIC_Init(void) {
    // 使能定时器0中断
    NVIC_EnableIRQ(TIMER0_IRQn);
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    Timer_Init(); // 初始化定时器0

    while (1) {
        // 主程序
    }
}

5.3 定时器应用示例

定时器可以用于多种应用,例如周期性地执行某个任务或控制外部设备。以下是一个使用定时器0控制LED闪烁的示例:

#include "LPC17xx.h"

void Timer_Init(void) {
    // 使能定时器0的时钟
    LPC_SC->PCONP |= (1 << 22); // 使能定时器0的时钟

    // 配置定时器0
    LPC_TIM0->TCR = 0x02; // 使能定时器复位
    LPC_TIM0->PR = 0x00; // 设置预分频器为0
    LPC_TIM0->MR0 = 100000; // 设置匹配寄存器0为100000个时钟周期
    LPC_TIM0->MCR = 0x04; // 设置中断模式为定时器匹配
    LPC_TIM0->TCR = 0x01; // 启动定时器
}

void Timer0_IRQHandler(void) {
    // 定时器0中断处理代码
    LPC_TIM0->IR = 0x01; // 清除定时器0中断标志
    static uint8_t led_state = 0;
    if (led_state) {
        LPC_GPIO0->FIOCLR = (1 << 0); // 设置P0.0为低电平
    } else {
        LPC_GPIO0->FIOSET = (1 << 0); // 设置P0.0为高电平
    }
    led_state = !led_state; // 切换LED状态
}

void GPIO_Init(void) {
    // 设置P0.0为输出模式
    LPC_PINCON->PINSEL0 &= ~(3 << 0); // 清除P0.0的位选择
    LPC_PINCON->PINSEL0 |= (0 << 0); // 设置P0.0为GPIO
    LPC_GPIO0->FIODIR |= (1 << 0); // 设置P0.0为输出
}

void NVIC_Init(void) {
    // 使能定时器0中断
    NVIC_EnableIRQ(TIMER0_IRQn);
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    Timer_Init(); // 初始化定时器0

    while (1) {
        // 主程序
    }
}

6. PWM(脉冲宽度调制)使用

LPC1700系列支持PWM(脉冲宽度调制)功能,可以用于控制电机、LED亮度等。以下是一个PWM使用的例子:

6.1 PWM初始化

在使用PWM之前,需要对其进行初始化。这包括使能PWM的时钟、配置PWM的寄存器等。以下是一个PWM初始化的示例:

#include "LPC17xx.h"

void PWM_Init(void) {
    // 使能PWM的时钟
    LPC_SC->PCONP |= (1 << 15); // 使能PWM的时钟

    // 设置PWM的引脚
    LPC_PINCON->PINSEL4 = (LPC_PINCON->PINSEL4 & (~0x0000000F)) | 0x0000000A; // 设置P0.18和P0.19为PWM

    // 配置PWM
    LPC_PWM1->PCR = 0x00; // 清除PWM控制寄存器
    LPC_PWM1->PCR = 0x03; // 使能PWM0和PWM1
    LPC_PWM1->LER = 0x00; // 清除匹配加载寄存器
    LPC_PWM1->LER = 0x03; // 使能匹配0和匹配1
    LPC_PWM1->MR0 = 100000; // 设置匹配寄存器0为100000个时钟周期
    LPC_PWM1->MR1 = 50000; // 设置匹配寄存器1为50000个时钟周期
    LPC_PWM1->TCR = 0x02; // 使能定时器复位
    LPC_PWM1->TCR = 0x01; // 启动PWM
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    PWM_Init(); // 初始化PWM

    while (1) {
        // 主程序
    }
}

6.2 PWM应用示例

PWM可以用于控制电机的速度或LED的亮度。以下是一个使用PWM控制LED亮度的示例:

#include "LPC17xx.h"

void PWM_Init(void) {
    // 使能PWM的时钟
    LPC_SC->PCONP |= (1 << 15); // 使能PWM的时钟

    // 设置PWM的引脚
    LPC_PINCON->PINSEL4 = (LPC_PINCON->PINSEL4 & (~0x0000000F)) | 0x0000000A; // 设置P0.18和P0.19为PWM

    // 配置PWM
    LPC_PWM1->PCR = 0x00; // 清除PWM控制寄存器
    LPC_PWM1->PCR = 0x03; // 使能PWM0和PWM1
    LPC_PWM1->LER = 0x00; // 清除匹配加载寄存器
    LPC_PWM1->LER = 0x03; // 使能匹配0和匹配1
    LPC_PWM1->MR0 = 100000; // 设置匹配寄存器0为100000个时钟周期
    LPC_PWM1->MR1 = 50000; // 设置匹配寄存器1为50000个时钟周期
    LPC_PWM1->TCR = 0x02; // 使能定时器复位
    LPC_PWM1->TCR = 0x01; // 启动PWM
}

void PWM_SetDutyCycle(uint32_t channel, uint32_t duty_cycle) {
    // 设置PWM通道的占空比
    switch (channel) {
        case 0:
            LPC_PWM1->MR1 = (LPC_PWM1->MR0 * duty_cycle) / 100;
            break;
        case 1:
            LPC_PWM1->MR2 = (LPC_PWM1->MR0 * duty_cycle) / 100;
            break;
        // 可以添加更多通道
    }
}

int main(void) {
    SystemInit(); // 初始化系统时钟
    GPIO_Init(); // 初始化GPIO
    NVIC_Init(); // 初始化NVIC
    PWM_Init(); // 初始化PWM

    while (1) {
        PWM_SetDutyCycle(0, 25); // 设置PWM0的占空比为25%
        for (volatile uint32_t i = 0; i < 500000; i++); // 延时
        PWM_SetDutyCycle(0, 50); // 设置PWM0的占空比为50%
        for (volatile uint32_t i = 0; i < 500000; i++); // 延时
        PWM_SetDutyCycle(0, 75); // 设置PWM0的占空比为75%
        for (volatile uint32_t i = 0; i < 500000; i++); // 延时
        PWM_SetDutyCycle(0, 100); // 设置PWM0的占空比为100%
        for (volatile uint32_t i = 0; i < 500000; i++); // 延时
    }
}

7. 总结

通过以上内容,我们详细介绍了如何搭建LPC1700系列的开发环境,包括Keil uVision和LPCXpresso。此外,我们还介绍了基本的硬件初始化步骤,如时钟配置、GPIO初始化和中断配置。最后,我们展示了如何使用LPC1700系列的常见外设,如UART、I2C、SPI和PWM。

希望这些内容能够帮助你更好地理解和使用LPC1700系列单片机。如果你有任何问题或需要进一步的帮助,请随时查阅官方文档或在线资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值