LPC1100 系列_5.外设接口详解

5. 外设接口详解

在这里插入图片描述

5.1 GPIO(通用输入输出端口)

5.1.1 GPIO 基本原理

通用输入输出端口(GPIO)是单片机中最基本的外设接口之一,用于控制外部设备的输入和输出。GPIO 可以配置为输入或输出模式,具有多种功能,如中断检测、上拉/下拉电阻配置等。LPC1100 系列单片机的 GPIO 端口通常由多个寄存器控制,包括数据寄存器、方向寄存器、中断寄存器等。

5.1.2 GPIO 寄存器

LPC1100 系列单片机的 GPIO 寄存器主要包括以下几类:

  • 数据寄存器(FIOxSET 和 FIOxCLR):用于设置或清除端口的输出值。
  • 方向寄存器(FIODIR):用于配置端口的方向,即输入或输出。
  • 中断寄存器(FIOINTENSET/FIOINTENCLR、FIOINTSTATR/FIOINTSTATF、FIOINTSTATR):用于配置和检测 GPIO 中断。
  • 状态寄存器(FIOPIN):用于读取端口的输入值。

5.1.3 GPIO 配置

GPIO 的配置通常包括以下几个步骤:

  1. 配置端口方向:使用 FIODIR 寄存器设置端口为输入或输出。
  2. 设置初始输出值:使用 FIOxSETFIOxCLR 寄存器设置端口的初始输出值。
  3. 配置中断:使用 FIOINTENSETFIOINTENCLR 寄存器启用或禁用中断,使用 FIOINTSTATRFIOINTSTATF 寄存器检测中断状态。

5.1.4 GPIO 示例

5.1.4.1 配置 GPIO 为输出

以下示例代码展示了如何配置 GPIO 为输出并控制 LED 的亮灭:

#include "LPC11xx.h"

#define LED_PORT (1)          // LED 连接在 PORT1
#define LED_PIN  (21)         // LED 连接在 PIN21

void GPIO_Init(void) {
    // 配置 GPIO 方向
    LPC_GPIO1->DIR |= (1 << LED_PIN);  // 设置 GPIO1 的 PIN21 为输出
}

void LED_Toggle(void) {
    // 切换 LED 状态
    LPC_GPIO1->DATA ^= (1 << LED_PIN);  // 切换 GPIO1 的 PIN21 输出值
}

int main(void) {
    // 初始化 GPIO
    GPIO_Init();

    while (1) {
        LED_Toggle();  // 切换 LED 状态
        for (int i = 0; i < 1000000; i++) {  // 延时
            __NOP();
        }
    }
}
5.1.4.2 配置 GPIO 为输入并检测按键

以下示例代码展示了如何配置 GPIO 为输入并检测按键的状态:

#include "LPC11xx.h"

#define BUTTON_PORT (0)       // 按键连接在 PORT0
#define BUTTON_PIN  (7)       // 按键连接在 PIN7

void GPIO_Init(void) {
    // 配置 GPIO 方向
    LPC_GPIO0->DIR &= ~(1 << BUTTON_PIN);  // 设置 GPIO0 的 PIN7 为输入
    LPC_GPIO0->DIR |= (1 << LED_PIN);     // 设置 GPIO1 的 PIN21 为输出
}

void GPIO_ISR(void) __attribute__((naked));
void GPIO_ISR(void) {
    // 中断处理函数
    if (LPC_GPIO0->INTSTATR & (1 << BUTTON_PIN)) {
        // 按键被按下
        LPC_GPIO1->DATA ^= (1 << LED_PIN);  // 切换 LED 状态
        LPC_GPIO0->INTCLR = (1 << BUTTON_PIN);  // 清除中断标志
    }
}

int main(void) {
    // 初始化 GPIO
    GPIO_Init();

    // 启用按键中断
    LPC_GPIO0->INTENSET = (1 << BUTTON_PIN);  // 启用 GPIO0 的 PIN7 中断
    NVIC_EnableIRQ(GPIO0_IRQn);  // 启用 GPIO0 中断

    while (1) {
        // 主循环
    }
}

5.1.5 GPIO 中断配置

GPIO 中断配置包括以下几个步骤:

  1. 配置中断源:使用 FIOINTENSET 寄存器启用特定的中断源。
  2. 配置中断触发条件:使用 FIOINTMODE 寄存器设置中断触发条件,如上升沿、下降沿或电平触发。
  3. 配置中断优先级:使用 NVIC(嵌套向量中断控制器)配置中断优先级。
  4. 编写中断处理函数:编写中断处理函数,处理中断事件。

5.1.6 GPIO 性能优化

  • 时序优化:合理设置延时,确保 GPIO 的切换频率符合系统要求。
  • 功耗优化:在不需要使用 GPIO 时,将其配置为高阻态以降低功耗。
  • 中断处理优化:减少中断处理函数的执行时间,提高系统的响应速度。

5.2 UART(通用异步收发传输器)

5.2.1 UART 基本原理

通用异步收发传输器(UART)用于实现串行通信,可以发送和接收数据。LPC1100 系列单片机的 UART 模块通常包括发送器、接收器和波特率生成器等组件。

5.2.2 UART 寄存器

LPC1100 系列单片机的 UART 寄存器主要包括以下几类:

  • 数据寄存器(USARTx_THR/USARTx_RBR):用于发送和接收数据。
  • 状态寄存器(USARTx_IIR/USARTx_ISR、USARTx_LSR):用于检测 UART 的状态,如接收缓冲区是否为空、发送缓冲区是否满等。
  • 控制寄存器(USARTx_LCR、USARTx_FCR、USARTx_MCR):用于配置 UART 的工作模式,如波特率、数据位、停止位等。
  • 波特率寄存器(USARTx_DLL/USARTx_DLM):用于设置 UART 的波特率。

5.2.3 UART 配置

UART 的配置通常包括以下几个步骤:

  1. 配置波特率:根据通信需求设置波特率。
  2. 配置数据格式:设置数据位、停止位和校验位。
  3. 使能 UART 模块:使能 UART 模块并配置中断。
  4. 初始化 UART:初始化 UART 的寄存器。

5.2.4 UART 示例

5.2.4.1 初始化 UART

以下示例代码展示了如何初始化 UART0,配置其波特率为 9600,并发送字符串 “Hello, World!”:

#include "LPC11xx.h"

void UART_Init(void) {
    // 使能 UART0 时钟
    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);  // 使能 UART0 时钟

    // 配置波特率
    LPC_USART0->LCR = 0x83;  // 8 位数据,无校验,1 位停止位,使能除法器
    LPC_USART0->DLL = 12;    // 设置 DLL 寄存器
    LPC_USART0->DLM = 0;     // 设置 DLM 寄存器
    LPC_USART0->LCR = 0x03;  // 8 位数据,无校验,1 位停止位

    // 使能 FIFO
    LPC_USART0->FCR = 0x07;  // 使能 FIFO,并清空接收和发送 FIFO

    // 配置中断
    LPC_USART0->IER = 0x01;  // 使能接收中断
    NVIC_EnableIRQ(USART0_IRQn);  // 使能 USART0 中断
}

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

void UART_SendString(char *str) {
    while (*str) {
        UART_SendChar(*str++);  // 发送字符串中的每个字符
    }
}

void USART0_IRQHandler(void) {
    // UART0 中断处理函数
    if (LPC_USART0->IIR & 0x01) {
        char ch = LPC_USART0->RBR;  // 读取接收缓冲区中的字符
        UART_SendChar(ch);  // 发送接收到的字符
    }
}

int main(void) {
    // 初始化 UART
    UART_Init();

    // 发送字符串
    UART_SendString("Hello, World!");

    while (1) {
        // 主循环
    }
}

5.2.5 UART 通信协议

UART 通信协议包括以下几个要素:

  • 波特率:通信速率,通常以 bps(位每秒)为单位。
  • 数据位:数据帧中的数据位数,通常为 5 到 8 位。
  • 停止位:数据帧结束时的位数,通常为 1 或 2 位。
  • 校验位:用于数据校验,可以是奇校验、偶校验或无校验。

5.2.6 UART 性能优化

  • 波特率优化:根据通信需求选择合适的波特率,提高通信效率。
  • 中断处理优化:减少中断处理函数的执行时间,提高系统的响应速度。
  • 数据缓冲优化:使用缓冲区管理数据流,减少数据溢出的风险。

5.3 SPI(串行外设接口)

5.3.1 SPI 基本原理

串行外设接口(SPI)是一种同步串行通信接口,用于主设备和从设备之间的高速通信。SPI 通常包括四条信号线:MOSI(主设备输出,从设备输入)、MISO(主设备输入,从设备输出)、SCLK(时钟信号)和 SS(从设备选择信号)。

5.3.2 SPI 寄存器

LPC1100 系列单片机的 SPI 寄存器主要包括以下几类:

  • 控制寄存器(SPIxCR、SPIxCFG):用于配置 SPI 的工作模式,如主模式或从模式、数据长度等。
  • 状态寄存器(SPIxSTAT):用于检测 SPI 的状态,如数据是否准备好、错误状态等。
  • 数据寄存器(SPIxTXDAT、SPIxRXDAT):用于发送和接收数据。
  • 中断寄存器(SPIxINTEN、SPIxINTSTAT):用于配置和检测 SPI 中断。

5.3.3 SPI 配置

SPI 的配置通常包括以下几个步骤:

  1. 配置 SPI 模式:选择主模式或从模式。
  2. 配置数据长度:设置数据帧的长度。
  3. 配置时钟极性和相位:设置 SCLK 的极性和相位。
  4. 使能 SPI 模块:使能 SPI 模块并配置中断。

5.3.4 SPI 示例

5.3.4.1 初始化 SPI

以下示例代码展示了如何初始化 SPI0,配置其为主模式,并发送和接收数据:

#include "LPC11xx.h"

#define SPI0_PORT (0)
#define SPI0_MOSI_PIN (25)
#define SPI0_MISO_PIN (26)
#define SPI0_SCLK_PIN (27)
#define SPI0_SSEL_PIN (28)

void SPI_Init(void) {
    // 使能 SPI0 时钟
    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13);  // 使能 SPI0 时钟

    // 配置引脚
    LPC_IOCON->P0_25 = (LPC_IOCON->P0_25 & ~0x0F) | 0x02;  // 配置 P0.25 为 SPI0 MOSI
    LPC_IOCON->P0_26 = (LPC_IOCON->P0_26 & ~0x0F) | 0x02;  // 配置 P0.26 为 SPI0 MISO
    LPC_IOCON->P0_27 = (LPC_IOCON->P0_27 & ~0x0F) | 0x02;  // 配置 P0.27 为 SPI0 SCLK
    LPC_IOCON->P0_28 = (LPC_IOCON->P0_28 & ~0x0F) | 0x02;  // 配置 P0.28 为 SPI0 SSEL

    // 配置 SPI0
    LPC_SPI0->CR = 0x02;  // 使能 SPI0,主模式
    LPC_SPI0->CFG = 0x08;  // 8 位数据长度
    LPC_SPI0->BR = 0x00;  // 设置波特率
}

void SPI_SendChar(char ch) {
    while (!(LPC_SPI0->STAT & 0x02));  // 等待发送缓冲区为空
    LPC_SPI0->TXDAT = ch;  // 发送字符
}

char SPI_ReceiveChar(void) {
    while (!(LPC_SPI0->STAT & 0x01));  // 等待接收缓冲区有数据
    return LPC_SPI0->RXDAT;  // 读取接收缓冲区中的数据
}

int main(void) {
    // 初始化 SPI
    SPI_Init();

    // 发送数据
    SPI_SendChar('H');
    SPI_SendChar('e');
    SPI_SendChar('l');
    SPI_SendChar('l');
    SPI_SendChar('o');

    // 接收数据
    char received_data = SPI_ReceiveChar();
    while (1) {
        // 主循环
    }
}

5.3.5 SPI 通信协议

SPI 通信协议包括以下几个要素:

  • 主从模式:主设备控制通信,从设备被动响应。
  • 数据长度:数据帧中的数据位数,通常为 8 位。
  • 时钟极性和相位:SCLK 的极性和相位,用于同步数据传输。
  • 从设备选择:通过 SSEL 信号选择从设备。

5.3.6 SPI 性能优化

  • 时钟频率优化:根据通信需求选择合适的时钟频率,提高通信速度。
  • 数据缓冲优化:使用缓冲区管理数据流,减少数据溢出的风险。
  • 中断处理优化:减少中断处理函数的执行时间,提高系统的响应速度。

5.4 I2C(内部集成电路总线)

5.4.1 I2C 基本原理

内部集成电路总线(I2C)是一种同步串行通信接口,用于主设备和从设备之间的通信。I2C 总线包括两条信号线:SDA(数据线)和 SCL(时钟线)。I2C 支持多主设备和多从设备,具有简单、可靠的通信特点。

5.4.2 I2C 寄存器

LPC1100 系列单片机的 I2C 寄存器主要包括以下几类:

  • 控制寄存器(I2C0CONSET、I2C0CONCLR):用于配置 I2C 的工作模式,如主模式或从模式、启动和停止条件等。
  • 状态寄存器(I2C0STAT):用于检测 I2C 的状态,如数据是否准备好、错误状态等。
  • 数据寄存器(I2C0DAT):用于发送和接收数据。
  • 配置寄存器(I2C0ADR、I2C0SCLH、I2C0SCLL):用于配置 I2C 的地址和时钟频率。

5.4.3 I2C 配置

I2C 的配置通常包括以下几个步骤:

  1. 配置 I2C 模式:选择主模式或从模式。
  2. 配置时钟频率:设置 I2C 的时钟频率。
  3. 配置设备地址:设置主设备或从设备的地址。
  4. 使能 I2C 模块:使能 I2C 模块并配置中断。

5.4.4 I2C 示例

5.4.4.1 初始化 I2C

以下示例代码展示了如何初始化 I2C0,配置其为主模式,并发送和接收数据:

#include "LPC11xx.h"

#define I2C0_SDA_PIN (23)
#define I2C0_SCL_PIN (24)
#define I2C0_DEVICE_ADDR (0x50)  // 设备地址

void I2C_Init(void) {
    // 使能 I2C0 时钟
    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 16);  // 使能 I2C0 时钟

    // 配置引脚
    LPC_IOCON->P0_23 = (LPC_IOCON->P0_23 & ~0x0F) | 0x02;  // 配置 P0.23 为 I2C0 SDA
    LPC_IOCON->P0_24 = (LPC_IOCON->P0_24 & ~0x0F) | 0x02;  // 配置 P0.24 为 I2C0 SCL

    // 配置 I2C0
    LPC_I2C0->CONSET = 0x02;  // 使能 I2C0,主模式
    LPC_I2C0->ADR = I2C0_DEVICE_ADDR;  // 设置设备地址
    LPC_I2C0->SCLH = 0x04;  // 设置 SCL 高电平时间
    LPC_I2C0->SCLL = 0x0A;  // 设置 SCL 低电平时间
    LPC_I2C0->CONSET |= (1 << 6);  // 使能 I2C0
}

void I2C_Start(void) {
    // 发送启动条件
    LPC_I2C0->CONSET |= (1 << 2);  // 设置启动位
    while (LPC_I2C0->STAT != 0x08);  // 等待启动条件被识别
}

void I2C_Stop(void) {
    // 发送停止条件
    LPC_I2C0->CONCLR = (1 << 4);  // 清除启动位
    LPC_I2C0->CONSET |= (1 << 4);  // 设置停止位
    while (LPC_I2C0->STAT != 0x18);  // 等待停止条件被识别
}

void I2C_SendByte(char data) {
    // 发送一个字节
    LPC_I2C0->DAT = data;  // 设置数据寄存器
    while (!(LPC_I2C0->CONSET & (1 << 5)));  // 等待数据传输完成
    LPC_I2C0->CONCLR = (1 << 5);  // 清除数据传输完成标志
}

char I2C_ReceiveByte(void) {
    // 接收一个字节
    LPC_I2C0->CONSET |= (1 << 5);  // 使能接收
    while (LPC_I2C0->STAT != 0x50);  // 等待数据准备好
    char data = LPC_I2C0->DAT;  // 读取数据寄存器
    LPC_I2C0->CONCLR = (1 << 5);  // 清除接收完成标志
    return data;
}

void I2C_Write(char addr, char reg, char data) {
    I2C_Start();
    I2C_SendByte(addr << 1);  // 发送目标设备地址,写模式
    I2C_SendByte(reg);  // 发送寄存器地址
    I2C_SendByte(data);  // 发送数据
    I2C_Stop();
}

char I2C_Read(char addr, char reg) {
    I2C_Start();
    I2C_SendByte((addr << 1) | 1);  // 发送目标设备地址,读模式
    char data = I2C_ReceiveByte();
    I2C_Stop();
    return data;
}

int main(void) {
    // 初始化 I2C
    I2C_Init();

    // 发送数据
    I2C_Write(I2C0_DEVICE_ADDR, 0x01, 0x55);  // 向地址 0x50 的设备的寄存器 0x01 写入 0x55

    // 接收数据
    char received_data = I2C_Read(I2C0_DEVICE_ADDR, 0x01);  // 从地址 0x50 的设备的寄存器 0x01 读取数据

    while (1) {
        // 主循环
    }
}

5.4.5 I2C 通信协议

I2C 通信协议包括以下几个要素:

  • 主从模式:主设备控制通信,从设备被动响应。
  • 设备地址:每个从设备在 I2C 总线上都有唯一的 7 位或 10 位地址。
  • 数据长度:每次传输的数据长度通常为 1 到 32 位。
  • 时钟频率:标准模式下 I2C 的时钟频率为 100 kHz,快速模式下为 400 kHz,高速模式下为 3.4 MHz。
  • 启动和停止条件:主设备通过发送启动和停止条件来控制通信的开始和结束。

5.4.6 I2C 性能优化

  • 时钟频率优化:根据通信需求选择合适的时钟频率,提高通信速度。
  • 数据缓冲优化:使用缓冲区管理数据流,减少数据溢出的风险。
  • 中断处理优化:减少中断处理函数的执行时间,提高系统的响应速度。
  • 总线负载优化:合理安排总线上的设备,避免总线负载过重导致通信失败。

通过以上配置和示例代码,可以更好地理解和使用 LPC1100 系列单片机的 GPIO、UART 和 SPI 外设接口。这些接口在嵌入式系统中非常常见,掌握它们的配置和使用方法对于开发高效的嵌入式应用至关重要。希望这些内容对您的开发工作有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值