2020年8月1日 星期六

I2C串列通訊實作Part4 – RFID

電路圖

 
 
 
 

程式列表

  • epy_pn532.py

"""

 epy_pn532.py

 

 ePy   PN532

 ------------

 3V3   VCC

 P19   SCL

 P20   SDA

 GND   GND

"""

 

from machine import KEY  #獲取按鍵KEY

from pn532api import PN532

 

if __name__== "__main__":

  key_c = KEY(KEY.KEYC)    #創建按鍵C

  nfc = PN532()

 

  # setup the device

  nfc.setup()

 

  # keep reading until a value is returned

  while True:

    read = nfc.read()

    #print(read)

    print("".join("\\x%02x" % i for i in read))

    if key_c.value() == 0:      #如果按鍵C被按下

      break

 

key_c.deinit()

 

  • pn532api.py

"""

# pn532api.py contains a set of core functions

 Reference: https://github.com/hoanhan101/pn532

"""

 

from micropython import const

from machine import I2C, PIN

import pn532register

import utime

 

# rest time in second betweet each read/write transaction

REST_INTERVAL = 500

 

# maximum block size for each read transaction

BLOCK_SIZE = 20

 

class PN532(object):

  def __init__(self):

    # i2c device address

    self.address = pn532register.PN532_DEFAULT_ADDRESS

 

    # smbus object

    self.bus = I2C(1,100000)    #創建頻率為100kHzI2C外設,選擇要使用的外設I2C 1

 

  def setup(self):

    """setup the device"""

    self.sam_config()

 

  def read(self):

    """return a raw reading value as an array of bytes"""

    self.in_list_passive_target()

 

    while True:

      read = self.read_addr(BLOCK_SIZE)

      # check the first 3 bytes to see if a card is detected or not

      if read[:3] != [0x00, 0x80, 0x80]:

        # TODO - the first 9 bytes are configs bytes so we're not really

        # interested in getting these at the moment, though they could

        # be used for validation in the future

        return read[9:]

 

  def sam_config(self):

    """send SAMConfiguration command"""

    self.write_addr(

      construct_frame([pn532register._COMMAND_SAMCONFIGURATION, 0x01, 0x01, 0x00])

    )

    self.read_addr(BLOCK_SIZE)

 

  def in_list_passive_target(self):

    """send InListPassiveTarget command"""

    self.write_addr(

      construct_frame([pn532register._COMMAND_INLISTPASSIVETARGET, 0x01, 0x00])

    )

    self.read_addr(BLOCK_SIZE)

 

  def write_addr(self, data):

    """write to its own address with given block data"""

    utime.sleep_ms(REST_INTERVAL)

 

    self.bus.write(1,self.address,data,len(data),1)

 

  def read_addr(self, length):

    """read from its own address a given-length of block data"""

    utime.sleep_ms(REST_INTERVAL)

 

    buf = bytearray(length)

    self.bus.read(1,self.address,buf,length,1)

 

  return buf

 

def construct_frame(data):

  """construct frame for communicating between host controller and pn532"""

  # begin with 6-bytes frame structure

  buf = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

  buf[0] = pn532register._PREAMBLE

  buf[1] = pn532register._STARTCODE1

  buf[2] = pn532register._STARTCODE2

  buf[3] = len(data) + 1       # number of bytes in data and frame identifier field

  buf[4] = (~buf[3] & 0xFF) + 0x01 # packet length checksum

  buf[5] = pn532register._HOSTTOPN532

 

  tmp_sum = pn532register._HOSTTOPN532

  for b in data:

    tmp_sum += b

    buf.append(b)

 

  buf.append((~tmp_sum & 0xFF) + 0x01) # data checksum

  buf.append(pn532register._POSTAMBLE)

 

  return buf

 

  • pn532register.py

# -*- coding: utf-8 -*-

#

# pn532register.py contains a set of registers addresses mapping

#

 

PN532_DEFAULT_ADDRESS = 0x24

 

_PREAMBLE   = 0x00

_STARTCODE1 = 0x00

_STARTCODE2 = 0xFF

_POSTAMBLE  = 0x00

 

# frame identifier

_HOSTTOPN532 = 0xD4

 

_COMMAND_SAMCONFIGURATION = 0x14

_COMMAND_INLISTPASSIVETARGET = 0x4A

 執行結果

 

沒有留言:

張貼留言