ARM------硬件程序开发

发布于:2025-04-04 ⋅ 阅读:(14) ⋅ 点赞:(0)

硬件程序开发流程

  1. 相关硬件的工作原理

    • 理解硬件的工作原理,明确硬件的功能和用途。

  2. 硬件连接

    • 将硬件设备正确连接到开发板上。

  3. 编写程序

    • 根据硬件功能编写相应的程序代码。

  4. 调试验证

    • 通过调试工具验证程序的正确性,确保硬件功能正常。


控制LED的步骤

  1. 找到LED对应的丝印

    • 在开发板(PCB)上找到LED对应的丝印标识。

  2. 找到对应的器件

    • 在原理图中根据丝印找到对应的LED器件。

  3. 找到连接的处理器引脚

    • 确定LED连接到处理器的哪个引脚(如GPB5)。

  4. 控制引脚输出高低电平

    • 配置引脚功能为输出,并通过寄存器控制引脚输出高低电平。

一、LED灯点亮

寄存器配置

端口B控制寄存器(GPBCON, GPBDAT, GPBUP)
寄存器 地址 R/W 描述 复位值
GPBCON 0x56000010 R/W 配置端口B的引脚 0x0
GPBDAT 0x56000014 R/W 端口B的数据寄存器 -
GPBUP 0x56000018 R/W 端口B的上拉使能寄存器 0x0
GPBCON寄存器位配置
描述 初始状态
GPB5[11:10] 00 = 输入,01 = 输出,10 = nXBACK,11 = 保留 0
GPBDAT寄存器位配置
描述 初始状态
GPB5 当端口配置为输出时,控制引脚输出高低电平 -

代码实现

1. 初始化LED
void led1_init(void)
{
    // 配置GPB5引脚功能为输出
    gpio_cfg(GPB5, OUT);

    // 使GPB输出高电平(LED灭)
    GPBDAT |= (0xF << 5);
}
2. LED亮灯
void led1_on(void)
{
    // 输出低电平(LED亮)
    GPBDAT &= ~(0xF << 5);
}
3. LED灭灯
void led1_off(void)
{
    // 输出高电平(LED灭)
    GPBDAT |= (0xF << 5);
}
4. 流水灯效果
void led1_flow(void)
{
    for (int i = 0; i < 4; i++)
    {
        // 依次点亮不同的LED
        GPBDAT |= (0xF << 5);          // 所有LED灭
        GPBDAT &= ~(1 << (5 + i));     // 第i个LED亮
        delay(100000);                 // 延时
    }
}
5. 按键控制LED
void buttons(void)
{
    int eint4 = GPGDAT & 1;        // 检测EINT4按键状态
    int eint5 = (GPFDAT >> 4) & 0x1; // 检测EINT5按键状态
    int eint6 = (GPFDAT >> 5) & 0x1; // 检测EINT6按键状态
    int eint8 = (GPFDAT >> 6) & 0x1; // 检测EINT8按键状态

    // 根据按键状态控制对应的LED
    if (eint4 == 0) GPBDAT &= ~(1 << 5);  // EINT4按下,LED5亮
    else            GPBDAT |= (1 << 5);   // EINT4松开,LED5灭

    if (eint5 == 0) GPBDAT &= ~(1 << 6);  // EINT5按下,LED6亮
    else            GPBDAT |= (1 << 6);   // EINT5松开,LED6灭

    if (eint6 == 0) GPBDAT &= ~(1 << 7);  // EINT6按下,LED7亮
    else            GPBDAT |= (1 << 7);   // EINT6松开,LED7灭

    if (eint8 == 0) GPBDAT &= ~(1 << 8);  // EINT8按下,LED8亮
    else            GPBDAT |= (1 << 8);   // EINT8松开,LED8灭
}

二、时钟配置

1. 时钟分频寄存器 (CLKDIVN)

  • 地址: 0x4C000014

  • 功能: 控制HCLK和PCLK的分频比例。

  • 位域定义:

    • HCLK分频器: 位1 (HDIVN),用于设置HCLK的分频比例。

    • PCLK分频器: 位0 (PDIVN),用于设置PCLK的分频比例。

  • 配置方法:

    CLKDIVN = (0x2 << 1) | 0x1;  // 设置 HCLK 分频器为 2,PCLK 分频器为 1
    • HCLK 分频器: 2 (HCLK = PCLK * 3)

    • PCLK 分频器: 1 (PCLK = MPLLCLK / 2 / 2)

2. 主PLL寄存器 (MPLLCON)

  • 地址: 0x4C000004

  • 功能: 配置主PLL的输出时钟频率。

  • 位域定义:

    • M值: 位15-12 (MDIV),用于设置主分频器。

    • P值: 位11-8 (PDIV),用于设置预分频器。

    • S值: 位7-4 (SDIV),用于设置后分频器。

  • 计算公式:

    • MPLL输出频率: (M + 8) * Fin / (P * S)

    • 其中:

      • M = MDIV + 8

      • P = PDIV + 2

      • S = SDIV + 2

      • Fin = 外部时钟输入频率 (通常为 12 MHz)

  • 配置方法:

    MPLLCON = (127 << 12) | (2 << 4) | 1;  // 设置 M=127, P=2, S=1
    • M值: 127 + 8 = 135

    • P值: 2 + 2 = 4

    • S值: 1 + 2 = 3

    • 计算结果: MPLL 输出频率 = (135) * 12 MHz / (4 * 3) = 135 MHz

3. 时钟频率计算
  • MPLL输出频率: 135 MHz

  • HCLK频率: 135 MHz / (HCLK分频器 + 1) = 135 MHz / 3 = 45 MHz

  • PCLK频率: 135 MHz / (2 * (PCLK分频器 + 1)) = 135 MHz / (2 * 2) = 33.75 MHz


代码实现

#include "clk.h"
#include <s3c2440.h>

// 初始化时钟配置
void clk_init(void)
{
    // 配置时钟分频寄存器 (CLKDIVN)
    // 设置 HCLK 分频器为 2,PCLK 分频器为 1
    CLKDIVN = (0x2 << 1) | 0x1;

    // 配置主PLL寄存器 (MPLLCON)
    // 设置 M=127, P=2, S=1
    MPLLCON = (127 << 12) | (2 << 4) | 1;
}