裸机芯片的引脚,可以直接使用
我们下载一份ESP32 Arduino core
我这里开发板是这个,选择
缩进起来的样子
里面包括这个头文件
在这个里面
我们看一眼内容
里面都是大量的宏定义
dint.h是c99中引进的一个标准C库的头文件.
https://blog.csdn.net/fangwei1235/article/details/6771117
stdint.h中定义了一些整数类型,规则如下(其中N可以为8,16,32,64)
intN_t, int_leastN_t, int_fastN_t表示长度为N位的整型数;
uintN_t, uint_leastN_t, uint_fastN_t表示长度为N位的无符号整型数 ;
stdint.h中的常量,定义以上各类型数的最大最小值(其中N可以为8,16,32,64)
INTN_MIN, UINTN_MIN, INTN_MAX, UINTN_MAX ;
INT_LEASEN_MIN, INT_LEASEN_MAX ;
INT_FASTN_MIN, INT_FASTN_MAX ;
以上类型的C++类型定义等
大数输出:
int64_t数的输出:%lld ;
uint64_t数的输出:%llu ;
uint64_t数十六进制输出:%llx ;
uint64_t数八进制输出:%llo ;
按照posix标准,一般整型对应的*_t类型为:
1字节 uint8_t
2字节 uint16_t
4字节 uint32_t
8字节 uint64_t
此处是引脚的头文件的一开始的内容
这个地方的这段代码,在每一种开发板上面都有.
这个地方的定义,有点像传统的Arduino里面的int led = 13
这里是三个通用的传输接口,串口,I2C,SPI
数字接口
Timer接口
DAC的接口
多次出现uint8_t类型
这个地方是定义所在
unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字。
在实际使用过程种有什么区别呢?
https://www.cnblogs.com/qytan36/archive/2010/09/27/1836569.html
主要是符号位,但是在普通的赋值,读写文件和网络字节流都没什么区别,反正就是一个字节,不管最高位是什么,最终的读取结果都一样,只是你怎么理解最高位而已,在屏幕上面的显示可能不一样。
但是我们却发现在表示byte时,都用unsigned char,这是为什么呢?
首先我们通常意义上理解,byte没有什么符号位之说,更重要的是如果将byte的值赋给int,long等数据类型时,系统会做一些额外的工作。
如果是char,那么系统认为最高位是符号位,而int可能是16或者32位,那么会对最高位进行扩展(注意,赋给unsigned int也会扩展)
而如果是unsigned char,那么不会扩展。
这就是二者的最大区别。
同理可以推导到其它的类型,比如short, unsigned short。等等
unsigned不会进行“符号扩展”,这个我不知道是不是对的。
c++算术运算和位运算中类型转换和类型提升规则和方法
#include <iostream>
using namespace std;
void main()
{
/************************************************************************/
/* 结论:
Memory中存储的是补码,是根据存入的具体数据的值进行转换为二进制
后的形式,如果超过该数据类型范围则不知道存的形式是什么了,这个
应该是编译器相关的,对越界数的处理方式;(无论存入的时候是用什
么进制表示的,在这里注意+/-单目运算符的作用)
无论要做什么运算都要先看这个数存入内存是什么样子的;
类型提升/截断的时候都是对内存中数据的操作,提升的时候就是需要
进行扩位:对无符号数扩位的时候直接把扩出的位上补零即可(因为unsigned都是正数);有符号
数进行扩位,则进行符号位扩展(sign extension)如果是整数即原最高位
是零则补零,如果是负数即原最高位是1则全补1;进行数据截断的时候是
从低位开始数位数然后截断,这里注意我们使用的一般都是小端机(little Endian)
类型强制转换其实也是对内存中存储的数据的一种呈现方式而已,如:内存
中是8000的时候(即1000 0000 0000 0000),如果用unsigned short int则打印出
来的是2的15次方,如果用short int则打印出来是负2的16次方
在进行算术运算和双目的位运算的时候如果操作数数据类型不一致,首先进
行数据 Arithmetical Conversion类型提升(其实提升就是进行扩位,然后把扩位后的内存二进制代码强制转为某种数据类型之后进行打印),然后 才开始运算
在进行单目位运算的时候,首先进行整型提升,然后开始运算Integer Promotion*/
/************************************************************************/
//目的:计算机内部存储形式(无符号数、有符号正数、有符号负数、直接十六进制;及其
//扩位后规则及其扩位后的存储形式)
unsigned char uch1 = 0x80; //80
unsigned char uch2 = 128; //80
//注意+/-作为单目运算符的作用和意义,就是让存入内存的时候,最高位写为1
//同时要注意各个数据类型的表示范围
char sch1 = -0x7f; //Memory中应该是81
char sch2 = 0x80;
cout << (short int)sch1 << endl;//-127
cout << (short int)sch2 << endl;//-128
unsigned usch3 = 0x7f;
unsigned ushc4 = 0x80;
cout << (short int)usch3 << endl;//127
cout << (short int)ushc4 << endl;//128
char sch3 = 127;
char sch4 = -128;
cout << (short int)sch3 << endl;//127
cout << (short int)sch4 << endl;//-128
unsigned uch3 = 0;
unsigned uch4 = 255;
cout << (short int)uch3 << endl;//0
cout << (short int)uch4 << endl;//255
char a = -0x80;
short int b = 0x7f80;
short int result = a&b;//0111 1111 1000 0000
cout << result <<endl;
}
结论:
Memory中存储的是补码,是根据存入的具体数据的值进行转换为二进制后的形式,如果超过该数据类型范围则不知道存的形式是什么了,这个应该是编译器相关的,对越界数的处理方式;(无论存入的时候是用什么进制表示的,在这里注意+/-单目运算符的作用)无论要做什么运算都要先看这个数存入内存是什么样子的;类型提升/截断的时候都是对内存中数据的操作,提升的时候就是需要进行扩位:对无符号数扩位的时候直接把扩出的位上补零即可(因为unsigned都是正数);有符号数进行扩位,则进行符号位扩展(sign extension)如果是整数即原最高位是零则补零,如果是负数即原最高位是1则全补1;进行数据截断的时候是从低位开始数位数然后截断,这里注意我们使用的一般都是小端机(little Endian)类型强制转换其实也是对内存中存储的数据的一种呈现方式而已,如:内存中是8000的时候(即1000 0000 0000 0000),如果用unsigned short int则打印出来的是2的15次方,如果用short int则打印出来是负2的16次方在进行算术运算和双目的位运算的时候如果操作数数据类型不一致,首先进行数据 Arithmetical Conversion类型提升(其实提升就是进行扩位,然后把扩位后的内存二进制代码强制转为某种数据类型之后进行打印),然后 才开始运算在进行单目位运算的时候,首先进行整型提升,然后开始运算Integer Promotion
这个叫做宏内嵌入表达式,写法上面值得商榷
在gun c中,用括号将符合语句的括起来形成了表达式,在一个表达式使用循环,跳转和局部变量.
对这里的写法迷惑不解,寻找一下根源
就是这个引脚的配置选项,以上的选项出现在所有的引脚配置文件内
我们换个名字进行搜索,看第一个
打开以后,看写的名字是esp32 hal逻辑层(gpio部分)。c文件
先不看具体实现,先看看头文件
头文件的框架
开始看,是不是看见这些Arduino的宏定义了。我简单的写了一些注释
中断模式,中断使能是什么的。都在这里了,以后具体的再来分析
这个是一个esp32 gpio 转换矩阵的结构体。具体的寄存器,有格600多页的文档,需要看哪个。这个电脑也没有,我也不讲解了
https://www.espressif.com/zh-hans/support/documents/technical-documents
https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_cn.pdf
《ESP32 技术参考手册》的目标读者群体是使用 ESP32 芯片的应用开发工程师。本手册提供了关于 ESP32 的具 体信息,包括各个功能模块的内部架构、功能描述和寄存器配置等。
我们之后会对这个地方详细的解答
一些外设的叫法
ESP32 芯片有 34 个物理 GPIO pad。
每个 pad 都可用作一个通用 IO,或连接一个内部的外设信号。
IO_MUX、RTC IO_MUX 和 GPIO 交换矩阵用于将信号从外设传输至 GPIO pad。
这些模块共同组成了芯片的 IO 控制。
注意:
这 34 个物理 GPIO pad 的序列号为:
0-19, 21-23, 25-27, 32-39。
其中 GPIO 34-39 仅用作输入管脚,其 他的既可以作为输入又可以作为输出管脚。
IO_MUX、RTC IO_MUX 和 GPIO 交换矩阵结构框图
按钮的电路图
https://github.com/Nicholas3388/LuaNode/tree/master/LuaNode_Esp32
四年前的一个资料,不知道有没有用
https://github.com/espressif/arduino-esp32/blob/master/variants/doitESP32devkitV1/pins_arduino.h
这个是对应文章里面的头文件的GitHub地址