嵌入式C语言基础学习

嵌入式系统是专为执行特定任务而优化的计算机系统,它们常见于各种设备如汽车、家电及工业机器中。

在嵌入式系统的开发中,C语言由于其接近硬件的特性、执行效率高和可移植性强的优点,被广泛使用。

下面我将详细介绍嵌入式系统中C语言的基础知识,包括环境搭建、核心语法和实践技巧,以及如何在实际项目中应用这些知识。

1. 环境准备

开发硬件和软件
  • 硬件选择:常用的嵌入式开发板包括Arduino、STM32、Raspberry Pi等。选择何种开发板取决于项目需求和个人喜好。
  • 集成开发环境(IDE):推荐使用Keil MDK-ARM、IAR Embedded Workbench或STM32CubeIDE等。这些IDE提供了编译、调试和代码管理的一体化解决方案。
安装和配置
  • 安装IDE:下载并安装适合你开发板的IDE。
  • 配置工程:在IDE中创建新项目,并根据你的开发板配置项目设置,如选择正确的处理器型号和配置编译器选项。

2. C语言基础

数据类型和变量
  • 基本类型:了解intcharfloatdoublevoid
  • 修饰符:熟悉signedunsignedlongshort等修饰符的使用。
  • 变量声明:变量在使用前必须声明,可以初始化一个或多个变量。
控制结构
  • 条件语句ifelse ifelseswitch语句用于基于条件执行代码。
  • 循环forwhiledo...while循环用于重复执行代码块。
函数
  • 定义和调用:函数是组织好的代码块,它们执行特定任务。每个函数都有一个返回类型,可以是void
  • 参数传递:理解值传递和引用传递的区别。
指针和数组
  • 指针基础:指针是存储另一个变量地址的变量。在嵌入式编程中,指针用于直接访问硬件地址或动态内存管理。
  • 数组和字符串:数组是相同类型数据的集合。字符串在C中以字符数组形式表示,以null字符\0结束。

3. 嵌入式特有的编程考虑

直接寄存器访问
  • 使用指针操作特定硬件地址,例如,直接操作微控制器的GPIO端口。
中断服务例程(ISR)
  • 编写和配置ISR来处理硬件中断,如定时器溢出或外部事件。
内存管理
  • 了解静态和动态内存的分配方式,及其在嵌入式系统中的应用和限制。

4. 实战技巧

调试
  • 使用IDE的调试工具来单步执行程序,监视变量和寄存器。
单元测试
  • 对关键功能进行单元测试,确保代码的可靠性。
性能优化
  • 优化代码以减少CPU使用率和内存消耗。

5. 示例项目

LED闪烁

一个简单的嵌入式C语言项目

#include "stm32f1xx.h" // 包含特定于设备的头文件

// 假设LED连接到PA5
#define LED_PIN GPIO_PIN_5
#define LED_GPIO_PORT GPIOA
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()

void SystemClock_Config(void);
void GPIO_Init(void);

int main(void)
{
    HAL_Init(); // 初始化HAL库
    SystemClock_Config(); // 配置系统时钟
    LED_GPIO_CLK_ENABLE(); // 使能GPIO时钟
    GPIO_Init(); // 初始化GPIO

    while (1)
    {
        HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN); // 切换PA5引脚的状态
        HAL_Delay(500); // 延时500毫秒
    }
}

void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    // 配置时钟源、时钟预分频等
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    // 选择PLL作为系统时钟源并配置HCLK, PCLK1和PCLK2
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
}

void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // GPIOA Clock Enable
    __HAL_RCC_GPIOA_CLK_ENABLE();

    // 配置GPIO为输出模式,推挽输出
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}

void Error_Handler(void)
{
    // 用户可以添加错误处理代码
    __disable_irq();
    while (1)
    {
    }
}

说明

  1. SystemClock_Config:此函数配置微控制器的系统时钟。在此示例中,我们使用外部晶体振荡器(HSE)和PLL乘数,以提高系统时钟频率。
  2. GPIO_Init:设置GPIOA的5号引脚为输出模式,用于控制LED。
  3. main:在主循环中,通过HAL_GPIO_TogglePin切换LED的状态,并通过HAL_Delay实现延时,从而让LED以大约1秒的周期闪烁。

资料分享 

点击领取嵌入式stm32方向资料在这里我给大家准备了我自己整理的资料继续分享,对大家的嵌入式方向的学习有一定的帮助,以后也会无偿持续的去更新。

小结

上文提供了嵌入式C语言的基础学习路径,包括环境搭建、核心语法讲解、实际编程技巧和一个简单的实战项目。通过这些步骤,相信你已经对嵌入式有了一个简单 的认识。

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值