串口
在Arduino中串口分为软串口( SoftwareSerial )和硬串口( HardwareSerial )。
在我个人的理解中两者的区别就在于是否带有独立的串口寄存器。
硬串口是芯片在设计时就带有独立的寄存器,当另一端的数据传输过来时,首先是存放在这个串口的独立寄存器中,然后再根据程序中的指令调取对应的数据,如果学过计算机组成原理的应该会有点感觉,程序将对应串口寄存器中的数据转移至通用寄存器再进行使用1。
在Arduino中软串口是程序通过计时器和中断实现的,而我是在它是文件 SoftwareSerial.cpp 中发现的有导入avr/interrupt.h和util/delay_basic.h,并有使用 _delay_loop_2 这个函数,间隔是4-cycle delays,并且在源文件里有如下注释,也就是arduino中软串口最大波特率的来源:
// Timings counted from gcc 4.8.2 output. This works up to 115200 on// 16Mhz and 57600 on 8Mhz.
程序通过模拟串口的通信方式,接收和发送数据,发送只需要控制高低电平的时间,而接收需要中断判断下降沿和持续时间,程序通过这些判断接收到的数据内容,并将数据直接存储到通用寄存器或段寄存器等位置。
由于Aduino中无论你定义多少个软串口都使用的1个计时器,所以同时只能监听1个串口,所以我之前希望通过外部中断的方式控制监听串口并同时传输数据时,就出现了没有读取出任何数据的现象,现在想的就是外部中断的中断保护等一系列原因造成的。
综上关于Arduino中关于软串口和硬件的使用我的规则一般是:
- 如果串口只有写没有读操作,那就统一使用软串口
- 如果串口有读写,那么波特率较低的串口优先使用软串口,并且软串口的读取不能放在中断中进行,硬串口可以随意
- 如果存在多个软串口需要读写,那么尽量能留有可以让外部设备进行串口监听切换的方法
I2C
I2C是所有接口中我使用最少的接口,主要是现阶段,我使用I2C时都使用都是单连1个设备,或生生把总线用成了串口,倒是开板上关于I2C是了解最多的。
插个旗,等之后补上。——2021.9.10
ISP和SPI
ISP(ICSP)和SPI我两个放一起是因为两者的高度重合,ISP是一种单片机的烧写方式和STLink、JLink以及串口烧写是等价的,而SPI则是和串口通信、I2C等价属于一种通信协议。
在接口方面,两者都占用的是MISO、MOSI、SCK和SS,不同的是ISP是烧录器的SS接口和需要烧录的RESET接口连接,而SPI则是双方的SS接口进行连接。
关于ISP的应用可以参考我的文章:Arduino 烧写Bootloader
至于SPI接口我目前仅在 W5500 网口转ISP上使用过,主要也是为了使用telnet控制协议,但关于这个模块的使用,我发现了一个问题,大致情况如下:
如果我在尝试在W5500工作的情况下,并且W5500在连有另外的网络设备时,这个时候我尝试给Arduino烧写程序,那么W5500多半会报废,这个报废并不是指W5500损坏,而是我能在ping通设备的同时,无法使用其他的一切协议包括telnet、http等。
尝试通过telnet进行连接时,会报错:
telnet: Unable to connect to remote host: Connection refused
我认为W5500多半是能复位的,但具体的方法不太想找,感觉会比较麻烦…