串口的使用-发送数据给电脑(学习笔记) 电脑版发表于:2023/8/18 16:10 ![](https://img.tnblog.net/arcimg/hb/ebdf26a98c214873aa205445b60ae1c5.png) >#串口的使用-发送数据给电脑(学习笔记) [TOC] 串口是什么? ------------ tn2>**串行通讯接口,简称串口,也称COM口,串行接口的数据是通过一条线一位位地顺序传输。** 并行接口,简称并口,是指8位数据同时通过8条并行线进行传送。 串口形容一下就是一条车道,而并口就是有8个车道同一时刻能传送8位(一个字节)数据。但是并不是并口快,由于8位通道之间的互相干扰。传输受速度就受到了限制。而且当传输出错时,要同时重新传8个位的数据。 串口没有干扰,传输出差后重新发一位就可以了。 ![](https://img.tnblog.net/arcimg/hb/b04d0d3587b9464285df674678a56b10.png) ![](https://img.tnblog.net/arcimg/hb/1536a20caa034ec78c688e9dd28ee97e.gif) 什么是串口波特率? ------------ tn2>波特率(bandrate),指的是串口通信的速率,也就是串口通信时每秒钟可以传输多少个二进制位。 比如每秒钟可以传输9600个二进制(传输一个二进制位需要的时间是1/9600秒,也就是104us),波特率就是9600.<br/> 串口的通信波特率不能随意设定,而应该再一些值中去选择。 一般常见的波特率是9600或者115200(低端的单片机如51常用9600,高端的单片机和嵌入式SOC一般用115200)。 ![](https://img.tnblog.net/arcimg/hb/db59de2fc8814278ae58f2c584f4acff.png) tn2>数据位: 1010 1010 -> 0xaa ->170 二进制 十六进制 十进制 也就是说我们可以通过控制引脚按上面的高低电平,每104us改变一次,就可以完成一个字节的传输。 但是芯片已经帮我们做好了这些操作,我们要做的只是配置好波特率,然后填写数据即可。 串口打印代码实现 ------------ ![](https://img.tnblog.net/arcimg/hb/1e445e56f9ed4d978505ba0da8277891.png) ```cpp // 设置波特率为9600 Serial.begin(9600); // 打印输出 Serial.print("内容+符号"); ``` 代码实践一 ------------ tn2>由于代码在第一次打印的时候可能会出现乱码的情况,所以我们可以设置`platformio.ini`文件的波特率初始化为`115200`或`9600`二者都可以。 代码如下: ```cpp [env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 ``` tn2>编写主要代码: ```cpp void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("setup\n"); } void loop() { // 当串口开始活动的时候 while (Serial.available()){ // 读取一个串口传来的一个字节 uint8_t data = Serial.read(); // 进行打印 Serial.printf("get data = %d\n",data); } delay(10); } ``` tn2>接下来我们运行代码,并输入一个a,它将输出一个97和10,97就是a的十进制,10是空格。 ![](https://img.tnblog.net/arcimg/hb/0a35bbc8fca74e8a837e90c9385e1e28.png) 电灯实验 ------------ tn2><a href="https://www.tnblog.net/hb/article/details/8185">结合上一篇博客</a>,我们通过输入k进行开始让灯闪一闪的,输入s进行停止闪烁。 代码如下: ```cpp //头文件 #include <Arduino.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> //定义LED灯引脚为常量,因为程序跑起来就不需要更改IO值 #define PIN_LED 18 boolean nowvalue; // 声明任务句柄 TaskHandle_t ledTaskHandle; void printnowvalue(){ String strValue; if (nowvalue) { strValue = "true"; } else { strValue = "false"; } Serial.println(strValue); } // LED任务函数 void ledTask(void *pvParameters) { while (1) { uint8_t data = Serial.read(); // 转换成字符 printnowvalue(); char ch = char(data); if(ch == 'k'){ Serial.printf("start /n"); nowvalue = true; printnowvalue(); }else if(ch == 's'){ Serial.printf("stop /n"); nowvalue = false; printnowvalue(); } delay(1000); } } void setup() { Serial.begin(9600); //初始化引脚为输出 pinMode(PIN_LED, OUTPUT); // 创建LED任务 xTaskCreate(ledTask, "LED Get Command Task", 1000, NULL, 1, &ledTaskHandle); } void loop() { if(nowvalue){ //设置为高电平(3.3V),1s后设置为低电平(0V),再1s后重复 digitalWrite(PIN_LED, HIGH); delay(1000); digitalWrite(PIN_LED, LOW); } delay(1000); } ``` tn2>注意我这里用了个句柄用于接收输入的内容。 ![](https://img.tnblog.net/arcimg/hb/218926ac2c284ccf8f265250c117e0a8.png)