CC2530+树莓派—–树莓派串口通信
树莓派初始化完毕下面就要将Zigbee模块与树莓派连接起来,Zigbee模块为CC2530。本文涉及到CC2530与树莓派的连接方式以及树莓派串口通信相关知识。
连接
树莓派GPIO图如下(https://pinout.xyz/pinout/)
CC2530核心板管脚图如下:
连接方式如下:
VCC -> 3,3V (Pin1)
GND -> GND (Pin6)
P02 -> TXD (Pin8 / BCM 14)
P03 -> RXD (Pin10 / BCM 15)
树莓派串口通信
树莓派从大的方向来说一共出了3代,每一代的CPU外设基本相同,但内核不同,外设里面一共包含两个串口,一个称之为硬件串口(/dev/ttyAMA0),一个称之为mini串口(/dev/ttyS0)。
硬件串口由硬件实现,有单独的波特率时钟源,性能高、可靠,mini串口性能低,功能也简单,并且没有波特率专用的时钟源而是由CPU内核时钟提供。在所有的树莓派板卡中都通过排针将一个串口引出来了,目前除了树莓派3代以外 ,引出的串口默认是CPU的那个硬件串口。而在树莓派3代中,由于板载蓝牙模块,因此这个硬件串口被默认分配给与蓝牙模块通信了,而把那个mini串口默认分配给了排针引出的GPIO Tx Rx,下其中pin8,pin10中就是引出的串口IO,如果我们需要通过UART外接模块,默认情况下必须得使用性能很低的mini串口。(GPIO映射的串口是默认的 /dev/ttyS0 这个mini串口)
/dev/ttyS0 更像是单片机中的一个一个字节去查询串口中断。
/dev/ttyAMA0 更像是串口开启了硬件的 FIFO/DMA 。
启用串口ttyS0
使用命令看一下树莓派支持的GPIO串口
ls -la /dev/
发现没有ttyS0,只有ttyAMA0。/dev/ttyAMA0串口时给蓝牙模块使用的。另外一个ttyS0应该是对接的miniUART,这个不能直接用,需要进行配置。为了打开串口/dev/ttyS0,在命令框输入
sudo raspi-config
打开系统配置界面,选择Inerfacing Options—->选择 serial—–>选择No—->然后Yes—->重启。
这个时候在输入下面的命令就可以看到串口ttyS0,但是还是不能用树莓派外接串口模块进行通信,继续配置。
这是因为树莓派IO引出的串口默认是用来做控制台使用的,它的初衷是为了在没有网络接口时,通过串口对树莓派进行相关的配置。因此需要禁用这个默认功能,使得串口为我们自由使用。在树莓派命令窗口中分别通过如下两个命令停止和禁用串口的控制台功能。在终端输入下面指令
sudo systemctl stop [email protected]
sudo systemctl disable [email protected]
再执行命令:
sudo vim /boot/cmdline.txt
删掉里面的console=serial0,115200
,注意,其他的不要删掉,不管后面是什么,都只删掉中间的这一句话。保存之后,重启树莓派。(没看到这句话)
测试
短接GPIO14和GPIO15,先使用minicom环回测试。
安装串口工具minicom
sudo apt-get install minicom
运行工具
sudo minicom -s
选择第三项
修改A和E两处
在mincom时打开回显(Ctrl+A,再全部松开按Z,跳出配置界面按E)
输入一个在字符,先回显字符,然后自己又接收到字符(按一下1,显示两个1),如下图测试成功
对接电脑的USB转TTL,树莓派RX对TTL的TX,树莓派TX对TTL的RX,接入电脑,com5
打开串口调试助手,测试成功,如下图:
树莓派发送123456,串口收到;串口发送abc,树莓派收到。
编写程序:串口发送给树莓派消息,树莓派接收之后再发送回串口,串口接收。
程序如下:
import serial
import time
ser = serial.Serial("/dev/ttyS0", 115200)
ser.flushInput()
ser.write("begin".encode("utf-8"))
def main():
while True:
count = ser.inWaiting()
if count != 0:
recv = ser.read(count)
ser.write("Recv some data is : ".encode("utf-8"))
ser.write(recv) #
ser.flushInput()
time.sleep(0.1)
if __name__ == '__main__':
main()
感觉不是很稳定?总有乱码
CC2530串口通信
Zstack协议栈/drivers/hal_uart.c文件,包括了串口初始化、发送、接收等函数,已经全部封装好了,只需要根据自己的需求修改相关的配置,包括串口头文件,调用相应的接口函数就可以使用串口了。
用户自己添加的应用程序任务在zstack中的调用过程:
打开SampleApp_init(),看到串口初始化代码
在MT_UartInit()初始化函数中有几个定义需要注意:
line108:baudRate,波特率,设置为115200bps
line109:flowControl:设置为false
-
line115:ZTOOL_P1串口0,对应ttyS0,在预编译选项中设置
串口数据发送函数,写在哪里都可以
HalUARTWrite(0,"hello\n",sizeof("hello")-1);
用USB to TTL测试之后可以正确通信。
串口收发
修改回调函数,接收数据之后再次转发
void rxCB( uint8 port, uint8 event )
{
unsigned char buf[30];
unsigned char len;
len = HalUARTRead(0, buf, 30);//读取串口数据,返回数据长度
if(len)
{
HalUARTWrite(0, buf, len);//通过串口原样返回数据 也可以修改数据返回用于区分数据
len = 0;
}
}
发送hello,同时收到hello,收发成功。
树莓派与CC2530的通信
CC2530给树莓派发消息,树莓派用minicom观察接收的数据。
minicom -b 115200 -D /dev/ttyS0
成功接收。
树莓派给CC2530发消息(发送”1”),CC2530接收之后在发给树莓派(收到”1”)。
经验证,两者的收发功能均成功。(不太稳定的样子)
参考资料
https://www.zigbee2mqtt.io/information/connecting_cc2530.html
https://blog.csdn.net/qq_16775293/article/details/97891715
https://zhuanlan.zhihu.com/p/38853178
https://blog.csdn.net/qq21497936/article/details/79758975?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-4&spm=1001.2101.3001.4242