操作技巧——vscode.git.
jxr@localhost:~/ros2-projects$ sudo docker rm ros-container
Error response from daemon: No such container: ros-container
jxr@localhost:~/ros2-projects$ sudo docker rm ros-dev
Error response from daemon: cannot remove container "ros-dev": container is running: stop the container before removing or force remove
jxr@localhost:~/ros2-projects$ sudo docker rm ros-dev
Error response from daemon: cannot remove container "ros-dev": container is running: stop the container before removing or force remove
jxr@localhost:~/ros2-projects$
1.git log 一定要在想查看的文档的目录下,可查看修改日期 按q退出
2.windows + r 然后cmd,输入wsl就可以进入wsl系统
3.Linux 命令
windows + 空格 切换输入法
根目录
cd /workspaces/ros2-develop
用户目录
cd ~/workspaces/ros2-develop
判断是否是可执行文件 输入ls
绿色是可执行文件,白色是不可执行文件
colcon build
#!/usr/bin/python3
###注意加了此前缀后,如果是可执行文件,该文件运行时有两种方法
print("hello world")
#一种是 python hello_world.py
#另一种是./hello_world.py
终端运行
chmod a+x hello_world.py
可以将该文件转为可执行文件
#终端运行
#chmod a+x hello_world.py 可以将该文件转为可执行文件
1.python 运行
python hello_world.py
2.c++ 运行
g++ hello_world.cpp
./a.out
1.printenv | grep AMENT
2.pwd--------------查看当前目录
3.ctrl + c 打断施法
can通信

这段代码是一个名为 LED_Control 的C语言函数,它的功能是根据一个8位的输入数据(一个字节)来控制8个LED灯的亮灭状态。
我们来分模块逐行解析它。
1. 函数的定义
void LED_Control(uint8_t data)
{
// ... 函数体 ...
}
-
void LED_Control(...): 定义了一个函数,名字叫 LED_Control。void 表示这个函数执行完后不返回任何结果。
-
uint8_t data: 这是函数的输入参数。
-
uint8_t 是一种数据类型,表示一个8位的无符号整数(也就是一个字节,范围是 0 到 255)。
-
data 是这个参数的名字。
-
核心思想: 这个 data 字节的8个位(bit)将分别对应8个LED灯。
-
2. 函数体:控制8个LED灯
函数体由8行相似的代码组成,每一行控制一个LED。我们以第一行为例来详细分析:
// 端口 引脚号 引脚状态
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, ((data & 1) == 0) ? GPIO_PIN_SET : GPIO_PIN_RESET);
这一行代码做了三件事:
第一件事:选择要控制的引脚
-
HAL_GPIO_WritePin(...): 这是STM32 HAL库中用于控制GPIO(通用输入/输出)引脚电平的函数。
-
GPIOG: 指定了要操作的是 G端口。
-
GPIO_PIN_1: 指定了要操作的是G端口的 1号引脚。
第二件事:位运算(Bitwise Operation)
-
data & 1: 这是理解这段代码的关键,它是一个**按位与(AND)**运算。
-
数字 1 的二进制是 0000 0001。
-
data & 1 的作用是只保留 data 这个字节的最低位(第0位),其他位全部清零。
-
举例:
-
如果 data 是 0101 0101,那么 data & 1 的结果是 0000 0001 (十进制的1)。
-
如果 data 是 0101 0100,那么 data & 1 的结果是 0000 0000 (十进制的0)。
-
-
第三件事:三元运算符(Ternary Operator)
-
((data & 1) == 0) ? GPIO_PIN_SET : GPIO_PIN_RESET
((数据 & 1) == 0) ?GPIO_PIN_SET : GPIO_PIN_RESET -
这是一个紧凑的 if-else 语句,格式是: (条件) ? (条件为真时的值) : (条件为假时的值)。
-
我们来分析这个逻辑:
-
如果 data 的第0位是 0:
-
data & 1 的结果是 0。
-
条件 (0 == 0) 为真。
-
整个表达式的值为 GPIO_PIN_SET,引脚输出高电平。通常高电平会让LED灯熄灭。
-
-
如果 data 的第0位是 1:
-
data & 1 的结果是 1。
-
条件 (1 == 0) 为假。
-
整个表达式的值为 GPIO_PIN_RESET,引脚输出低电平。通常低电平会让LED灯点亮。
-
-
结论: data 的第0位是 1,则1号引脚的LED亮;是 0,则灭。
3. 其他7行代码
后面的7行代码逻辑完全相同,只是检查的 data 的位和控制的引脚不同。
-
((data & 2) == 0): 2 的二进制是 0000 0010,所以 data & 2 是在检查第1位,用来控制 2号引脚 的LED。
-
((data & 4) == 0): 4 的二进制是 0000 0100,所以 data & 4 是在检查第2位,用来控制 3号引脚 的LED。
-
...以此类推...
-
((data & 128) == 0): 128 的二进制是 1000 0000,所以 data & 128 是在检查最高位(第7位),用来控制 8号引脚 的LED。
总结与应用场景
| 如果 data 的... | 那么它会控制... | 逻辑 |
| 第0位 (最低位) | GPIO_PIN_1 | 1 = 亮, 0 = 灭 |
| 第1位 | GPIO_PIN_2 | 1 = 亮, 0 = 灭 |
| 第2位 | GPIO_PIN_3 | 1 = 亮, 0 = 灭 |
| ... | ... | ... |
| 第7位 (最高位) | GPIO_PIN_8 | 1 = 亮, 0 = 灭 |
这个函数有什么用?
从你截图的左侧PPT标题“4 CAN通信的软件配置工程方式”和代码下方的HAL_CAN_RxFifo1MsgPendingCallback(CAN接收中断回调函数)可以推断出这个函数的应用场景:
-
STM32的CAN总线接收到了一个数据包。
-
这个数据包里包含了一个字节的数据。
-
在CAN接收中断服务程序中,程序会提取出这个字节的数据。
-
然后调用 LED_Control() 函数,并将这个字节作为参数 data 传进去。
-
最终,8个LED灯的状态就会实时地显示出接收到的这个字节的二进制形式。
例如: 如果CAN总线收到的数据是 90(十六进制为0x5A,二进制为01011010),那么调用LED_Control(90)后,LED的亮灭状态会是:
灭-亮-灭-亮-亮-灭-亮-灭 (从第8个灯到第1个灯)
更多推荐


所有评论(0)