1.实验平台
开发板:移远EC600X_QuecPython_EVB_V2.0
开发工具:QPYcom
实验目标:使用GPIO和Timer实现数码管的动态显示
2.GPIO和Timer的使用
俗话说的好,工欲善其事,必先利其器。要实现数码管的动态显示一定需要对GPIO有一定的了解,GPIO又称通用型输入输出口,通过GPIO可以实现与外部的通讯、控制和数据的采集。
(1)GPIO特性
移远EC6000x开发板一共支持几十个GPIO,既可以输出也可以输入,并且支持上拉、下拉和浮空三种模式。
通过图片我们可知,GPIO最大输出电压1.35V,最低输出电压0.45V。输入电压范围为-0.3V到2.0V,由此看见GPIO低电平驱动能力大于高电平驱动能力。
(2)电平转换
从上图可知,GPIO标准输出为1.8v左右。在实际使用中常常要解决电平转换问题,实质上是要解决IO电平兼容问题,即VOL< VIL VOH >VIH。查看移远的硬件设计手册得知EC600X开发板采用Texas Instruments 公司(TI)的TXS0108EPWR双向电平转换IC。下面是原理图:
需要注意的是:采用TXS0108EPWR最大数据速率
– 110Mbps(推挽)
– 1.2Mbps(开漏)
• A 端口 1.2V 至 3.6V;B 端口 1.65V 至 5.5V (VCCA≤ VCCB)
详见TXS0108EPWR中文数据手册
(3)GPIO操作函数
在使用GPIO之前需要从machine硬件包中导入Pin,然后创建GPIO对象并设置输入输出模式和驱动模式。
from machine import Pin
gpio1 = Pin(Pin.GPIO8,Pin.OUT,Pin.PULL_PU,0) #创建gpio对象 设置gpio8为上拉输出模式,初始为低电平
#Pin.OUT 设置输出模式 Pin.IN设置输入模式
#Pin.PULL_PU 设置上拉 Pin.PULL_PD 设置下拉 Pin.PULL_DISABLE 设置浮空
gpio1.write(0) #设置PIN脚电平,设置高低电平前需要保证引脚为输出模式。0 - 低电平 1 - 高电平
value = gpio1.read() #获取PIN脚电平,0-低电平,1-高电平。
gpio1.set_dir(Pin.OUT) #gpio设置输出方向 Pin.OUT 设置输出模式 Pin.IN设置输入模式
value = gpio1.get_dir() #获取输出方向 PIN模式,0-输入模式,1-输出模式。
(4) 定时器
移远定时器的使用更为简单。如操作GPIO一样,先导入Timer然后创建一个Timer对象,并设置使用的定时器号。
form machine import Timer
def func() : #定时器回调函数
print('hello world')
return
mytimer = Timer(Timer.Timer1) #创建一个定时器对象并使用Timer1
mytimer.start(period=1000, mode=timer1.PERIODIC, callback=func)
#启动定时器 设置定时周期 period = 1000ms 定时模式 mode = timer1.PERIODIC 自动重载 mode = Timer.ONE_SHOT 单次模式 callback = func 注册回调函数
mytimer.stop() #暂停定时器
需要注意的是 period 最小值不能超过 5 ms,一旦小于5ms 定时器将不工作。
动态数码管实验
上面我们已经学习了GPIO和定时器的使用,现在来做一个简单的实验,驱动数码管显示字符即0-9包含空格和小数点。实验采用2位共阳极数码管,使用8个GPIO控制段选和2个GPIO控制片选加三极管放大见下图。
==上图没有添加限流电阻,有可能会烧坏数码管,请读者自行根据实际计算。==废话不多说直接贴代码。
from machine import Timer
from machine import Pin
import utime
def timerfunc(arg): #定时器回调函数
rst.handler() #数码管处理函数
#rst.stop()
#byte 转换 bit
def byte2bit(Bytes):
tmp = []
for x in range(0,8):
tmp.append((~Bytes>>(7-x))&0x01) #取反是因为numtable中是共阴极段码表
return tmp
numtable ={
'0': byte2bit(0x3f),
'1': byte2bit(0x06),
'2': byte2bit(0x5b),
'3': byte2bit(0x4f),
'4': byte2bit(0x66),
'5': byte2bit(0x6d),
'6': byte2bit(0x7d),
'7': byte2bit(0x07),
'8': byte2bit(0x7f),
'9': byte2bit(0x6f),
'A': byte2bit(0x77),
'B': byte2bit(0x7c),
'C': byte2bit(0x39),
'D': byte2bit(0x5e),
'E': byte2bit(0x79),
'F': byte2bit(0x71),
' ': byte2bit(0x00),
'.': byte2bit(0x80),
'0.': byte2bit(0x3f+0x80),
'1.': byte2bit(0x06+0x80),
'2.': byte2bit(0x5b+0x80),
'3.': byte2bit(0x4f+0x80),
'4.': byte2bit(0x66+0x80),
'5.': byte2bit(0x6d+0x80),
'6.': byte2bit(0x7d+0x80),
'7.': byte2bit(0x07+0x80),
'8.': byte2bit(0x7f+0x80),
'9.': byte2bit(0x6f+0x80)
}
# 断码表 0-9 0.-9. A-F
def mystr2list(tmp):
tmp1 = list(tmp)
conut = len(tmp1)
i = 0
result = []
while i < conut:
if i == 0 and tmp1[i] == '.': #首小数点不结合
result.append('.')
i = i+1
elif i < conut-1 and tmp[i+1] == '.':#小数点与前面的数字结合
result.append(tmp[i] + tmp[i+1])
i = i+2
else:
result.append(tmp[i])
i=i+1
return result
#字符串处理函数
#小数点自动与数字结合
class Display_led(object):
def __init__ (self,gap_time=1000,data_pin=[Pin.GPIO8,Pin.GPIO13,Pin.GPIO11,Pin.GPIO14,Pin.GPIO10,Pin.GPIO9,Pin.GPIO28,Pin.GPIO12],duan_pin=[Pin.GPIO19,Pin.GPIO29]):
self.gap_time = gap_time
self.data_pin = [Pin(x,Pin.OUT,Pin.PULL_PU,0) for x in data_pin] #段选
self.duan_pin = [Pin(x,Pin.OUT,Pin.PULL_PU,0) for x in duan_pin] #片选
self.duan_max = len(duan_pin) #获取片选位数
self.timer = Timer(Timer.Timer1) #实例化定时器
self.conut = 0
return
def stop(self):
self.timer.stop()
return
def start(self):
self.timer.start(period=self.gap_time, mode=Timer.PERIODIC, callback=timerfunc) #周期运行 定时一秒
return
#初始化定时器
def show(self,str):
self.showarry = mystr2list(str)
return
def __write_byte(self,bytes):
l = numtable[bytes]
duan_count = 0
for i in self.data_pin :
i.write(l[duan_count])
duan_coun += 1
return
#显示一个字符
def handler(self):
self.__write_byte(' ') #消隐
i = 0
for value in self.duan_pin :
if i == self.conut :
value.write(1)
else :
value.write(0)
i = i+1
self.__write_byte(self.showarry[self.conut])
self.conut = self.conut + 1
if self.conut >= self.duan_max :
self.conut = 0
return
rst = Display_led(gap_time = 5)
rst.start()
done = 0.0
while True:
done += 0.1
if done >= 9.9:
done = 0.0
print(done)
rst.show("%3.1f"%(done))
utime.sleep(1)
#测试code
ps:由于数码管模块没有在身边,不能上传测试图片。如果遇到不能正常显示,请查看数码管极性和查看移远GPIO引脚号是否对应。移远PIn手册如下:Pin