1 GPIO初始化的几个关键代码
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
GPIO_InitTypeDef GPIO_PC2_InitStruct;
GPIO_PC2_InitStruct.GPIO_Pin = GPIO_Pin_2;
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
GPIO_Init(GPIOC, &GPIO_PC2_InitStruct);
以下是stm32对GPIO初始化的几个关键代码,初学者不容易理解,因而自行写了C语言的范例。
2 C语言写的简单结构体初始化范例
用简单的例子展示了结构体的使用、自定义函数的实现以及结构体成员值的复制操作,认真消化就可以对stm32以上代码深刻理解:
/online run c @: https://www.onlinegdb.com/online_c_compiler
// DEV C++6.3安装 https://blog.csdn.net/WeiHao0240/article/details/113757133
// hello world 范例: file- new- project- 选下面的hello world 和 点击 下面的选C
// 中文无法显示看:https://blog.csdn.net/h465705089/article/details/124711035
#include <stdio.h>
//#include <string.h> // when use this, change strCopy to strcpy
#define a (struct Person*)(&p1)
#define b (&p2)
// here we use strCopy , instead strcpy from string.h
void strCopy(char *destination, char *source) {
int i = 0;
while (source[i]!= '\0') {
destination[i] = source[i];
i++;
}
destination[i] = '\0';
}
struct Person {
char name[50];
int age;
};
struct Person p0,p1,p2;
void IntP(struct Person* ptrPerson1, struct Person* ptrPerson2) {
strCopy(ptrPerson1->name, ptrPerson2->name);//
ptrPerson1->age = ptrPerson2->age;
}
int main() {
strCopy(p0.name, "Asdf");// 初始化 p0
p0.age = 15;
IntP(a, &p0);
IntP(b, &p0);
printf("Now, p1 来自 p0 , p1.name: %s, age: %d\n", p1.name, p1.age);
printf("Now, p2 来自 p0 , p2.name: %s, age: %d\n", p2.name, p2.age);
return 0;
}
3 define a (struct Person*)(&p1)` 和 `#define b (&p2)` 这两个宏定义有以下不同之处:
1. **类型转换**:
- `#define a (struct Person*)(&p1)`:这个宏定义中,`&p1` 的地址被显式地转换为 `struct Person*` 类型。这意味着在使用 `a` 时,编译器会将它视为一个指向 `struct Person` 类型的指针。这种类型转换在C语言中是合法的,因为 `p1` 本身就是 `struct Person` 类型的变量,所以它的地址自然可以被视为指向 `struct Person` 的指针。
- `#define b (&p2)`:这个宏定义中,`&p2` 的地址直接被定义为 `b`。这里没有进行类型转换,因为 `&p2` 的类型已经是 `struct Person*`,即指向 `struct Person` 类型的指针。
2. **使用场景**:
- `a` 的定义中包含了类型转换,这可能是因为在某些上下文中,需要明确指出这是一个指向 `struct Person` 的指针。这种转换在实际使用中可能不是必需的,但在这里可能是为了强调或确保类型的一致性。
- `b` 的定义则直接使用了指针,没有进行额外的类型转换,因为 `&p2` 的类型已经是指向 `struct Person` 的指针。
总结来说,两者的主要区别在于 `a` 进行了类型转换,而 `b` 没有。在实际使用中,如果没有特殊需要,通常不需要进行额外的类型转换,因为变量的地址类型已经符合所需类型。
(这部分用deepseek 生成,推荐下)
4 以下是对这段代码的详细解释:
- 开头的几个注释是关于代码的运行环境、安装说明以及相关问题的解决链接。
#include <stdio.h>
:这是一个预处理指令,用于包含标准输入输出头文件,以便后续使用其中定义的函数,如printf
。#define a (&p1)
和#define b (&p2)
:这是宏定义,将a
定义为&p1
(即p1
的地址),将b
定义为&p2
(即p2
的地址)。void strCopy(char *destination, char *source)
函数:这是一个自定义的字符串复制函数,通过循环逐个字符地将源字符串复制到目标字符串,直到遇到源字符串的结束符'\0'
,并在目标字符串末尾添加结束符。struct Person
结构体:定义了一个名为Person
的结构体,包含两个成员:一个字符数组name
用于存储名字,一个整数age
用于存储年龄。- 定义了三个
struct Person
类型的变量p0
、p1
和p2
。 void IntP(struct Person* ptrPerson1, struct Person* ptrPerson2)
函数:该函数用于将第二个参数所指向的结构体的成员值复制到第一个参数所指向的结构体中,包括字符串成员name
和整数成员age
。int main()
函数:这是主函数,程序的入口点。strCopy(p0.name, "Asdf");
:初始化p0
结构体中的name
成员为"Asdf"
。p0.age = 15;
:初始化p0
结构体中的age
成员为 15 。IntP(a, &p0);
:将p0
的成员值复制到p1
。IntP(b, &p0);
:将p0
的成员值复制到p2
。- 最后通过
printf
函数输出p1
和p2
的信息。
5 运行环境:
有的编译器不成功,以下可以
//online run c @:http:// https://www.onlinegdb.com/online_c_compiler
// DEV C++6.3安装 https://blog.csdn.net/WeiHao0240/article/details/113757133
本人没采用安装版本,不好设置,使用这个版本正常运行:https://github.com/Embarcadero/Dev-Cpp/releases/download/v6.3/Embarcadero_Dev-Cpp_6.3_TDM-GCC_9.2_Portable.7z
// hello world 范例: file- new- project- 选下面的hello world 和 点击 下面的选C