打印
[汽车MCU – KEA]

基于KEA单片机的出租车载nfc终端设计

[复制链接]
17022|97
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gxliu08|  楼主 | 2014-6-25 19:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 gxliu08 于 2014-6-26 13:20 编辑

为出租车设计一款车载nfc终端,支持公交一卡通,支持手机支付,手机交互(获取消费优惠券、打车确认等等),器件选择KEA系列单片机,射频卡控制器暂选NXP PN532,车载12伏供电。

相关帖子

沙发
gxliu08|  楼主 | 2014-6-25 19:41 | 只看该作者
近场通信(Near Field Communication,NFC),又称近距离无线通信,是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据传输(在十厘米内)交换数据。这个技术由免接触式射频识别(RFID)演变而来,并向下兼容RFID,最早由Sony和Philips各自开发成功,主要用于手机等手持设备中提供M2M(Machine to Machine)的通信。
NFC 芯片是具有相互通信功能,并具有计算能力,在Felica标准中还含有加密逻辑电路,MIFARE的后期标准也追加了加密/解密模块(SAM)。NFC标准兼容了索尼公司的FeliCaTM标准,以及ISO 14443 A,B,也就是使用飞利浦的MIFARE标准。在业界简称为TypeA,TypeB和TypeF,其中A,B为Mifare标准,F为Felica标准。为了推动 NFC 的发展和普及,业界创建了一个非营利性的标准组织——NFC Forum,促进 NFC 技术的实施和标准化,确保设备和服务之间协同合作。目前,NFC Forum在全球拥有数百个成员,包括:SONY、 Phlips、LG、摩托罗拉、NXP、NEC、三星、atoam、Intel、其中中国成员有中国移动、华为、中兴、上海同耀和台湾正隆等公司。

使用特权

评论回复
板凳
gxliu08|  楼主 | 2014-6-25 19:42 | 只看该作者
NFC信息也是通过频谱中无线频率部分的电磁感应耦合方式传递,但两者之间还 是存在很大的区别。首先,NFC是一种提供轻松、安全、迅速的通信的无线连接技术,其传输 范围比RFID小,RFID的传输范围可以达到几米、甚至几十米,但由于NFC采取了独特的信号衰 减技术,相对于RFID来说NFC具有距离近、带宽高、能耗低等特点。 其次,NFC与现有非接触 智能卡技术兼容,目前已经成为得到越来越多主要厂商支持的正式标准。再次,NFC还是一种 近距离连接协议,提供各种设备间轻松、安全、迅速而自动的通信。与无线世界中的其他连接 方式相比,NFC是一种近距离的私密通信方式。最后,RFID更多的被应用在生产、物流、跟踪 、资产管理上,而NFC则在门禁、公交、手机支付等领域内发挥着巨大的作用。

使用特权

评论回复
地板
gxliu08|  楼主 | 2014-6-25 19:43 | 只看该作者
工作模式:
卡模式(Card emulation):这个模式其实就是相当于一张采用RFID技术的IC卡。可以替代现 在大量的IC卡(包括信用*)场合商场刷卡、公交卡、门禁管制,车票,门票等等。此种方式 下,有一个极大的优点,那就是卡片通过非接触读卡器的 RF 域来供电,即便是寄主设备(如 手机)没电也可以工作。
点对点模式(P2P mode):这个模式和红外线差不多,可用于数据交换,只是传输距离较短, 传输创建速度较快,传输速度也快些,功耗低(蓝牙也类似)。将两个具备NFC功能的设备链 接,能实现数据点对点传输,如下载音乐、交换图片或者同步设备地址薄。因此通过NFC,多 个设备如数位相机、PDA、计算机和手机之间都可以交换资料或者服务。
读卡器模式(Reader/writer mode):作为非接触读卡器使用,比如从海报或者展览信息电子标 签上读取相关信息。
NFC天线:
一种近场耦合天线,由于13.56Mhz波长很长,且读写距离很短,合适的耦合方式是磁场耦合, 线圈是合适的耦合方式。 业界在手机中通常采用磁性薄膜(如TDK等公司生产)贴合FPC方式 来做天线。一种新技术是磁性薄膜与FPC合一,也即磁性FPC。
NFC标签种类:
NFC的基本标签类型有四种,以1至4来标识,各有不同的格式与容量。这些标签类型格式的基 础是:ISO 14443的A与B类型、Sony FeliCa,前者是非接触式智能卡的国际标准,而后者符合 ISO 18092被动式通讯模式标准。 保持NFC标签尽可能简单的优势是:在很多场合,标签可为 一次性使用,例如在海报中寿命较短的场合。
第1类标签(Tag 1 Type):此类型基于ISO14443A标准。此类标签具有可读、重新写入的能力 ,用户可将其配置为只读。存储能力为96字节,用来存网址URL或其他小量数据富富有余。然 而,内存可被扩充到2k字节。此类NFC标签的通信速度为106 kbit/s。此类标签简洁,故成本 效益较好,适用于许多NFC应用
第2类标签(Tag 2 Type):此类标签也是基于ISO14443A,具有可读、重新写入的能力,用户 可将其配置为只读。其基本内存大小为48字节,但可被扩充到2k字节。通信速度也是106  kbit/s。
第3类标签(Tag 3 Type):此类标签基于Sony FeliCa体系。目前具有2k字节内存容量,数据 通讯速度为212 kbit/s。故此类标签较为适合较复杂的应用,尽管成本较高。
第4类标签(Tag 4 Type):此类标签被定义为与ISO14443A、B标准兼容。制造时被预先设定 为可读/可重写、或者只读。内存容量可达32k字节,通信速度介于106 kbit/s和424 kbit/s之 间。

使用特权

评论回复
5
gxliu08|  楼主 | 2014-6-25 22:10 | 只看该作者
PN532特性:
带40 kB ROM和1 kB RAM的80C51微控制器内核;
高度集成的模拟电路,解调和译码响应;
输出缓冲驱动器通过最少量的外部无源器件连接天线;
集成了RF场检测器;
集成了数据模式检测器;
支持ISO/IEC 14443A / MIFARE;
只在读写器模式中支持ISO/IEC 14443B;
在读写器模式中典型工作距离超过50mm,具体距离由天线尺寸、调谐和电源决定;
在NFCIP-1模式下工作距离高达50mm,具体视天线的尺寸、调谐以及电源而定;
在卡操作模式中典型工作距离约为100mm,具体距离由天线尺寸、调谐和外部场强度决定;
在读写器模式中,支持Mifare Classic加密,可支持212 kbit/s和424 kbit/s两种更高数据传输速率;
FeliCa模式下,支持106kbit/s 、212kbit/s和424kbit/s的通信波特率;
集成了NFCIP-1的RF接口,传输速率高达424kbit/s;
支持主机接口:
   -SPI接口;
   -I2C接口;
   -串行UART;
灵活的中断模式;
低功耗模式 一硬件掉电模式 一软件掉电模式;
当器件处于掉电模式时能够通过I2C、HSU和SPI接口自动唤醒;
可编程定时器;
石英晶体振荡器;
2.7V~5.5V的电源;
供外部加密芯片使用的电源切换功能;
控制外部设备的专用I/O管脚;
供产品测试使用的集成天线检测器;
与外部加密IC连接的ECMA 373 NFC-WI接口;

我打算用SPI接口,KEA与PN532接口

使用特权

评论回复
6
ar_m_cu| | 2014-6-26 09:39 | 只看该作者
不错,不过现在市面上好像已经有很多这样的东西了。楼主需要有点改进和创新才行啊

使用特权

评论回复
7
gxliu08|  楼主 | 2014-6-26 10:08 | 只看该作者
本帖最后由 gxliu08 于 2014-6-26 10:12 编辑
ar_m_cu 发表于 2014-6-26 09:39
不错,不过现在市面上好像已经有很多这样的东西了。楼主需要有点改进和创新才行啊 ...

那是普通读卡器,我要做的支持nfc的,刷公交卡的我早就做过了。这个要和手机互通。nfc和RFID的区别是很大的,不过好多人搞不清。很多开发也是仅仅当RFID用。

使用特权

评论回复
8
gxliu08|  楼主 | 2014-6-26 10:16 | 只看该作者
PN532 SPI驱动,准备移植到KEA

#include "PN532_SPI.h"
#include "PN532_debug.h"

#define STATUS_READ     2
#define DATA_WRITE      1
#define DATA_READ       3

PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss)
{
    command = 0;
    _spi = &spi;
    _ss  = ss;
}

void PN532_SPI::begin()
{
    pinMode(_ss, OUTPUT);

    _spi->begin();
    _spi->setDataMode(SPI_MODE0);  // PN532 only supports mode0
    _spi->setBitOrder(LSBFIRST);
#ifndef __SAM3X8E__
    _spi->setClockDivider(SPI_CLOCK_DIV8); // set clock 2MHz(max: 5MHz)
#else
    /** DUE spi library does not support SPI_CLOCK_DIV8 macro */
    _spi->setClockDivider(42);             // set clock 2MHz(max: 5MHz)
#endif

}

void PN532_SPI::wakeup()
{
    digitalWrite(_ss, LOW);
    delay(2);
    digitalWrite(_ss, HIGH);
}



int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
{
    command = header[0];
    writeFrame(header, hlen, body, blen);
   
    uint8_t timeout = PN532_ACK_WAIT_TIME;
    while (!isReady()) {
        delay(1);
        timeout--;
        if (0 == timeout) {
            DMSG("Time out when waiting for ACK\n");
            return -2;
        }
    }
    if (readAckFrame()) {
        DMSG("Invalid ACK\n");
        return PN532_INVALID_ACK;
    }
    return 0;
}

int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
{
    uint16_t time = 0;
    while (!isReady()) {
        delay(1);
        time++;
        if (timeout > 0 && time > timeout) {
            return PN532_TIMEOUT;
        }
    }

    digitalWrite(_ss, LOW);
    delay(1);

    int16_t result;
    do {
        write(DATA_READ);

        if (0x00 != read()      ||       // PREAMBLE
                0x00 != read()  ||       // STARTCODE1
                0xFF != read()           // STARTCODE2
           ) {

            result = PN532_INVALID_FRAME;
            break;
        }

        uint8_t length = read();
        if (0 != (uint8_t)(length + read())) {   // checksum of length
            result = PN532_INVALID_FRAME;
            break;
        }

        uint8_t cmd = command + 1;               // response command
        if (PN532_PN532TOHOST != read() || (cmd) != read()) {
            result = PN532_INVALID_FRAME;
            break;
        }

        DMSG("read:  ");
        DMSG_HEX(cmd);

        length -= 2;
        if (length > len) {
            for (uint8_t i = 0; i < length; i++) {
                DMSG_HEX(read());                 // dump message
            }
            DMSG("\nNot enough space\n");
            read();
            read();
            result = PN532_NO_SPACE;  // not enough space
            break;
        }

        uint8_t sum = PN532_PN532TOHOST + cmd;
        for (uint8_t i = 0; i < length; i++) {
            buf[i] = read();
            sum += buf[i];

            DMSG_HEX(buf[i]);
        }
        DMSG('\n');

        uint8_t checksum = read();
        if (0 != (uint8_t)(sum + checksum)) {
            DMSG("checksum is not ok\n");
            result = PN532_INVALID_FRAME;
            break;
        }
        read();         // POSTAMBLE

        result = length;
    } while (0);

    digitalWrite(_ss, HIGH);

    return result;
}

boolean PN532_SPI::isReady()
{
    digitalWrite(_ss, LOW);

    write(STATUS_READ);
    uint8_t status = read() & 1;
    digitalWrite(_ss, HIGH);
    return status;
}

void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
{
    digitalWrite(_ss, LOW);
    delay(2);               // wake up PN532

    write(DATA_WRITE);
    write(PN532_PREAMBLE);
    write(PN532_STARTCODE1);
    write(PN532_STARTCODE2);

    uint8_t length = hlen + blen + 1;   // length of data field: TFI + DATA
    write(length);
    write(~length + 1);         // checksum of length

    write(PN532_HOSTTOPN532);
    uint8_t sum = PN532_HOSTTOPN532;    // sum of TFI + DATA

    DMSG("write: ");

    for (uint8_t i = 0; i < hlen; i++) {
        write(header[i]);
        sum += header[i];

        DMSG_HEX(header[i]);
    }
    for (uint8_t i = 0; i < blen; i++) {
        write(body[i]);
        sum += body[i];

        DMSG_HEX(body[i]);
    }

    uint8_t checksum = ~sum + 1;        // checksum of TFI + DATA
    write(checksum);
    write(PN532_POSTAMBLE);

    digitalWrite(_ss, HIGH);

    DMSG('\n');
}

int8_t PN532_SPI::readAckFrame()
{
    const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};

    uint8_t ackBuf[sizeof(PN532_ACK)];

    digitalWrite(_ss, LOW);
    delay(1);
    write(DATA_READ);

    for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
        ackBuf[i] = read();
    }

    digitalWrite(_ss, HIGH);

    return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
}

使用特权

评论回复
9
gxliu08|  楼主 | 2014-6-26 10:18 | 只看该作者
每天都有成百上千吨的优惠券被打印出来发送给路人。这么做既不环保,用起来也麻烦。而设计这个车载NFC终端,只要用手机轻轻碰一下,就能将优惠信息下载到手机上,然后直接去商家享受打折优惠,是不是非常的方便呢?

使用特权

评论回复
10
gxliu08|  楼主 | 2014-6-26 10:22 | 只看该作者
出租车载nfc终端发放优惠券,就需要把自己模拟成标签了。

使用特权

评论回复
11
gxliu08|  楼主 | 2014-6-26 10:25 | 只看该作者
另外一个重要功能,什么打车软件都可以利用nfc终端进行确认啊,把nfc终端当作最终确认设备,避免恶意欺诈。

使用特权

评论回复
12
gxliu08|  楼主 | 2014-6-26 10:25 | 只看该作者
开始原型设计!

使用特权

评论回复
13
gxliu08|  楼主 | 2014-6-26 10:58 | 只看该作者
貌似这个系列片子不好买啊,是不是还没有量产?

使用特权

评论回复
14
袍哥人家9527| | 2014-6-26 11:03 | 只看该作者
KEA的样品可以找我,QQ29609669

使用特权

评论回复
评分
参与人数 1威望 +4 收起 理由
gxliu08 + 4 赞一个!
15
FSL_TICS_Robin| | 2014-6-26 11:50 | 只看该作者
nfc信息标注+google眼镜,应该会很科幻呢

使用特权

评论回复
评分
参与人数 1威望 +4 收起 理由
gxliu08 + 4 很给力!
16
gxliu08|  楼主 | 2014-6-26 13:07 | 只看该作者
袍哥人家9527 发表于 2014-6-26 11:03
KEA的样品可以找我,QQ29609669

qq加你了,准备在数控电台里用

使用特权

评论回复
17
gxliu08|  楼主 | 2014-6-26 13:16 | 只看该作者
PN532原理图

使用特权

评论回复
18
gxliu08|  楼主 | 2014-6-26 13:19 | 只看该作者
可惜PN532是QFN封装,不太好焊接,还是喜欢FMSH的SO封装,FMSH也有类似NFC产品,我也在用,还不成熟,就不献丑了。

使用特权

评论回复
19
gxliu08|  楼主 | 2014-6-26 13:23 | 只看该作者
淘宝了一下,没有找到该系列片子。

使用特权

评论回复
20
gxliu08|  楼主 | 2014-6-26 13:28 | 只看该作者
有人把libnfc库移植到stm32了,这种感觉和上次看到有人在stm32上跑linux相似,至于吗,写个驱动的事。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

1192

帖子

10

粉丝