微机原理之MSP432——基础知识(什锦)

1.位运算

符号 描述 运算规则
& 与 两个位都为1时,结果才为1
| 或 两个位都为0时,结果才为0
^ 异或 两个位相同为0,相异为1
~ 取反 0变1,1变0
<< 左移 各二进位全部左移若干位,高位丢弃,低位补0
>> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

2.RS232、TTL关系

内容来源于https://zhuanlan.zhihu.com/p/25893717

RS232通常出现在传统的PC和服务器领域,TTL通常用于嵌入式设备。

TTL全名是晶体管-晶体管逻辑集成电路(Transistor-Transistor Logic),这种串行通信,对应的物理电平,始终是在0V和Vcc之间,其中常见的Vcc是5V或3.3V。TTL 高电平1是>=2.4V,低电平0是<=0.5V(对于5V或3.3V电源电压),这里是正逻辑。

RS232接口的电平范围是**-15V到+15V。 在 单片机范围内,RS232由于没有负电源,所以使用非常规的接口电平0-5V**.如果需要和PC连接,需要进行电平转换成-15+15V才能被PC识别,逻辑1的电平为-3~-15V,逻辑0的电平为+3~+15V,注意电平的定义反相了一次。

RS232和TTL的时序对比:

RS232和TTL之间的转换,不仅仅是简单的电平转换,还要考虑到其他一些因素,比如调节和矫正一些电平(提高或降低对应的电平),确保可能的有害的RS232电压不会破坏微控制器的串口针脚。这里有很成熟的方案,我们可以通过MAX3232之类的芯片,把TTL电平转为RS232电平,或者简单的在淘宝购买TTL转RS232电缆即可。

MAX3232一端与单片机的引脚相连,另一端与RS232的串口相连,完成了TTL电平到RS232电平的转换。其原理图如下:

3.进制转换

3.1基数对照表

3.2十进制转二进制

十进制转二进制的转换原理:除以2,反向取余数,直到商为0终止。

3.3十进制转十六进制

十进制转二进制的转换原理:除以16,反向取余数,直到商为0终止。

4.嵌入式C语言improve

4.1 如何进入死循环

1
2
3
while(1)
{
}

4.2 do while 和 while 有什么区别

简而言之 do while 就是先执行do里面的内容再来判断是否符合条件,而while是先判断条件再执行花括号里面的内容。下面的例子一目了然。

1
2
3
4
5
6
7
8
9
10
11
//while
#include <stdio.h>
int main() {
int i = 0;
while (i < 0)
{
i++;
printf("%d\n", i);
}
return 0;
}
1
输出结果:无输出
1
2
3
4
5
6
7
// do while
int i = 0;
do
{
i++;
printf("%d\n", i);
}while (i < 0);
1
输出结果:1

4.3 定义变量

用变量a定义

  1. 一个整数型
  2. 一个指向整型数的指针
  3. 一个有10个整型数的数组
  4. 一个有10个指针的数组,该指针指向一个整型数
1
2
3
4
5
6
7
8
// 1.一个整型数
int a;
// 2.一个指向整型数的指针
int *a;
// 3.一个有10个整型数的数组
int a[10];
// 4.一个有10个指针的数组,该指针指向一个整型数
int *a[10]

4.4 关键字static的作用是什么

static有三种不同的用法

1.修饰局部变量,2.修饰全局变量,3.修饰函数

1.当我们用static修饰局部变量,那么这个变量在函数调用完之后不会被释放

2.当我们用static修饰全局变量,我们知道全局变量在不同的源文件中是可以使用的,只不过需要先用extern外部声明一下。但是当我们用static修饰时那么被修饰的变量只能在当前.c文件中访问

3.当我们用static修饰函数,那么被修饰的函数只能在当前.c文件中中访问

4.5 关键字const的作用是什么

const修饰的东西无法修改。(常量)

const常量与#define有本质上的区别,#define本质上是文本替换

4.6 定义一个标准宏MIN,这个宏输入两个参数并返回较小的一个

上面我们说过,宏定义本质上是文本替换,那么我们只要把他替换成函数不就行了?

宏的替换规则:
1.在调用宏的时候,首先检查参数,看看是否包含任何由#define定义的符号,如果是,首先它们被替换。

2.替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。

3.最后再次对结果文件进行扫描,看着它是否包含任何由#define定义的符号,如果是,就重复上述处理。

1
#define MIN(A,B) ( (A)<=(B)?(A):(B) )

4.7 寄存器位操作,给一个int变量a,将a的bit3置为1或0,并保证其他位不变

先说思路,先用位操作将0x01左移3位并赋值给BIT3,然后我们紧抓其他位不变的条件

将a与BIT3做按位或操作即可将a的bit3置为1且其他位保持不变

将a与~BIT3做按位与操作即可将a的bit3置为0且其他位保持不变

1
2
3
4
5
6
7
8
9
10
#define BIT3  (0x1<<3)
static int a;
void set_bit3(void)
{
a|=BIT3;
}
void clear_bit3(void)
{
a &=~BIT3;
}

4.8 设置0x5a00的整型变量值为0xaa55

首先将0x5a00转换为地址复制给指针

然后对指针所对应的值进行修改

1
2
int *ptrTemp = (int *)0x5a00;
*ptrTemp = 0xaa55;

c

4.9 下面代码输出是什么

1
2
3
4
5
6
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b>6)?puts(">6"):puts("<6");
}

输出结果:>6

有符号数与无符号数进行运算时,有符号数先自动转换成无符号数。

1
2
3
4
5
6
#include <stdio.h>
int main()
{
int a = -20;
printf("%u", a);
}

输出结果:4294967276

4.10 评论下面代码

1
2
3
4
5
6
void test()
{
char string[10];
char *str = "0123456789";
strcpy(string,str);
}

这段代码会报错,因为string数组只能存放10个字节,而str有11个字节(字符串要加个\0)

4.11 评论下面代码

1
2
3
4
5
6
7
8
9
10
11
void GetMemory(char *p)
{
p = (char *)malloc(0x20);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str,"Hello World!");
printf(str);
}
  1. 调用GetMemory( str )后, str并未产生变化,依然是NULL.只是改变的str的一个拷贝的内存的变化

  2. strcpy( str, “hello world” );程序运行到这将产生错误。

4.12 评论下面中断回调函数

1
2
3
4
5
6
_interrupt double compute_area(double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}

中断最好不要有返回值,最好不要传入参数,最好不要用printf,要保证中断是短而有效率的

5.C语言基础

5.1 循环和分支

5.1.1 循环语句

  1. for循环

    1
    2
    3
    4
    5
    6
    7
    for(init; test; update)

    {

    body;

    }
  2. while循环

    1
    2
    3
    4
    5
    6
    7
    while(test)

    {

    body;

    }
  3. do while

    1
    2
    3
    4
    5
    6
    7
    do

    {

    body;

    }while(test)

循环辅助

break; //跳出循环

continue; //跳出本次循环

5.1.2 if语句

1
2
3
4
if(test)
{
body;
}
1
2
3
4
5
6
7
8
9
if(test)
{
body;
}

else
{
body;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(test)
{
body;
}

else if(test)
{
body;
}

else
{
body;
}

5.1.3 三元运算符

1
Exp1 ? Exp2 : Exp3;

5.1.4 switch语句

1
2
3
4
5
6
7
8
9
10
11
switch(exp)

{

case const1 : statements; break;

case const2 : statements; break;

default : statements; break;

}

注意:switch判断表达式必须是整数值,case标签必须是整数常量或常量表达式、字符,不能是变量

5.2 作用域与存储类

5.2.1 作用域

代码块作用域(局部变量)

代码块:包含在开始花括号和对应结束花括号之内的代码

作用域:从定义变量位置到该代码块的末尾

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main()
{
itemp++;
int itemp = 10; // 这个itemp变量的作用域是从这里开始到return0;也就是说前面的itemp++不会执行
itemp--;
return 0;
}

文件作用域(全局变量——多文件编程)

文件作用域:在所有函数之外定义的变量具有文件作用域

作用域:从定义变量位置到包含该定义文件的结尾处。在其他位置使用该变量应用extern来声明该变量

函数也是同理所以下面直接用函数的例子

1
2
3
4
5
6
7
8
9
10
// c源文件 func.c
int Max(int num1, int num2)
{
int max = num1;
if(max < num2)
{
max = num2;
}
return max;
}
1
2
3
4
5
// 头文件 head.h
#ifndef C_IMPROVE_HEAD_H
#define C_IMPROVE_HEAD_H
extern int Max(int num1, int num2);
#endif //C_IMPROVE_HEAD_H
1
2
3
4
5
6
7
8
#include <stdio.h>
#include "head.h"
int main() {
int num1 = 10;
int num2 = 20;
printf("%d",Max(num1, num2));
return 0;
}

5.2.2 存储时期

自动存储期 静态存储期
生成 程序执行到对象声明的时候创建出相应的对象 在程序执行开始执行的时候被创建出来
初始化 如果不显示地进行初始化,则该对象会被初始化为不确定的值 如果不显示地进行初始化,则该对象会被初始化为0
消失 执行到包含该声明的程序块的结尾时,该对象就会消失 在程序结束的时候消失

5.2.3 存储类

存储类 时期 作用域 链接 声明方式
自动 自动 代码块 空 代码块内
寄存器 自动 代码块 空 代码块内,使用关键字register
具有外部连接的静态 静态 文件 外部 所有函数之外
具有内部连接的静态 静态 文件 内部 所有函数之外,使用关键字static
空连接的静态 静态 代码块 空 代码块内,使用关键字static

5.3 内存与指针

5.3.1 指针

无论是什么类型的指针他所占的内存空间都是四个字节