前言

原创文章,转载引用务必注明链接。水平有限,如有疏漏,欢迎指正。

本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo。

本文使用Markdown写成,为获得更好的阅读体验和正常的图片、链接,请访问我的博客:

http://www.cnblogs.com/sjqlwy/p/up_1602.html

本文环境:ublinux 3.0;Win7_x64

通过阅读本文你可以学到:

  • UP Board GPIO 接口的介绍以及使用
  • PyCharm 远程调试 UP上的Python代码
  • Lemaker LN IO 拓展板的使用
  • 使用RPi.GPIO这个Python库控制1602液晶屏

UP板载GPIO接口介绍

UP板的GPIO接口兼容树莓派40 Pin。实现起来比较复杂,部分从Intel Atom Z8350引出(需要电平转换),部分由板载CPLD实现。

操作GPIO

官方提供了三种方式:用户空间sysfs (shell)、RPi.GPIO库(Python)和libMRAA(多种编程语言)。

Lemaker LN IO拓展板介绍

之前在云汉社区试用Lemaker Guitar开发板时一并入手的。兼容树莓派引脚。个人非常喜欢乐美客公司的产品,包括BananaPi、BananaPi Pro、Lemaker Guitar、96boards Hikey (Lemaker Version),以及包括LN IO在内的三款拓展板,做工优良,可以在官方微店买到。LN IO 介绍页面电路原理图

【下面是Lemaker Guitar开发板,上面就是LN IO 拓展板】我们下面将会利用板载的4个按键、LED灯以及1602接口。

Python控制LN IO 扩展板按键和LED

最近在学习Python,恰巧ubilinux移植了RPi.GPIO库,让我们可以非常方便地操作GPIO资源。吐槽一下,由于被动散热片的存在,使用转接线等会卡到无法完全贴合。

Blink!——控制发光二极管闪烁

我们以点亮LN IO上的led2为例:

【LED电路原理图】LCD和LED是切换显示的。可以看到LED2连接到GPIO0,那么GPIO0是对应树莓派是哪个引脚呢?

【底板对应引脚】GPIO0对应物理引脚11。

【UP Board 引脚定义图】为了方便起见,我们统一使用BOARD物理引脚编号而非BCM引脚编号。

  • 关于树莓派GPIO的操作可以参考芒果爱吃胡萝卜这个博客,写的非常不错,由浅入深。本文部分以他的博文为基础进行演示。
  • ubilinux移植的RPi.GPIO库仅兼容Python 2.x版本
  • 为方便转换,我们以BOARD编码GPIO引脚顺序(物理顺序)
  • LN IO Board的LED和LCD可以切换显示,连接帽导通不同引脚即可。

下面创建一个文件lcd.py,内容如下,然后运行看看:sudo python lcd.py

#!/usr/bin/env python
# encoding: utf-8 import RPi.GPIO as GPIO
import time # 为保持兼容性,选择GPIO引脚主板编号模式,也就是物理引脚编号
GPIO.setmode(GPIO.BOARD)
LedPin = 11
# 指定11引脚(就是LED长针连接的GPIO针脚)的模式为输出模式
# LN IO 的GPIO0,主板编号是11,对应BCM模式引脚为17
GPIO.setup(LedPin, GPIO.OUT) # 循环10次
for i in range(0, 10):
# 让11引脚输出高电平(LED灯亮)
GPIO.output(LedPin, True)
# 持续一段时间
time.sleep(0.5)
# 让11引脚输出低电平(LED灯灭)
GPIO.output(LedPin, False)
# 持续一段时间
time.sleep(0.5) # 最后清理GPIO口(不做也可以,建议每次程序结束时清理一下,好习惯)
GPIO.cleanup()

效果如图所示:

按键控制LED开关

有了上面的我们再来试试用按键控制LED,很多用过Arduino的应该轻车熟路啦。

#!/usr/bin/env python
# encoding: utf-8 import RPi.GPIO as GPIO
import time # 为保持兼容性,选择GPIO引脚主板编号模式,也就是物理引脚编号
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
LedPin = 11
BtnPin = 13 # 11引脚(LED2)为输出模式,13引脚(Key1)为输入模式
GPIO.setup(LedPin, GPIO.OUT)
GPIO.setup(BtnPin, GPIO.IN) try:
GPIO.output(LedPin, True)
while True:
time.sleep(0.01)
if (GPIO.input(BtnPin)) == False:
GPIO.output(LedPin, False)
else:
GPIO.output(LedPin, True)
except KeyboardInterrupt:
pass # 最后清理GPIO口(不做也可以,建议每次程序结束时清理一下,好习惯)
GPIO.cleanup()

有兴趣的可以做一个防按键抖动(Debounce)版本。

Python控制1602液晶屏显示当前时间

感谢Hugo Zhu的这篇《如何使用Raspberry Pi在1602液晶屏上显示当前时间--电子钟》博文,他的博客非常棒,受益匪浅。以下仍然以BOARD编码为例。

硬件包括LN IO 拓展板;1602液晶屏;USB无线网卡;UPBoard。注意LN IO拓展板将连接帽切换到LCD引脚。

1602液晶屏的引脚定义:

  1. VSS,接地
  2. VDD,接3.3V电源
  3. VO,液晶对比度调节,接电位器中间的引脚(板载R2)
  4. RS,寄存器选择,接PB 03,Pin 29
  5. RW,读写选择,接地,表示写模式
  6. EN,使能信号,接PB 13,Pin 33
  7. D0,数据位0,4位工作模式下不用,不接
  8. D1,数据位1,4位工作模式下不用,不接
  9. D2,数据位2,4位工作模式下不用,不接
  10. D3,数据位3,4位工作模式下不用,不接
  11. D4,数据位4,接GPIO 4,Pin 16
  12. D5,数据位5,接GPIO 5,PIN 18
  13. D6,数据位6,接GPIO 6,PIN 22
  14. D7,数据位7,接GPIO 7,PIN 7
  15. A,液晶屏背光+,接3.3v
  16. K,液晶屏背光-,接地

源代码可以从github页面下载,修改相关引脚序号,如下:

#!/usr/bin/python

#
# based on code from lrvick and LiquidCrystal
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
# from time import sleep
from datetime import datetime
from time import sleep class Adafruit_CharLCD: # commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80 # flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00 # flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00 # flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00 # flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00 # flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00 # LN IO Board: RS=PB03=29, EN=PB13=33; DB4-7=GPIO4-7=16,18,22,7
def __init__(self, pin_rs=29, pin_e=33, pins_db=[16,18,22,7], GPIO = None):
# Emulate the old behavior of using RPi.GPIO if we haven't been given
# an explicit GPIO interface to use
if not GPIO:
import RPi.GPIO as GPIO
GPIO.setwarnings(False) self.GPIO = GPIO
self.pin_rs = pin_rs
self.pin_e = pin_e
self.pins_db = pins_db self.GPIO.setmode(GPIO.BOARD)
self.GPIO.setup(self.pin_e, GPIO.OUT)
self.GPIO.setup(self.pin_rs, GPIO.OUT) for pin in self.pins_db:
self.GPIO.setup(pin, GPIO.OUT) self.write4bits(0x33) # initialization
self.write4bits(0x32) # initialization
self.write4bits(0x28) # 2 line 5x7 matrix
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
self.write4bits(0x06) # shift cursor right self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
self.displayfunction |= self.LCD_2LINE """ Initialize to default text direction (for romance languages) """
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode self.clear() def begin(self, cols, lines): if (lines > 1):
self.numlines = lines
self.displayfunction |= self.LCD_2LINE
self.currline = 0 def home(self): self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
self.delayMicroseconds(3000) # this command takes a long time! def clear(self): self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time def setCursor(self, col, row): self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ] if ( row > self.numlines ):
row = self.numlines - 1 # we count rows starting w/0 self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row])) def noDisplay(self):
""" Turn the display off (quickly) """ self.displaycontrol &= ~self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def display(self):
""" Turn the display on (quickly) """ self.displaycontrol |= self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noCursor(self):
""" Turns the underline cursor on/off """ self.displaycontrol &= ~self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def cursor(self):
""" Cursor On """ self.displaycontrol |= self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self):
""" Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self):
""" Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def DisplayLeft(self):
""" These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT) def scrollDisplayRight(self):
""" These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT); def leftToRight(self):
""" This is for text that flows Left to Right """ self.displaymode |= self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode); def rightToLeft(self):
""" This is for text that flows Right to Left """
self.displaymode &= ~self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def autoscroll(self):
""" This will 'right justify' text from the cursor """ self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def noAutoscroll(self):
""" This will 'left justify' text from the cursor """ self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def write4bits(self, bits, char_mode=False):
""" Send command to LCD """ self.delayMicroseconds(1000) # 1000 microsecond sleep bits=bin(bits)[2:].zfill(8) self.GPIO.output(self.pin_rs, char_mode) for pin in self.pins_db:
self.GPIO.output(pin, False) for i in range(4):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i], True) self.pulseEnable() for pin in self.pins_db:
self.GPIO.output(pin, False) for i in range(4,8):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i-4], True) self.pulseEnable() def delayMicroseconds(self, microseconds):
seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
sleep(seconds) def pulseEnable(self):
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, True)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # commands need > 37us to settle def message(self, text):
""" Send string to LCD. Newline wraps to second line""" for char in text:
if char == '\n':
self.write4bits(0xC0) # next line
else:
self.write4bits(ord(char),True) if __name__ == '__main__': lcd = Adafruit_CharLCD()
lcd.noBlink()
# lcd.clear()
# lcd.message("Hello, Jessica!\nHow are you? .....abcdefghijg ")
# lcd.scrollDisplayRight() while True:
sleep(1)
lcd.clear()
lcd.message(datetime.now().strftime(' %I : %M : %S \n%a %b %d %Y'))

每秒更新,显示当前时间,效果如图所示:

进阶

分析代码可知,该代码段可作为1602驱动库,支持1602的基本显示控制。后面可以自定义显示自己的信息,例如做一个小闹钟。

PyCharm远程调试UP Board上的Python程序

由于在UP Board上使用终端界面调试Python确实不很方便(其实是PyCharm用起来太爽了),所以使用Windows 上的PyCharm调试UP Board上的程序,可以直接使用UP的GPIO硬件资源,并且可以非常方便地安装各种库,简直停不下来,当然前文提到的cloud9也不错。远程调试功能只有专业版(Professional)可用,免费的社区版(Community)无此功能。通过edu邮箱验证可以免费使用专业版。

参考这篇文章pycharm 远程调试进行设置即可,注意点如下:

  • 因为我们使用ubilinux移植的RPi.GPIO库,所以解释器只能选择python2
  • 需要启用root账户并更改ssh设置允许root登录
  • 可以通过PyCharm更新UP板上的Python库
sudo passwd root #启用root账户
sudo nano /etc/ssh/sshd_config # 添加 PermitRootLogin yes,Ctrl+O保存,Ctrl+X退出
sudo systemctl restart sshd # 重启SSH服务,使更改生效

效果如图所示:

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)的更多相关文章

  1. Arduino 1602液晶屏实验和程序

    在Arduino IDE中, 项目->加载库->管理库中搜索LiquidCrystal,然后安装即可 1.接线图 2.引脚图 3.最简单程序 #include <LiquidCrys ...

  2. jquery在网页实时显示时间;

    1.定义一个显示时间的位置 <div id="shijian"> </div> 2.jquery代码 function showTime() { var c ...

  3. 使用pycharm远程调试python代码

    使用 pycharm 进行 python 代码远程调试 pycharm 的远程调试是从远程机器连接到本地机器,需要在远程机器的py文件中指定本地机器的IP和端口. 远程机器上,通过easy_insta ...

  4. 在液晶屏里显示浮点数的方法 (sprintf 的妙用)

    思路:使用 sprintf 函数将浮点型数据转为指定格式的字符串 #include <stdio.h> #include<string.h> int main() { unsi ...

  5. [DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)

    首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动函数: /* * fileName: st7565_driver.c * just for LCD12864 driver * GP ...

  6. 给基于对话框的MFC程序添加状态栏并实时显示时间

    转载自丝雪儿 1.首先在string table 里添加两个字串,ID分别为IDS_INDICATOR_MESSAGE and IDS_INDICATOR_TIME 2.在你的 dlg.h 类里面加个 ...

  7. js页面实时显示时间

    1.通过getMonth()实现获取月份,从0开始计数,需要+1: 2.通过getDay()实现获取星期天数,从0开始,0表示星期日: 3.通过getDate()获取日期. 4.setTimeout( ...

  8. Python测试进阶——(2)配置PyCharm远程调试环境

    新建一个Python项目 配置Deployment,用于本地文件和远程文件的同步,在pycharm的菜单栏依次找到:Tools > Deployment > Configuration 点 ...

  9. 单片机中不带字库LCD液晶屏显示少量汉字

    单片机中不带字库LCD液晶屏如何显示少量汉字,一般显示汉字的方法有1.使用带字库的LCD屏,2.通过SD 卡或者外挂spi flash存中文字库,3.直接将需要的汉字取模存入mcu的flash中. 第 ...

随机推荐

  1. windows下升级pip失败,重新安装pip最新版本

    环境: python3.6.5 32bit,后改为python3.4.3 32bit pycharm2018旗舰版 问题: pycharm里的pip一直无法升级到10.0.1版本,在cmd中使用升级命 ...

  2. android sdk 下载

    不知道是因为最近kaihui还是怎么的,打开android sdk官方网站特别的慢,想下载最新版本的platform几乎变成不可能完成的任务,不知道为什么Google不像Apache那样在各国设立镜像 ...

  3. Thymeleaf模板引擎+Spring整合使用方式的介绍

    尊重原创,原文地址为:https://www.cnblogs.com/jiangchao226/p/5937458.html 前言 这个教程介绍了Thymeleaf与Spring框架的集成,特别是Sp ...

  4. Python开发:模块

    在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了. 为此 Python 提供了一个办法,把这些定义存放在文 ...

  5. swift final关键字、?、!可选与非可选符

    ?符号: 可选型 在初始化时可以赋值为nil !符号:  隐形可选型 类型值不能为nil,如果解包后的可选类型为nil会报运行时错误,主要用在一个变量/常量在定义瞬间完成之后值一定会存在的情况.这主要 ...

  6. D. Frequent values

    D. Frequent values Time Limit: 3000ms Case Time Limit: 3000ms Memory Limit: 131072KB   64-bit intege ...

  7. CSAPP学习笔记—虚拟内存

    CSAPP学习笔记—虚拟内存 符号说明 虚拟内存地址寻址 图9-12展示了MMU如何利用页表来实现这种映射.CPU中的一个控制寄存器,页表基址寄存器(Page Table Base Register, ...

  8. Leetcode 336.回文对

    回文对 给定一组唯一的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串. 示例 1: 输入: ["abcd&quo ...

  9. xtrabackup实现全量备份和增量备份

    mysql增量和完全备份innobackupex2.1.9版本1 yum安装: 官网地址:https://www.percona.com/doc/percona-xtrabackup/LATEST/i ...

  10. CSGO

    CSGO Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Problem D ...