STM32知识点(1)常用基础C语言(长文总结)

下面就列出了一些STM32中重要的C语言知识点。

目录

引用

一、位操作

二、define宏定义

三、ifdef条件编译

四、extern变量申明

五、结构体

六、typedef类型别名

七、static

 八、函数

总结



引用

stm32常用c语言这里主要参考了

(19条消息) STM32常用C语言基础_菜鸡路上越走越远的菜鸡的博客-CSDN博客_stm32常用c语言https://blog.csdn.net/weixin_45941080/article/details/105225887?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164177177516780366560579%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164177177516780366560579&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-105225887.first_rank_v2_pc_rank_v29&utm_term=stm32&spm=1018.2226.3001.4187(19条消息) STM32 | STM32中一些非常重要的C语言知识点汇总_嵌入式大杂烩-CSDN博客_stm32语言https://blog.csdn.net/zhengnianli/article/details/112256241?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-5.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-5.no_search_link&utm_relevant_index=10


一、位操作

 位操作与位带操作并不相同,位操作就是对一个变量的每一位做运算,而逻辑位操作是对这个变量整体进行运算。下面是六种常用的操作运算符:

#include
//1、按位取反  ~
void test01()
{
	int num = 7;
	printf("~num = %d\n", ~num);//-8
	
	// 0111  按位取反   1000   机器中存放的都是补码   补码转换原码需要分有符号数和无符号数两种
}


//2、按位与
void test02()
{
	int num = 128;
	if ( (num & 1) == 0)    //换算为八位,1换算就是00000001, 这样只要所给数字的二进制最后一位是1.那么就是奇数,否则就是偶数
	{
		printf("num为偶数\n");
	}
	else
	{
		printf("num为奇数\n");
	}
}

//3、按位或  |
void test03()
{
	//按位异或的意思是,两个数字相同为0,不同为1。我们可以利用按位异或实现两个数的交换
	num01 = 1; // 0001
	num02 = 4; // 0100
	printf("num01 ^ num02 = %d", num01 ^ num02); // 5  两个二进制按位异或之后是: 0101

   	printf("交换前\n");
	printf("num01 = %d\n", num1);
	printf("num02 = %d\n", num2);

	num01 = num01 ^  num02;
	num02 = num01 ^  num02;
	num01 = num01 ^  num02;

	//不用临时数字实现两个变量交换
	printf("交换后\n");
	printf("num01 = %d\n", num1);
	printf("num02 = %d\n", num2);


}


//左移运算符
void test05()
{
	int num = 6;
	printf("%d\n", num << 3);//左移三位,就是0000


}

//右移运算符
void test06()
{
	int num = 6; //0110
	printf("%d\n", num >> 1); //右移一位,就是0011,输出3
}


int main(){

	test01();
	test02();
	test03();
	test05();
	test06();
	return 0;
}

二、define宏定义

define 是 C 语言中的预处理命令,它用于宏定义,可以提高源代码的可读性,为编程提供方便。常见的格式如下,标识符意思是所定义的宏名,字符串可以是常数、表达式或者格式串等:

#define 标识符 字符串
#define PLL_Q 7  //注意,这个定义语句的最后不需要加分号

三、ifdef条件编译

在程序开发的过程中,经常会用到这种条件编译。这段代码作用就是当这个标识符已经被定义过,那么就进行程序程序段1,如果没有则进行程序段2。当然,和我们设计普通的c代码是一样的,"#else"也可以没有,就是上面的代码减去"#else"和程序段2。

#ifdef PLL_Q
   程序段1
#else
	程序段2
#endif

四、extern变量申明

C 语言中 extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义(一个变量只能定义一次,而extern可以申明很多次)使用例子如下:

extern u16 USART_RX_STA; //申明 “USART_RX_STA” 这个变量在其他文件中已经定义了,"u16"的意思是16位的。

五、结构体

在程序开发的过程中,经常会用到这种条件编译。这段代码作用就是当这个标识符已经被定义过,那么就进行程序程序段1,如果没有则进行程序段2。当然,和我们设计普通的c代码是一样的,"#else"也可以没有,就是上面的代码减去"#else"和程序段2。

struct 结构名
{
	成员列表
};
//结构体例子
struct sutdent
{
	int num;
	char name[20];  //20个字节长的字符
	char sex;
	int age;
	float score;
	char addr[30]; //30个字节长的字符
}
//若我们想定义结构体变量,可以定义这个结构体时直接定义,或者定义完结构体再另外定义结构体变量
struct sutdent
{
	int num;
	char name[20];  //20个字节长的字符
	char sex;
	int age;
	float score;
	char addr[30]; //30个字节长的字符
}student01,student02; //变量名表列(如果由结构体变量名,那么我们可以不写结构体名称)
//结构体的嵌套
struct date
{
	int year, month,day;
};
struct sutdent
{
	int num;
	char name[20];  //20个字节长的字符
	char sex;
	struct date birthday; //这里就用到了结构体的嵌套
	int age;
	float score;
	char addr[30]; //30个字节长的字符
}student01,student02; //变量名表列(如果由结构体变量名,那么我们可以不写结构体名称)

 引用结构体里面的成员内容

student01.name = 小李; // 结构体变量名.成员名(注意这里用的是点),这里是对这个成员的赋值
struct student *pstu; //定义一个指向结构体"student"的指针变量pstu
//一个结构体指针变量赋初值,注意赋值方式,必须使用结构体变量(stu),而不能使用结构体名(student)
struct student
{
	char name[66];
	int num;
	char sex;
}stu;

pstu = &stu;
//访问结构体成员的一般形式
	(*pstu).name;   //(1)(*结构指针变量).成员名;
	pstu->name;   //(2)结构指针变量->成员名

六、typedef类型别名

typedef用来为现有类型创建一个新的名字,或者称为类型别名,用来简化变量的定义(上边extern变量申明的例子中,"u16"就是对"uint16_t"类型名称的简化)。typedef在MDK中用得最多的就是定义结构体的类型别名和枚举类型。我们定义一个结构体GPIO:

struct _GPIO
{
	_IO uint32_t MODER;
	_IO uint32_tOTYPER;
	...
};
struct _GPIO GPIOA;

 虽然也可以达到我们的目的,但是这样会比较麻烦,而且在MDK中会有很多地方用到,所以,我们可以使用"typedef"为其定义一个别名,这样直接通过这个别名就可以定义结构体变量,来达到我们的目的:

typedef struct
{
	_IO uint32_t MODER;
	_IO uint32_t OTYPER;
}GPIO_typedef;
GPIO_typedef_GPIOA,_GPIOB;

七、static

static主要有三种用法:在函数内用于修饰变量、用于修饰函数、用于修饰本.c文件全局变量。后两个容易理解,用于修饰函数与全局变量表明变量与函数在本模块内使用。

#include 

void test(void)
{
    int normal_var = 0;
    static int static_var = 0;

    printf("normal_var:%d  static_var:%d\n", normal_var, static_var);
    normal_var++;
    static_var++;
}

int main(void)
{
     int i;

     for ( i = 0; i < 3; i++)
     {
       test();
     }

     return 0;
}

可以看出,函数每次被调用,普通局部变量都是重新分配,而static修饰的变量保持上次调用的值不变,即只被初始化一次。

 八、函数

可以看出,函数每次被调用,普通局部变量都是重新分配,而static修饰的变量保持上次调用的值不变,即只被初始化一次。


总结

还有以后会继续补充

你可能感兴趣的:(stm32,c语言,arm)