您现在的位置是:网站首页> 智能硬件
树莓派相关技术汇集
- 智能硬件
- 2025-09-07
- 1548人已阅读
树莓派注意
树莓派更改用户密码
树莓派安装ftp
步骤1 -安装vsftpd
使用以下命令更新您的系统库并安装vsftpd软件:
步骤2 -更新配置文件
安装后,使用工具编辑vsftpd配置文件:
在这个文件中找到以下几行,通过删除#字符取消注释:
在文件末尾添加以下几行:
使用CTRL-X、Y和ENTER保存和退出。
步骤3 -为默认用户创建FTP目录
为了允许您使用默认用户连接到FTP服务器,我们需要创建几个目录:
更改ftp目录的权限:
步骤4 -创建新用户(可选)
如果您想用另一个用户名登录服务器,我们可以创建一个新用户。在本例中,我们将创建一个名为“camera”的新用户:
系统会提示您输入密码,根据喜好输入吧。
在屏幕上应该看到这样的显示
这个新用户还需要配置FTP目录:
更改目录权限:
下面不是基本文件传输功能所必需的,但新用户可以通过运行命令获得使用“sudo”相同的权限:
步骤5 -重新启动FTP服务器
最后重新启动vsftpd服务,使我们的更改生效:
树莓派中QT实现串口通讯
先简单说一些开发过程中需要注意的问题
- Linux 下设备为 tty ,对应在 windows 下为 COM
- ttyS0 与 ttyUSB0 不是一个东西
- raspi-config 中, serial 应该被打开, 但是 Serial Console 不应该被打开,除非你想要用 Serial Console 去作为终端来控制树莓派
- 默认pin8,10 是作为 Serial1 分配给蓝牙, 需要关闭蓝牙才可以使用
- 在树莓派与本机中USB设备如何选择可以看这里
- 树莓派中QT要使用QtSerialPort需要安装库
sudo apt-get install libqt5serialport5 sudo apt-get install libqt5serialport5-dev
代码展示
widget.pro 中
QT += core gui LIBS += -lwiringPi QT += serialport
widget.h 中
#include <QWidget>#include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> #include <QString> namespace Ui { class Widget;} class Widget : public QWidget { Q_OBJECTpublic: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_pushButton_clicked(); void read();private: Ui::Widget *ui; QSerialPort *serial;
widget.cpp 中
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); serial = new QSerialPort; serial->close(); serial->setPortName("ttyS0"); serial->open(QIODevice::ReadWrite); serial->setBaudRate(115200); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); connect(serial,&QSerialPort::readyRead,this,&Widget::read); } Widget::~Widget(){ delete ui; } void Widget::on_pushButton_clicked(){ QByteArray a = QByteArray("\n"); a.append(ui->textEdit->toPlainText().toLatin1()); serial->write(a); } void Widget::read(){ QByteArray buf; buf = serial->readAll(); qDebug() << buf; QString a = QString(buf); ui->textEdit_2->setText(a); }
说在最后
关于如何选择你的设备
在树莓派中选择你的串口
一般来说, 选择 ttyS0 即对应了你的pin8,10 serial1
详细可见
https://www.raspberrypi.org/documentation/configuration/uart.md
在你的电脑上选择对应的USB
试试命令
ls -l /dev/ttyUSB*
树莓派设置语言
sudo raspi-config
localisation Options 第4项
Change Locale 第1项
去掉(空格) (en_GB.UTF-8 UTF-8)
勾上(空格) (en_US.UTF-8 UTF-8) (zh_CN.UTF-8 UTF-8) (zh_CN.GBK GBK)
回车后选择默认语言选 zh_CN.UTF-8
重启
sudo reboot
安装中文拼音输入法sudo apt-get install scim-pinyin
树莓派开机自启动程序
一、在/home/pi/.config下找到autostart(没有就新建一个)的文件夹
进入/home/pi/.config文件夹:
$:cd /home/pi/.config
查看autostart目录是否存在 :
$:ls -l
如果不存在,创建autostart目录;否则,跳过这一步:
$: mkdir autostart
进入autostart目录:
$: cd autostart
二、在该文件夹内创建一个.desktop结尾的文件(自拟文件名,注意后缀必须是.desktop)
创建.desktop文件:
$: touch filename.desktop
编辑.desktop文件:
$: vim filename.desktop
进去之后,按A键或O键键进入编辑模式。
三、在第二步中新建的文件中添加如下内容(添加是将后面小括号内的说明连同小括号一同去掉):
[Desktop Entry](注意:方括号必须是英文格式的方括号)
Name=python(名字自拟)
Comment=Python program(内容说明自拟)
Exec=python3 wifitz.py(这里是中端执行的命令,比如我这里在终端命令启动程序的话,我在命令提示符后面执行
命令$:python3 wifitz.py(程序的路径最好是绝对路径,比如我这里应该是
$:python3 /program/wifitz.py))
Icon=/home/pi/python_games/4row_arrow.png(图标自拟,可以从系统其他地方直接法制个图标路径过来)
Terminal=false
MultipleArgs=false
Type=Application
Categories=Application;Development;
StartupNotify=true
(第三步操作具体详见上述链接)
这里主要是第一行的方括号需要注意下(本人已入坑),还有第4行的执行程序语句最好加绝对路径。
四、保存文件重启树莓派,sudo reboot
编辑结束后,先按Esc键,再按 :+; 键,左下角出现:时,用wq保存文件并返回到终端。
重启树莓派,sudo reboot。
五、重启成功后,在linux终端使用命令ps aux查看当前运行的所有程序,如果程序正常启动,可以在这里找到,本人查找结果如下图:
六、如果需要启动多个程序,我试过用上述方法添加三个.desktop文件,结果失败了;所以,如果需要启动多个程序,建议创建一个.sh脚本文件,将多个程序的终端启动命令添加到.sh文件中,然后将上述第三步中的第4行改为Exec=./filename.sh。接下来执行第4步和第5步查看执行结果,我这里能够成功启动三个python程序,如下图:
如有侵权,请您留言!谢谢!
树莓派3B--WiringPi控制GPIO
1.WiringPi简介 (官网)
WiringPi是应用于树莓派平台的GPIO控制库函数,WiringPi遵守GUN Lv3。wiringPi使用C或者C++开发并且可以被其他语言包转,例如python、ruby或者PHP等。WiringPi中的函数类似于Arduino的wiring系统,这使得熟悉arduino的用户使用wringPi更为方便。
树莓派具有26个普通输入和输出引脚。在这26个引脚中具有8个普通输入和输出管脚,这8个引脚既可以作为输入管脚也可以作为输出管脚。除此之外,树莓派还有一个2线形式的I2C、一个4线形式的SPI和一个UART接口。树莓派上的I2C和SPI接口也可以作为普通端口使用。如果串口控制台被关闭便可以使用树莓派上的UART功能。如果不使用I2C,SPI和UART等复用接口,那么树莓派总共具有8+2+5+2 =17个普通IO。wiringPi包括一套gpio控制命令,使用gpio命令可以控制树莓派GPIO管脚。用户可以利用gpio命令通过shell脚本控制或查询GPIO管脚。wiringPi是可以扩展的,可以利用wiringPi的内部模块扩展模拟量输入芯片,可以使用MCP23x17/MCP23x08(I2C 或者SPI)扩展GPIO接口。另外可通过树莓派上的串口和Atmega(例如arduino等)扩展更多的GPIO功能。另外,用户可以自己编写扩展模块并把自定义的扩展模块集成到wiringPi中。WiringPi支持模拟量的读取和设置功能,不过在树莓派上并没有模拟量设备。但是使用WiringPi中的软件模块却可以轻松地应用AD或DA芯片。
更丰富的内容请参考——【树莓派学习笔记——索引博文】
2.wiringPi安装
wiringPi的安装存在方案A和方案B。wiringPi使用GIT工具维护个更新代码,但是如果处于一些其他原因不能使用GIT,那么也可以使用方案B下载和安装wiringPi。
方案A——使用GIT工具
如果在你的平台上还没有安装GIT工具,可以输入以下命令:
sudo apt-get install git-core
如果在这个过程中出现错误,尝试更新软件,例如输入以下指令:
sudo apt-get update
sudo apt-get upgrade
紧接着可以通过GIT获得wiringPi的源代码
git clone git://git.drogon.net/wiringPi
若需要更新wiringPi。
cd wiringPi
git pull origin
进入wiringPi目录并安装wiringPi
cd wiringPi
./build
build脚本会帮助你编译和安装wiringPi
测试wiringPi是否安装成功
wiringPi包括一套gpio命令,使用gpio命令可以控制树莓派上的各种接口,通过以下指令可以测试wiringPi是否安装成功。
gpio -v
可以看到树莓派的基本信息:树莓派 3 版本2,内存1G。
使用gpio readall命令来查看所有管脚的基本信息
从上图可以知道树莓派管脚有三种编号方式,第一种为板上编号(37),即中间两列,表示第几号插针。第二中为wiringPi编码(25),使用wiringPi库编程时是用wiringPi编号,第三种为BCM编号,这个是更加BCM管脚来编号的,使用bcm2837库或python的RPi.GPIO编程时使用BCM编号。
方案B——直接下载和解压
简单的输入以下网址:
https://git.drogon.net/?p=wiringPi;a=summary
图1 下载wiringPi最新版本源代码
点击图中的snapshot便可下载最新版本。
你可能下载到一个名为wiringPi-98bcb20.tar.gz的压缩包,需要助于的是98bcb20只是一个版本号,当你下载wiringPi的时候该版本号可能会发生改变。
你需要解压wiringPi源代码并进行安装,可输入以下指令:
tar xfz wiringPi-98bcb20.tar.gz
cd wiringPi-98bcb20
./build
再次说明,wiringPi压缩包的名称很可能不是98bcb20,请根据实际情况改变。
测试wiringPi是否安装成功
wiringPi包括一套gpio命令,使用gpio命令可以控制树莓派上的各种接口,通过以下指令可以测试wiringPi是否安装成功。
gpio -v
gpio readall
树莓派安装游戏系统
树莓派默认密码
树莓派各种系统默认密码合集(欢迎补充)
由于树莓派系统众多,各个密码也不一样,所以整理出来一个合计给大家参考。
如果有不对或者不足的地方 还请大家多多留言、指正。
谢谢大家,树莓派社区的发展离不开大家的支持!
Raspberry Pi
默认用户是 pi 密码为 raspberry
FreeBSD
默认的密码是 freebsd/freebsd 和 root/root。
CentOS 7
默认主机名:rpi2 默认用户名 root 密码 centos
recalbox
默认主机名 root 密码 recalboxroot
OpenELEC
默认主机名 root 密码 openelec
树莓派家庭影院安装
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install kodi
安装完后启动可设置为中文
也可以用 kodi系统
修改树莓派的软件源
默认情况下,树莓派软件源地址是 http://archive.raspbian.org/,位于欧洲,在国内访问是非常慢的,经常只有几 k 每秒的下载速率。所以我们在玩转树莓派之前,强烈推荐替换成国内的软件源
树莓派的所有软件源地址可以从这里找到:https://www.raspbian.org/RaspbianMi
一般我们找个国内的就行了,比如清华大学的(下图表格的第一行)
首先点击桌面左上角的命令行按钮,进入命令行窗口
然后在命令行窗口内输入 sudo nano /etc/apt/sources.list 并回车,进入编辑器。
sudo 是指用系统管理员权限启动,nano 是树莓派内置的轻量文本编辑器,而 /etc/apt/sources.list 就是软件源的配置文件地址了。
接着编辑这个文件,如下图所示,把原来的内容注释掉(最前面加 # 号),在文件最顶部添加下面的内容:
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib
按 ctrl-o 保存,按 ctrl-x 关闭。
同样的方法,把 /etc/apt/sources.list.d/raspi.list 文件也替换成下面的内容:
deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui
至此,树莓派软件源就替换好了。是不是很简单,就改两行配置即可。
最后,你可以试下执行 sudo apt-get update
,会发现更新速度快了很多。
【实用手记】树莓派旋转屏幕
#display_rotate=0 Normal
#display_rotate=1 90 degrees
#display_rotate=2 180 degrees
#display_rotate=3 270 degrees
树莓派3B+配置QT5开发环境
没事不要进行sudo apt-get upgrade
如果安装QT失败那么把软件源恢复到原来的地址
执行如下步骤:
工具 ->选项
树莓派安装windows远程
首先提一下我之前做的部分:
1、安装rasbian系统
2、因为家里操作方便,于是安装触摸屏
3、接入鼠标
4、更新系统 sudo apt-get update(利用系统自身的keyword)
读取源列表中的每个软件列表并进行更新
5、sudo apt-get upgrade -y
更新软件,一般update 后需要upgrade
6、sudo apt-get dist-upgrade -y
此类更新一般为解决依赖关系,并做出处理
一般安装软件前需要update
7、安装xrdp服务,通过ssl方式连接到电脑
sudo apt-get install xrdp
sudo apt-get purge tightvnc xrdp
sudo apt-get install tightvncserver xrdp
8、检查通道是否处于监听,3350和3389端口
terminal输入netstat -tnl
9、通过计算机登录远程桌面,输入树莓派的ip地址
QT全屏和恢复
树莓派3B--Qt中使用wiringPi来开发工程
- //
- # 下面这个LIBS很关键
- LIBS += -lwiringPi
- //
#include <wiringPi.h>
#include <wiringSerial.h>
我的QT第一个程序MyQT
安装BCM2835
- P1-19 (MOSI)
- P1-21 (MISO)
- P1-23 (CLK)
- P1-24 (CE0)
- P1-26 (CE1)
- P1-38 (MOSI)
- P1-35 (MISO)
- P1-40 (CLK)
- P1-36 (CE2)
- P1-03 (SDA)
- P1-05 (SLC)
树莓派C所在的库和include
基于RFID RC522模块制作树莓派通读卡器
RC522 RFID模块在单片机开发中常用来作为读卡器使用,在本文中我们把它连接到树莓派,然后就可以制作读卡器了,比如读取门禁卡的UID。本项目只是一个读卡器的雏形,如果需要运用到实际项目中,还需要你的更多深加工。读卡器常见的应用场景还是安全管理系统,其它常见的应用场景还有按卡计时、考勤系统和游戏系统授权等。
RC522 RFID模块支持的卡片标准
使用RC522芯片的模块支持以下标准的卡片:
MIFARE Mini
MIFARE 1K
MIFARE 4K,
MIFARE Ultralight
MIFARE DESFire EV1
MIFARE Plus RF
当我们购买卡片时,应该确保卡片支持以上标准。
RC522 RFID模块接口定义
市面上的RC522 RFID模块可能因为生产厂家不同外观上会有些许不同,常见的是下图蓝色外观,8个引脚的这种。在模块的PCB上我们可以看到天线的线路布局,模块就是通过天线与靠近它的卡片进行通信的。
上图左上角,蓝色圆扣状卡片是一种可以挂在钥匙扣上的卡片,所有的卡片都有一个惟一的UID,我们可以使用Python脚本来读取它。
上图是RC522 RFID模块的接口定义,从图中可以看出RC522 RFID模块支持UART接口、I2C总线接口和SPI可编程接口。
RC522 RFID模块与树莓派的电路连接
RC522模块有8个引脚,但我们只需要将其中7个引脚连接到树莓派的GPIO接口即可。RC522模块的引脚定义见上图,电路连接见下图。
树莓派3B+如何打开SPI接口
在本项目中,RC522模块使用SPI接口与树莓派进行通信。因此,树莓派的SPI接口必须要先启用,默认情况下树莓派的SPI接口是禁用的,SPI接口如何打开可以参照 修改树莓派I2C总线接口速度 中的做法。也就是从命令行“sudo raspi-config”进入系统配置打开,或者从桌面进入“Raspberry Pi Configuration”面板中去打开。
安装树莓派3B+的SPI接口支持库
这里的支持库分别是“Py-spidev”和“SPI-Py”,安装“Py-spidev”可以使用命令来安装:
sudo apt-get install python-spidev python3-spidev
这样“Py-spidev”就可以同时支持Python 2和Python 3了。虽然使用“py-spidev”可以驱动Python中的SPI接口,但是项目中我们使用了“SPI-Py”,可以通过以下命令来完成安装“SPI-Py”:
cd ~
git clone https://github.com/lthiery/SPI-Py.git
cd SPI-Py
sudo python setup.py install
sudo python3 setup.py install
同样的“SPI-Py”也可以同时支持Python 2和Python 3了。
下载RC522 的Python库
最后我们还需要下载一个RC522 的Python库,它可以实现SPI接口与RC522模块的通信,这个库依赖于上一步中安装的“SPI-Py”。
cd ~
git clone https://github.com/mxgxw/MFRC522-python.git
Python脚本示例
在“MFRC522-python”目录中有一些示例脚本。可以这样使用它:
cd MFRC522-python
进入“MFRC522-python”目录,然后运行“Read.py”
python Read.py
这个脚本的功能是,首先等待RFID模块检测可识别卡。当它检测到一张卡时,读取该卡的UID并将其显示在屏幕上。该脚本可循环执行,也就是当它读取一个UID后,它还会继续等待读取并显示任何检测到的卡片UID。
Python 2 或 Python 3代码
默认情况下,MFRC522的库只支持Python 2。如果使用Python 3也可以很容易的进行修改。我们只需要修改“MFRC522.py”文件即可,按Python 3的语法格式修改9个 print 语句即可。例如,
print "Authentication Error" 修改为:print("Authentication Error")
Python 3语法中,print语句之后的所有内容都应该用括号“()”括起来。这样示例程序也可以在Python 3下运行了,依然采用“python Read.py”。
本项目的Python脚本
为了简化输出,本项目代码中创建了一个修改过的示例脚本。它首先读取一张卡片,打印出UID后等待2秒,这样就不会重复打印相同的UID了,除非你将卡片放置天线感应到的区域超过2秒。
import time
import RPi.GPIO as GPIO
import MFRC522
# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()
# Welcome message
print("Looking for cards")
print("Press Ctrl-C to stop.")
# This loop checks for chips. If one is near it will get the UID
try:
while True:
# Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()
# If we have the UID, continue
if status == MIFAREReader.MI_OK:
# Print UID
print("UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
time.sleep(2)
except KeyboardInterrupt:
GPIO.cleanup()
将上面的代码保存为“rc522_read_card.py”。然后运行:
python rc522_read.py
输出结果如下:
UID是由四个元素组成的数组,脚本将每个元素组合成一个由逗号分隔的字符串。数组的4个元素可以组合成一个纯数字。例如,我的卡片UID是“1483565119”,而不是“148,35,65,119”。至此读卡器项目的雏形就完成了。
C语言操作的是wirePI角

- #include <stdio.h>
- #include <wiringPi.h>
- #include <mcp23017.h>
- // 扩展MCP23017 起始PIN地址
- // MCP23017占用 100-115
- #define EXTEND_BASE 100
- int main (void)
- {
- // wiringPi初始化
- wiringPiSetup( );
- // mcp23017初始化,此时MCP23017的I2C地址为0x20
- mcp23017Setup( EXTEND_BAS E, 0x20 );
- int i;
- for( i = 0 ; i < 16 ; i++ )
- {
- pinMode( EXTEND_BASE + i, OUTPUT );
- }
- for (;;)
- {
- for( i = 0 ; i < 16; i++)
- {
- digitalWrite ( EXTEND_BASE + i, HIGH);
- delay (500);
- digitalWrite ( EXTEND_BASE + i, LOW);
- delay (500);
- }
- }
- return 0 ;
- }
- int mcp23017Setup (const int pinBase, const int i2cAddress)
- {
- int fd ;
- struct wiringPiNodeStruct *node ;
- // 初始化I2C设备
- if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
- return fd ;
- // 附加操作,设置MCP23017设备 I2C操作地址不自动递增
- wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
- // MCP23017加入链表
- node = wiringPiNewNode (pinBase, 16) ;
- // 赋值相应的操作函数 my开头的函数均位于mcp23017.c文件中
- node->fd = fd ;
- node->pinMode = myPinMode ;
- node->pullUpDnControl = myPullUpDnControl ;
- node->digitalRead = myDigitalRead ;
- node->digitalWrite = myDigitalWrite ;
- node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ;
- node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ;
- return 0 ;
- }
- struct wiringPiNodeStruct
- {
- int pinBase ;
- int pinMax ;
- int fd ; // Node specific
- unsigned int data0 ; // ditto
- unsigned int data1 ; // ditto
- unsigned int data2 ; // ditto
- unsigned int data3 ; // ditto
- void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ;
- void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ;
- int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ;
- void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
- void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
- int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
- void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
- struct wiringPiNodeStruct *next ;
- } ;
- // 位于wiringPi.c
- void pinMode (int pin, int mode)
- {
- int fSel, shift, alt ;
- struct wiringPiNodeStruct *node = wiringPiNodes ;
- // PIN编号小于64,内部设备
- if ((pin & PI_GPIO_MASK) == 0)
- {
- // 代码省略
- }
- else
- {
- // 查找是否存在该设备
- if ((node = wiringPiFindNode (pin)) != NULL)
- node->pinMode (node, pin, mode) ;
- return ;
- }
- }
- // 位于mcp23017.c
- static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
- {
- int mask, old, reg ;
- pin -= node->pinBase ;
- // 操作GPA 或 GPB
- if (pin < 8)
- reg = MCP23x17_IODIRA ;
- else
- {
- reg = MCP23x17_IODIRB ;
- pin &= 0x07 ;
- }
- // 获得IODIRx原始值
- mask = 1 << pin ;
- old = wiringPiI2CReadReg8 (node->fd, reg) ;
- // 设置新值
- if (mode == OUTPUT)
- old &= (~mask) ;
- else
- old |= mask ;
- wiringPiI2CWriteReg8 (node->fd, reg, old) ;
- }
- // 位于wiringPi.c
- int digitalWrite (int pin)
- {
- char c ;
- struct wiringPiNodeStruct *node = wiringPiNodes ;
- // PIN编号小于64,内部设备
- if ((pin & PI_GPIO_MASK) == 0)
- {
- // 代码省略
- }
- else
- {
- // 查找是否存在该设备
- if ((node = wiringPiFindNode (pin)) == NULL)
- return LOW ;
- return node->digitalWrite (node, pin) ;
- }
- }
- // 位于mcp23017.c
- static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
- {
- int bit, old ;
- pin -= node->pinBase ;
- bit = 1 << (pin & 7) ;
- // 操作GPA
- if (pin < 8)
- {
- old = node->data2 ;
- if (value == LOW)
- old &= (~bit) ;
- else
- old |= bit ;
- wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ;
- node->data2 = old ;
- }
- // 操作GPB
- else
- {
- old = node->data3 ;
- if (value == LOW)
- old &= (~bit) ;
- else
- old |= bit ;
- wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ;
- node->data3 = old ;
- }
- }
- struct i2c_smbus_ioctl_data
- {
- char read_write ;
- uint8_t command ;
- int size ;
- union i2c_smbus_data *data ;
- } ;
- static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data)
- {
- struct i2c_smbus_ioctl_data args ;
- args.read_write = rw ;
- args.command = command ;
- args.size = size ;
- args.data = data ;
- return ioctl (fd, I2C_SMBUS, &args) ;
- }
- int wiringPiI2CReadReg8 (int fd, int reg)
- {
- union i2c_smbus_data data;
- if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data))
- return -1 ;
- else
- return data.byte & 0xFF ;
- }
- int wiringPiI2CWriteReg8 (int fd, int reg, int value)
- {
- union i2c_smbus_data data ;
- data.byte = value ;
- return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ;
- }
QT 添加自定义类中使用Q_OBJECT宏问题
今天在使用Qt5中,使用类向导添加自定义类后,并添加Q_OBJECT宏,出现报错:error: undefined reference to `vtable for xxxx'
印象中,VS 报此错误一般是虚函数没有实现,仔细检查自定义类,并未发现代码异常。
在Qt中如果要使用信号槽就必须添加Q_OBJECT宏,至于Q_OBJECT宏的作用可以查看帮助里的介绍。要使用Q_OBJECT宏,就必须继承QObject类
如果自定义类型要添加使用Q_OBJECT宏可以通过如下方法:
1. 继承QObject
2. 修改pro文件(也就是文件带*),以达到修改makefile文件的目的(添加删除,空行空格都可以),只要修改pro文件就行。
3. 重新编译
树莓派wiringPi库详解
wiringPi是一个很棒的树莓派IO控制库,使用C语言开发,提供了丰富的接口:GPIO控制,中断,多线程,等等。java 的pi4j项目也是基于wiringPi的,我最近也在看源代码,到时候整理好了会放出来的。
下面开始wiringPi之旅吧!
安装
进入 wiringPi的github (https://git.drogon.net/?p=wiringPi;a=summary) 下载安装包。点击页面的第一个链接的右边的snapshot,下载安装压缩包。
然后进入安装包所在的目录执行以下命令:
>tar xfz wiringPi-98bcb20.tar.gz //98bcb20为版本标号,可能不同
>cd wiringPi-98bcb20
>./build
验证wiringPi的是否安装成功,输入gpio -v,会在终端中输出相关wiringPi的信息。否则安装失败。
编译 和运行
假如你写了一个LEDtest.c 的项目,则如下。
编译:
g++ -Wall -o LEDtest LEDtest.cpp -lwiringPi //使用C++编程 , -Wall 是为了使能所有警告,以便发现程序中的问题
gcc -Wall -o LEDtest LEDtest.c -lwiringPi //使用C语言编程
运行:
sudo ./LEDtest
查看引脚编号表格
使用如下控制台下命令
> gpio readall
也可以查看下面的图。
注意:查看时,将树莓派的USB接口面对自己,这样看才是正确的。
wiringPi库API大全
在使用wiringPi库时,你需要包含头文件 #include<wiringPi.h>。凡是写wiringPi的程序,都包含这个头文件。
硬件初始化函数
使用wiringPi时,你必须在执行任何操作前初始化树莓派,否则程序不能正常工作。
可以调用下表函数之一进行初始化,它们都会返回一个int , 返回 -1 表示初始化失败。
LED闪烁程序
#include<iostream>
#include<cstdlib>
#include<wiringPi.h>
const int LEDpin = 1;
int main()
{
if(-1==wiringPiSetup())
{
cerr<<"setup error\n";
exit(-1);
}
pinMode(LEDpin,OUTPUT);
for(size_t i=0;i<10;++i)
{
digitalWrite(LEDpin,HIGH);
delay(600);
digitalWrite(LEDpin,LOW);
delay(600);
}
cout<<"------------bye-------------"<<endl;
return 0;
}
PWM输出控制LED呼吸灯的例子
#include<iostream>
#include<wiringPi.h>
#include<cstdlib>
using namespace std;
const int PWMpin = 1; //只有wiringPi编号下的1脚(BCM标号下的18脚)支持
void setup();
int main()
{
setup();
int val = 0;
int step = 2;
while(true)
{
if(val>1024)
{
step = -step;
val = 1024;
}
else if(val<0)
{
step = -step;
val = 0;
}
pwmWrite(PWMpin,val);
val+=step;
delay(10);
}
return 0;
}
通过1脚检测 因为按键按下引发的 下降沿,触发中断,反转11控制的LED
#include<iostream>
#include<wiringPi.h>
#include<cstdlib>
using namespace std;
void ButtonPressed(void);
void setup();
/********************************/
const int LEDPin = 11;
const int ButtonPin = 1;
/*******************************/
int main()
{
setup();
//注册中断处理函数
if(0>wiringPiISR(ButtonPin,INT_EDGE_FALLING,ButtonPressed))
{
cerr<<"interrupt function register failure"<<endl;
exit(-1);
}
while(1)
;
return 0;
}
void setup()
{
if(-1==wiringPiSetup())
{
cerr<<"wiringPi setup error"<<endl;
exit(-1);
}
pinMode(LEDPin,OUTPUT); //配置11脚为控制LED的输出模式
digitalWrite(LEDPin,LOW); //初始化为低电平
pinMode(ButtonPin,INPUT); //配置1脚为输入
pullUpDnControl(ButtonPin,PUD_UP); //将1脚上拉到3.3v
}
//中断处理函数:反转LED的电平
void ButtonPressed(void)
{
digitalWrite(LEDPin, (HIGH==digitalRead(LEDPin))?LOW:HIGH );
}
凡是涉及到多线程编程,就会涉及到线程安全的问题,多线程访问同一个数据,需要使用同步锁来保障数据操作正确性和符合预期。
当A线程锁上 锁S 后,其他共用这个锁的竞争线程,只能等到锁被释放,才能继续执行。
成功执行了piLock 函数的线程将拥有这把锁。其他线程想要拥有这把锁必须等到这个线程释放锁,也就是这个线程执行piUnlock后。
同时要扩展的知识是:volatile 这个C/C++中的关键字,它请求编译器不缓存这个变量的数据,而是每次都从内存中读取。特别是在多线程下共享放变量,必须使用volatile关键字声明才是保险的。
/* 修改 cmdline.txt文件 */
>cd /boot/
>sudo vim cmdline.txt
删除【】之间的部分
dwc_otg.lpm_enable=0 【console=ttyAMA0,115200】 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
/*修改 inittab文件 */
>cd /etc/
>sudo vim inittab
注释掉最后一行内容:,在前面加上 # 号
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
sudo reboot 重启
下面是双机通信的一个例子
C51代码,作为串口通信的接发送。serial库请看另一篇文章
#include<reg52.h>
#include"serial.h"
/**********function****************/
bit isOpenPressed(void);
bit isClosePressed(void);
void delay(unsigned int t);
/*********************************/
sbit closeButton = P2^0; //与关闭按键相连的引脚
sbit openButton = P2^1; //与打开按键相连的引脚
void main(void)
{
closeButton = 1; //拉高
openButton = 1; //拉高
EA =1; //打开总中断
serial_init(9600); //初始化51串口
while(1)
{
if(isClosePressed()) //如果关闭按钮按下
{
serial_write(0); //发送数据 0给树莓派
delay(10);
}
else if(isOpenPressed()) //如果打开按钮按下
{
serial_write(1); //发送数据 1给树莓派
delay(10);
}
}
}
bit isOpenPressed(void)
{
bit press =0;
if(0==openButton)
{
delay(5);
if(0==openButton)
{
while(!openButton)
;
press = 1;
}
}
return press;
}
bit isClosePressed(void)
{
bit press =0;
if(0==closeButton)
{
delay(5);
if(0==closeButton)
{
while(!closeButton)
;
press = 1;
}
}
return press;
}
void delay(unsigned int t)
{
unsigned int i ;
unsigned char j;
for(i = t;i>0;i--)
for(j=120;j>0;j--)
;
}
#include<iostream>
#include<cstdlib>
#include<wiringPi.h>
#include<wiringSerial.h>
using namespace std;
void setup();
const int LEDPin = 11;
int main()
{
setup();
int fd; //Linux 的思想是:将一切IO设备,都看做 文件,fd就是代表串口抽象出来的文件
if((fd = serialOpen("/dev/ttyAMA0",9600))==-1) //初始化串口,波特率9600
{
cerr<<"serial open error"<<endl;
exit(-1);
}
while(true)
{
if(serialDataAvail(fd) >= 1) //如果串口缓存中有数据
{
int data = serialGetchar(fd);
if(data==0) //接受到51发送的 数据 0
{
// close led
digitalWrite(LEDPin,LOW);
}
else if(data==1) //接受到51发送的 数据 1
{
//open led
digitalWrite(LEDPin,HIGH);
}
}
}
return 0;
}
void setup()
{
if(-1==wiringPiSetup())
{
cerr<<"set up error"<<endl;
exit(-1);
}
pinMode(LEDPin,OUTPUT);
digitalWrite(LEDPin,HIGH);
}
树莓派上的QT
树莓派安装编译好的库
go编译树莓派上运行的程序
go编译树莓派上运行的程序
选编译为:cross-arm6
命令行arm
set GOOS=linux
set GOARCH=arm
set GOARM=6
命令行Windows
set GOOS=windows
set GOARCH=amd64
命令行Mac
set GOOS=darwin
set GOARCH=amd64
GOOS:目标平台的操作系统(darwin、freebsd、linux、windows)
GOARCH:目标平台的体系架构(386、amd64、arm)
交叉编译不支持 CGO 所以要禁用它
禁止用用:
SET CGO_ENABLED=0
下一篇:快速系统集成板子收集