2. 架构与硬件特性
2.1 架构概述
LPC1100 系列是 NXP 公司基于 ARM Cortex-M0 内核的微控制器系列。ARM Cortex-M0 是 ARM 公司推出的一款低功耗、高性能的 32 位 RISC 处理器内核,适用于嵌入式系统和微控制器应用。LPC1100 系列微控制器采用了 Cortex-M0 内核,具有以下主要特点:
- 低功耗:Cortex-M0 内核的低功耗特性使得 LPC1100 系列适用于电池供电的设备。
- 高性能:尽管是低功耗内核,Cortex-M0 仍然提供了较高的处理性能,适用于多种嵌入式应用。
- 小尺寸:Cortex-M0 内核的代码密度较高,使得 LPC1100 系列的芯片尺寸较小,适合紧凑型设计。
- 丰富的外设:LPC1100 系列集成了多种外设,如 UART、SPI、I2C、ADC、DAC 等,满足各种应用需求。
2.1.1 ARM Cortex-M0 内核概述
ARM Cortex-M0 内核是一个高度优化的 32 位 RISC 处理器,具有以下特点:
- 哈佛架构:Cortex-M0 采用哈佛架构,分别有独立的指令和数据总线,提高了数据处理的效率。
- 32 位指令集:支持 32 位指令集,提供了丰富的指令操作,提高了代码的执行效率。
- 16 位 Thumb-2 指令集:支持 16 位 Thumb-2 指令集,进一步提高了代码密度和执行效率。
- 中断系统:Cortex-M0 具有高效的中断处理机制,支持快速中断响应和低中断延迟。
- 调试支持:内核支持多种调试接口,如 JTAG 和 SWD,便于开发和调试。
2.1.2 LPC1100 系列架构特点
LPC1100 系列微控制器在 ARM Cortex-M0 内核的基础上,集成了多种硬件特性,以满足不同应用需求。主要特点包括:
- 嵌入式闪存:LPC1100 系列通常配备 32KB 到 256KB 的嵌入式闪存,支持多次编程和擦除。
- SRAM:提供 8KB 到 32KB 的 SRAM,用于数据存储和程序运行。
- 时钟系统:支持多种时钟源,包括内部 RC 振荡器、外部晶振和 PLL(锁相环)。
- 电源管理:具有低功耗模式,如睡眠模式和深度睡眠模式,以延长电池寿命。
- 丰富的外设:集成了多种常用的外设,如 UART、SPI、I2C、ADC、DAC、GPIO 等。
2.2 时钟系统
2.2.1 时钟源
LPC1100 系列微控制器支持多种时钟源,包括:
- 内部 RC 振荡器:提供 12MHz 的内部时钟源,无需外部组件,适合快速启动和简单应用。
- 外部晶振:支持外部晶体振荡器,提供更精确的时钟源,适用于需要高精度时钟的应用。
- PLL(锁相环):通过 PLL 可以将外部时钟源倍频到更高的频率,以提高处理性能。
2.2.2 时钟配置
时钟配置通常通过寄存器进行,以下是一个配置外部晶振和 PLL 的示例代码:
// 配置外部晶振和 PLL
void configure_clock(void) {
// 使能外部晶振
LPC_SYSCON->SYSOSCCTRL |= (1 << 0); // SYSOSCCTRL[0]: Enable external oscillator
LPC_SYSCON->SYSPLLCLKSEL = 0; // 选择外部晶振作为 PLL 输入源
LPC_SYSCON->PDRUNCFGCLR |= (1 << 4); // 清除 PLL 电源运行配置,使能 PLL
// 配置 PLL
LPC_SYSCON->SYSPLLCTRL = (1 << 0) | (1 << 1); // 设置 PLL 倍频因子
while ((LPC_SYSPLLCLKUEN & (1 << 1)) == 0); // 等待 PLL 锁定
// 选择 PLL 作为系统时钟源
LPC_SYSCON->SYSAHBCLKSEL = 1; // SYSAHBCLKSEL[0]: Select PLL as system clock source
LPC_SYSCON->SYSAHBCLKDIV = 1; // 设置系统时钟分频因子
}
2.2.3 低功耗模式
LPC1100 系列支持多种低功耗模式,包括睡眠模式和深度睡眠模式。这些模式通过关闭不必要的时钟和电源,降低功耗。
- 睡眠模式:在睡眠模式下,CPU 停止运行,但外设和时钟源仍然保持运行。
- 深度睡眠模式:在深度睡眠模式下,CPU 和大部分外设停止运行,只保留最基本的时钟源和电源管理功能。
以下是一个进入睡眠模式的示例代码:
// 进入睡眠模式
void enter_sleep_mode(void) {
// 禁用所有外设时钟
LPC_SYSCON->SYSAHBCLKDIV = 0;
LPC_SYSCON->SYSAHBCLKSEL = 0;
// 进入睡眠模式
__WFI(); // Wait For Interrupt
}
2.3 电源管理
2.3.1 供电模式
LPC1100 系列微控制器支持多种供电模式,包括:
- 正常模式:CPU 和所有外设正常运行。
- 睡眠模式:CPU 停止运行,外设保持运行。
- 深度睡眠模式:CPU 和大部分外设停止运行,只有最基本的时钟源和电源管理功能保持运行。
- 掉电模式:所有组件停止运行,只保留最基本的掉电检测功能。
2.3.2 电源管理寄存器
电源管理主要通过以下寄存器进行配置:
- PDRUNCFG:电源运行配置寄存器,用于控制各个模块的电源状态。
- SYSAHBCLKDIV 和 SYSAHBCLKSEL:系统时钟分频和选择寄存器,用于配置系统时钟。
以下是一个配置电源管理的示例代码:
// 配置电源管理
void configure_power_management(void) {
// 使能内部 RC 振荡器
LPC_SYSCON->SYSOSCCTRL |= (1 << 0); // SYSOSCCTRL[0]: Enable internal RC oscillator
// 关闭 PLL
LPC_SYSCON->PDRUNCFGSET |= (1 << 4); // 设置 PLL 电源运行配置,关闭 PLL
// 选择内部 RC 振荡器作为系统时钟源
LPC_SYSCON->SYSAHBCLKSEL = 0; // SYSAHBCLKSEL[0]: Select internal RC oscillator as system clock source
LPC_SYSCON->SYSAHBCLKDIV = 1; // 设置系统时钟分频因子
}
2.4 存储器
2.4.1 闪存
LPC1100 系列微控制器通常配备 32KB 到 256KB 的嵌入式闪存,用于存储程序代码和常量数据。闪存的读写操作通过 Flash Memory Controller (FLM) 进行控制。
2.4.2 SRAM
LPC1100 系列提供 8KB 到 32KB 的 SRAM,用于数据存储和程序运行。SRAM 的访问速度较快,适合频繁读写的数据。
2.4.3 存储器映射
LPC1100 系列的存储器映射如下:
- 0x0000_0000 - 0x0000_FFFF:闪存
- 0x1000_0000 - 0x1000_FFFF:SRAM
- 0x4000_0000 - 0x400F_FFFF:系统外设寄存器
- 0xE000_E000 - 0xE000_EFFF:嵌入式外设寄存器(如 NVIC)
以下是一个简单的存储器访问示例代码:
// 存储器访问示例
void memory_access_example(void) {
// 定义 SRAM 地址
uint32_t *sram_address = (uint32_t *)0x10000000;
// 写入数据到 SRAM
*sram_address = 0x12345678;
// 读取数据从 SRAM
uint32_t data = *sram_address;
// 输出读取的数据
printf("Data from SRAM: 0x%08X\n", data);
}
2.5 外设
2.5.1 UART
LPC1100 系列集成了一个或多个 UART 接口,用于串行通信。UART 的配置和使用通常通过寄存器进行。
2.5.1.1 UART 配置
以下是一个配置 UART 的示例代码:
// 配置 UART
void configure_uart(void) {
// 使能 UART 时钟
LPC_SYSCON->SYSAHBCLKDIV = 1; // 设置分频因子
LPC_SYSCON->SYSAHBCLKSEL = 1; // 选择 PLL 作为系统时钟源
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12); // 使能 UART0 时钟
// 配置 UART 波特率
LPC_UART0->LCR = (1 << 7); // DLAB = 1,允许访问 DLL 和 DLM 寄存器
LPC_UART0->DLL = 12; // 设置低 8 位波特率
LPC_UART0->DLM = 0; // 设置高 8 位波特率
LPC_UART0->LCR = 0x03; // 8 位数据,无校验位,1 位停止位
// 使能 UART 发送和接收
LPC_UART0->IER = (1 << 0) | (1 << 1); // 使能接收和发送中断
LPC_UART0->FCR = 0x07; // 清除 FIFO,使能 FIFO,设置触发级别
}
2.5.1.2 UART 数据发送
以下是一个通过 UART 发送数据的示例代码:
// 发送数据通过 UART
void uart_send_data(uint8_t data) {
// 等待发送缓冲区为空
while (!(LPC_UART0->LSR & (1 << 5))); // 检查 LSR[5]: THRE
// 发送数据
LPC_UART0->THR = data;
}
2.5.2 SPI
LPC1100 系列集成了 SPI 接口,用于同步串行通信。SPI 的配置和使用通常通过寄存器进行。
2.5.2.1 SPI 配置
以下是一个配置 SPI 的示例代码:
// 配置 SPI
void configure_spi(void) {
// 使能 SPI 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10); // 使能 SPI 时钟
// 配置 SPI 模式
LPC_SPI->CR1 = 0x03; // 主模式,时钟源为 PCLK
LPC_SPI->CR0 = 0x0F; // 设置时钟分频因子为 16,波特率为 PCLK/16
// 配置 SPI 数据格式
LPC_SPI->CPSR = 0x01; // 设置时钟预分频因子
LPC_SPI->DCR = 0x08; // 设置数据位长度为 8 位
// 使能 SPI
LPC_SPI->CR1 |= (1 << 1); // 使能 SPI
}
2.5.2.2 SPI 数据发送
以下是一个通过 SPI 发送数据的示例代码:
// 发送数据通过 SPI
void spi_send_data(uint8_t data) {
// 等待发送缓冲区为空
while (!(LPC_SPI->SR & (1 << 5))); // 检查 SR[5]: TX FIFO 空
// 发送数据
LPC_SPI->DR = data;
// 等待发送完成
while (!(LPC_SPI->SR & (1 << 3))); // 检查 SR[3]: 传输完成
}
2.5.3 I2C
LPC1100 系列集成了 I2C 接口,用于同步串行通信。I2C 的配置和使用通常通过寄存器进行。
2.5.3.1 I2C 配置
以下是一个配置 I2C 的示例代码:
// 配置 I2C
void configure_i2c(void) {
// 使能 I2C 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7); // 使能 I2C 时钟
// 配置 I2C 波特率
LPC_I2C->SCL = 100000; // 设置 SCL 时钟频率为 100kHz
// 使能 I2C
LPC_I2C->CONSET = (1 << 6); // 使能 I2C
}
2.5.3.2 I2C 数据发送
以下是一个通过 I2C 发送数据的示例代码:
// 发送数据通过 I2C
void i2c_send_data(uint8_t slave_address, uint8_t *data, uint8_t length) {
// 发送起始信号
LPC_I2C->CONSET |= (1 << 0); // 发送起始信号
// 等待起始信号发送完成
while (LPC_I2C->STAT != 0x08); // 检查状态寄存器
// 发送从设备地址和写操作
LPC_I2C->DAT = (slave_address << 1) | 0; // 从设备地址和写操作
while (LPC_I2C->STAT != 0x18); // 检查状态寄存器
// 发送数据
for (uint8_t i = 0; i < length; i++) {
LPC_I2C->DAT = data[i];
while (LPC_I2C->STAT != 0x28); // 检查状态寄存器
}
// 发送停止信号
LPC_I2C->CONCLR = (1 << 0); // 发送停止信号
}
2.5.4 ADC
LPC1100 系列集成了 ADC(模数转换器),用于将模拟信号转换为数字信号。ADC 的配置和使用通常通过寄存器进行。
2.5.4.1 ADC 配置
以下是一个配置 ADC 的示例代码:
// 配置 ADC
void configure_adc(void) {
// 使能 ADC 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12); // 使能 ADC 时钟
// 配置 ADC 分辨率和时钟源
LPC_ADC->CR = (1 << 24) | (1 << 21); // 10 位分辨率,PCLK/4 作为时钟源
// 选择 ADC 通道
LPC_ADC->CR |= (1 << 0); // 选择通道 0
}
2.5.4.2 ADC 数据读取
以下是一个读取 ADC 数据的示例代码:
// 读取 ADC 数据
uint16_t read_adc_data(void) {
// 开始转换
LPC_ADC->CR |= (1 << 24); // 设置 START 位
// 等待转换完成
while (!(LPC_ADC->DR[0] & (1 << 31))); // 检查 DR[31]: DATAVALID
// 读取转换结果
uint16_t result = (LPC_ADC->DR[0] & 0x3FF); // 读取 10 位结果
return result;
}
2.5.5 DAC
LPC1100 系列集成了 DAC(数模转换器),用于将数字信号转换为模拟信号。DAC 的配置和使用通常通过寄存器进行。
2.5.5.1 DAC 配置
以下是一个配置 DAC 的示例代码:
// 配置 DAC
void configure_dac(void) {
// 使能 DAC 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); // 使能 DAC 时钟
// 配置 DAC 分辨率和时钟源
LPC_DAC->CR = (1 << 16); // 12 位分辨率
}
2.5.5.2 DAC 数据发送
以下是一个通过 DAC 发送数据的示例代码:
// 发送数据通过 DAC
void dac_send_data(uint16_t data) {
// 设置 DAC 输出值
LPC_DAC->CR = (data &当然,我会继续前文内容并确保前后连贯。以下是续写的内容:
## 2.5 外设
### 2.5.5 DAC
LPC1100 系列集成了 DAC(数模转换器),用于将数字信号转换为模拟信号。DAC 的配置和使用通常通过寄存器进行。
#### 2.5.5.1 DAC 配置
以下是一个配置 DAC 的示例代码:
```c
// 配置 DAC
void configure_dac(void) {
// 使能 DAC 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); // 使能 DAC 时钟
// 配置 DAC 分辨率和时钟源
LPC_DAC->CR = (1 << 16); // 12 位分辨率
}
2.5.5.2 DAC 数据发送
以下是一个通过 DAC 发送数据的示例代码:
// 发送数据通过 DAC
void dac_send_data(uint16_t data) {
// 设置 DAC 输出值
LPC_DAC->CR = (data & 0x0FFF) | (1 << 24); // 设置 12 位输出值并启动转换
}
2.5.6 GPIO
LPC1100 系列集成了通用输入输出(GPIO)端口,用于控制外部设备和接收外部信号。GPIO 的配置和使用通常通过寄存器进行。
2.5.6.1 GPIO 配置
以下是一个配置 GPIO 的示例代码:
// 配置 GPIO
void configure_gpio(void) {
// 使能 GPIO 时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); // 使能 GPIO 时钟
// 配置 GPIO 为输出模式
LPC_GPIO->DIR = (1 << 0); // 设置 P0.0 为输出模式
// 配置 GPIO 为输入模式
LPC_GPIO->DIR &= ~(1 << 1); // 设置 P0.1 为输入模式
}
2.5.6.2 GPIO 数据读写
以下是一个读取和设置 GPIO 数据的示例代码:
// 设置 GPIO 输出
void set_gpio_output(uint8_t pin, uint8_t value) {
if (value) {
LPC_GPIO->SET = (1 << pin); // 设置 P0.pin 为高电平
} else {
LPC_GPIO->CLR = (1 << pin); // 设置 P0.pin 为低电平
}
}
// 读取 GPIO 输入
uint8_t read_gpio_input(uint8_t pin) {
return (LPC_GPIO->PIN & (1 << pin)) ? 1 : 0; // 读取 P0.pin 的状态
}
2.5.7 定时器
LPC1100 系列集成了多个定时器,用于产生定时中断和延时功能。定时器的配置和使用通常通过寄存器进行。
2.5.7.1 定时器配置
以下是一个配置定时器的示例代码:
// 配置定时器
void configure_timer(void) {
// 使能定时器时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8); // 使能 TMR16B1 时钟
// 选择定时器时钟源
LPC_SYSCON->TMR16BCLKSEL = 0; // 选择 PCLK 作为定时器时钟源
// 配置定时器预分频器和匹配值
LPC_TMR16B1->PR = 0; // 预分频器设置为 0
LPC_TMR16B1->MR0 = 10000; // 设置匹配值为 10000
// 配置定时器中断
LPC_TMR16B1->MCR = (1 << 0) | (1 << 1); // 在匹配值 0 时产生中断并复位定时器
// 使能定时器
LPC_TMR16B1->TCR = (1 << 0); // 使能定时器
LPC_TMR16B1->TCR |= (1 << 1); // 启动定时器
}
2.5.7.2 定时器中断处理
以下是一个处理定时器中断的示例代码:
// 定时器中断处理函数
void TIMER16B1_IRQHandler(void) {
// 清除中断标志
LPC_TMR16B1->IR = (1 << 0); // 清除 MR0 匹配中断标志
// 处理定时器中断事件
// 例如,切换一个 LED 的状态
if (LPC_GPIO->PIN & (1 << 0)) {
LPC_GPIO->CLR = (1 << 0); // 关闭 P0.0
} else {
LPC_GPIO->SET = (1 << 0); // 打开 P0.0
}
}
2.5.8 看门狗定时器
LPC1100 系列集成了看门狗定时器(WDT),用于在系统出现异常时复位微控制器。看门狗定时器的配置和使用通常通过寄存器进行。
2.5.8.1 看门狗定时器配置
以下是一个配置看门狗定时器的示例代码:
// 配置看门狗定时器
void configure_wdt(void) {
// 使能看门狗定时器时钟
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9); // 使能 WDT 时钟
// 配置看门狗定时器时钟源
LPC_WDT->TC = 0x00000000; // 选择外部 RC 振荡器作为时钟源
// 配置看门狗定时器时钟分频因子
LPC_WDT->PC = 0x000000FF; // 设置分频因子为 256
// 配置看门狗定时器超时周期
LPC_WDT->TV = 0x0000FFFF; // 设置超时周期为 65535 * 256 / 12MHz = 1.39 秒
// 使能看门狗定时器
LPC_WDT->TCR = 0x00000001; // 使能看门狗定时器
}
2.5.8.2 看门狗定时器喂狗
以下是一个喂狗的示例代码:
// 喂狗
void feed_wdt(void) {
LPC_WDT->TCR = 0x00000002; // 喂狗
}
2.6 中断系统
2.6.1 中断控制器
LPC1100 系列集成了嵌套向量中断控制器(NVIC),用于管理和处理中断。NVIC 支持多个中断源,并且可以配置中断优先级。
2.6.1.1 中断配置
以下是一个配置中断的示例代码:
// 配置中断
void configure_interrupt(void) {
// 使能外部中断
LPC_SC->EXTINT = (1 << 0); // 使能外部中断 0
LPC_SC->EXTMODE = (1 << 0); // 设置外部中断 0 为边沿触发
LPC_SC->EXTPOLAR = (1 << 0); // 设置外部中断 0 为上升沿触发
// 使能定时器中断
NVIC_EnableIRQ(TIMER16B1_IRQn); // 使能定时器 16B1 中断
// 配置中断优先级
NVIC_SetPriority(TIMER16B1_IRQn, 1); // 设置定时器 16B1 中断优先级为 1
}
2.6.2 中断服务例程
以下是一个中断服务例程(ISR)的示例代码:
// 定时器中断处理函数
void TIMER16B1_IRQHandler(void) {
// 清除中断标志
LPC_TMR16B1->IR = (1 << 0); // 清除 MR0 匹配中断标志
// 处理定时器中断事件
// 例如,切换一个 LED 的状态
if (LPC_GPIO->PIN & (1 << 0)) {
LPC_GPIO->CLR = (1 << 0); // 关闭 P0.0
} else {
LPC_GPIO->SET = (1 << 0); // 打开 P0.0
}
}
// 外部中断处理函数
void EINT0_IRQHandler(void) {
// 清除中断标志
LPC_SC->EXTINT = (1 << 0); // 清除外部中断 0 标志
// 处理外部中断事件
// 例如,点亮一个 LED
LPC_GPIO->SET = (1 << 1); // 打开 P0.1
}
2.7 调试支持
2.7.1 调试接口
LPC1100 系列微控制器支持多种调试接口,如 JTAG 和 SWD(单线调试)。这些接口用于开发和调试过程中的程序下载和运行状态监控。
2.7.1.1 JTAG 接口
JTAG 接口是一种标准的调试接口,支持多线调试和边界扫描。以下是一个启用 JTAG 接口的示例代码:
// 启用 JTAG 接口
void enable_jtag(void) {
// 使能 JTAG 接口
LPC_SC->EXTMODE = (1 << 4); // 使能 JTAG 接口
}
2.7.1.2 SWD 接口
SWD 接口是一种单线调试接口,适用于资源受限的应用。以下是一个启用 SWD 接口的示例代码:
// 启用 SWD 接口
void enable_swd(void) {
// 使能 SWD 接口
LPC_SC->EXTMODE &= ~(1 << 4); // 禁用 JTAG 接口
LPC_SC->EXTMODE |= (1 << 5); // 使能 SWD 接口
}
2.7.2 调试寄存器
调试寄存器用于控制调试接口和调试功能。以下是一些常用的调试寄存器:
- DHCSR:调试硬件控制状态寄存器,用于控制调试状态。
- DEMCR:调试事件控制寄存器,用于配置调试事件。
- DSCR:调试状态控制寄存器,用于读取调试状态。
以下是一个配置调试寄存器的示例代码:
// 配置调试寄存器
void configure_debug_registers(void) {
// 使能调试
LPC_SC->DHCSR |= (1 << 0); // 使能调试
// 配置调试事件
LPC_SC->DEMCR |= (1 << 24); // 使能核心调试事件
// 读取调试状态
uint32_t debug_status = LPC_SC->DSCR;
}
2.8 总结
LPC1100 系列微控制器基于 ARM Cortex-M0 内核,具有低功耗、高性能、小尺寸和丰富的外设等特点。时钟系统、电源管理、存储器和外设的配置和使用通过寄存器进行控制。中断系统和调试支持使得开发和调试过程更加便捷。通过本文档的介绍,开发者可以更好地理解和使用 LPC1100 系列微控制器的各项功能。
标签:架构,示例,void,配置,硬件,LPC1100,LPC,2.5,时钟 From: https://blog.csdn.net/chenlz2007/article/details/143417483