STM32常用C语言知识总结

瑞星  金牌会员 | 2024-8-20 19:34:14 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 535|帖子 535|积分 1605


目录

一、引言
二、C 语言底子
1.数据类型
2.变量与常量
3.控制布局
4.数组与指针
 5.字符串
6. extern变量声明
7.内存管理 
三、STM32 中的 C 语言特性
1.位操作
2.寄存器操作


一、引言


STM32 作为一款广泛应用的微控制器,其开发离不开 C 语言的支持。C 语言凭借其高效、灵活和可移植性,成为了嵌入式系统开发的首选语言。本文将对 STM32 开发中涉及的 C 语言知识点进行具体总结,资助大家更好地把握 STM32 的开发。

二、C 语言底子

1.数据类型

基本数据类型:包括整型(int、short、long)、浮点型(float、double)、字符型(char)等。
stdint.h中的类型:在STM32开发中,经常利用stdint.h头文件中的类型界说,如int8_t、uint16_t、int32_t等,以确保数据类型的跨平台一致性。
派生数据类型:指针(*)、数组([])、布局体(struct)、共用体(union)等。
示例:
  1.     int num = 10;
  2.     float pi = 3.14;
  3.     char ch = 'A';
  4.     int8_t=10;
  5.     struct Point {
  6.         int x;
  7.         int y;
  8.     };
  9.     union Data {
  10.         int i;
  11.         float f;
  12.     };
复制代码
 
2.变量与常量



  • 变量的界说和初始化:变量在利用前必须先界说,并可以在界说时进行初始化。
  • 常量的界说:利用#define宏界说或const关键字界说常量。
    示例:
  1.     int a = 5;  // 定义并初始化变量
  2.     #define PI 3.14  // 宏定义常量
  3.     const float E = 2.718;  // 使用 const 定义常量
复制代码

3.控制布局



  • 顺序布局:步伐按照语句的誊写顺序依次实行。
  • 选择布局:包括if-else语句和switch-case语句。
  • 循环布局:for循环、while循环和do-while循环。
  示例:
  1. int num = 10;
  2.     if (num > 5) {
  3.         printf("Num is greater than 5\n");
  4.     } else {
  5.         printf("Num is less than or equal to 5\n");
  6.     }
  7.     int choice = 2;
  8.     switch (choice) {
  9.         case 1:
  10.             printf("Choice is 1\n");
  11.             break;
  12.         case 2:
  13.             printf("Choice is 2\n");
  14.             break;
  15.         default:
  16.             printf("Invalid choice\n");
  17.             break;
  18.     }
  19.     for (int i = 0; i < 5; i++) {
  20.         printf("%d ", i);
  21.     }
复制代码

4.数组与指针



  • 数组的界说、初始化和访问:数组是一组类似类型元素的聚集。
  • 指针的概念和操作:指针是一个变量,其值为另一个变量的地址。
   指针与数组的关系: 
  数组名在很多情况下会被当作指向数组首元素的指针来利用。比方,当将数组名传递给函数时,现实上传递的是一个指向数组首元素的指针。
  
  通过指针的算术运算,可以实现类似数组下标的操作来访问数组元素。比方,如果有一个指针 p 指向一个数组的首元素,那么 p + i 就指向了数组的第 i 个元素。
    示例:
  1. #include <stdio.h>
  2. int main() {
  3.     int arr[] = {1, 2, 3, 4, 5};
  4.     int *ptr = arr;  // 此时数组名相当于指向首元素的指针
  5.     printf("%d\n", arr[0]);  // 通过数组下标访问
  6.     printf("%d\n", *(ptr + 0));  // 通过指针的算术运算访问
  7.     ptr = &arr[2];  // 指针可以改变指向
  8.     printf("%d\n", *ptr);  // 输出 3
  9.     // 不能修改数组名的指向
  10.     // arr = &arr[1];  // 这是错误的
  11.     return 0;
  12. }素
复制代码
 5.字符串



  • 字符串的表示:利用字符数组或字符指针。
  • 字符串操作函数:如strcpy、strcat、strcmp等。
示例:
  1.     char str1[] = "Hello";
  2.     char *str2 = "World";
  3.     strcpy(str1, str2);  // 复制字符串
复制代码
6. extern变量声明

extern 声明只是告诉编译器该变量在其他地方已经界说,并不为变量分配内存空间,通常用于在多个源文件之间共享全局变量。
示例:
假设有两个源文件 file1.c 和 file2.c 。
在 file1.c 中界说一个全局变量:
  1. int global_variable = 10;  // 定义并初始化全局变量
复制代码
在 file2.c 中利用 extern 声明来访问这个全局变量: 
  1. extern int global_variable;  // 声明该变量在其他文件中已定义
  2. int main() {
  3.     printf("%d\n", global_variable);  // 可以使用该全局变量
  4.     return 0;
  5. }
复制代码
这样,在 file2.c 中就可以通过 extern 声明来利用在 file1.c 中界说的全局变量 global_variable 。
需要注意的是,利用 extern 声明变量时,要确保在其他地方确实有该变量的界说,否则会导致链接错误。
7.内存管理 

malloc、memset 和 free 是三个常用的库函数,用于动态内存管理。
(1) malloc 函数:
malloc 函数用于在堆上动态分配内存。它的函数原型为:
  1. void *malloc(size_t size);
复制代码
size 参数指定要分配的字节数。malloc 函数返回一个指向分配的内存块的指针,如果分配失败则返回 NULL 。
   示例:
  1. int *ptr = (int *)malloc(sizeof(int) * 10);  // 分配 10 个整数大小的内存
复制代码
 
 (2)memset 函数:
memset 函数用于将一段内存空间设置为指定的值。它的函数原型为:
  1. void *memset(void *str, int c, size_t n);
复制代码
 str 是要设置的内存块的指针,c 是要设置的值(以 int 形式传递,现实设置时会转换为 unsigned char 类型),n 是要设置的字节数。
   示例:
  1. memset(ptr, 0, sizeof(int) * 10);  // 将之前分配的内存初始化为 0
复制代码
 
(3)free 函数:
free 函数用于开释之前由 malloc 等函数分配的内存。它的函数原型为:
  1. void free(void *ptr);
复制代码
ptr 是要开释的内存块的指针。
   示例:
  1. free(ptr);  // 释放之前分配的内存
复制代码
 
 
三、STM32 中的 C 语言特性

1.位操作



  • 位域:用于界说布局体中的位变量。
  • 位运算:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)。
 示例:
  1.     struct Flags {
  2.         unsigned int flag1 : 1;
  3.         unsigned int flag2 : 1;
  4.     };
  5.     unsigned int num = 5;
  6.     num = num << 2;  // 左移操作
复制代码
2.寄存器操作



  • 直接访问寄存器:通过指针或宏界说来访问寄存器地址。
  • 寄存器位操作:利用位掩码和位运算进行寄存器位的设置和扫除。
 volatile 关键字用于修饰可能被意外修改的变量,数据每次从内存中直接读取,不会被编译器优化导致数据不同步的题目。
  示例:
  1. #define GPIOA_BASE  (0x40020000UL)
  2. #define GPIOA_MODER  (*((volatile unsigned int *)(GPIOA_BASE + 0x00)))
  3. GPIOA_MODER |= (1 << 10);  // 设置 GPIOA 引脚 5 的模式
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

瑞星

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表