0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

msp430でi2c keypad

Last updated at Posted at 2023-11-25

以前ジャンク袋で手に入れたkeypadをi2cで使えるようにしてみました。

電話機などで使われている12キーのもので3x4のマトリックスになっています。

image.png

i2c keypadをネットで調べるとマイコンを使ったものと、i2c gpio変換を使ったものがあります。後者はホスト側でスキャンするようです。

ホスト側の処理を簡単にするためにマイコンを使い、8ピンでは処理できないので、ピンの多いMSP430を使います。

image.png

P1はI2CやISPで使うので、P2で処理する事にしてP2.0,P2.1,P2.2が出力でP2.3,P2.4,P2.5,P2.6を入力にします。

ネットの記事を参考に出力には適当なダイオードを入れました。

keypadの端子をP2.1,P2.3,P2.0,P2.6,P2.2,P2.5,P2.4の並びで接続します。

mainのループで繰り返しキースキャンを行い、i2cのリクエストで返すようにします。

以前試したコードをベースにPlatformIOで開発します。

main.c
/*
 * This file is part of the MSP430 USCI I2C slave example.
 *
 * Copyright (C) 2012 Stefan Wendler <sw@kaltpost.de>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * This firmware acts as an I2C slave on address 0x90(W)/0x91(R).
 * It receives a command / parameter pair from the I2C master and
 * sends out a response on a masters read request.
 *
 * The firmware knows two commands:
 *
 * CMD_SETLED: sets the build in LED (P1.0) of the launchpad depending
 * on the given parameter to HIGH (0x01) or LOW (0x00).
 *
 * CMD_GETBTN: copies the state of the build in push-button (P1.3) to
 * the response buffer and transmits it to the master on the next read
 * request.
 *
 * As a I2C master, the bus pirate could be used. To set the BP into
 * I2C mode use:
 *
 *    m4 3
 *
 * Bus-Piret I2C commands to
 *
 * - set LED HIGH (P1.0)
 *    [0x90 0x00 0x01
 *
 * - set LED LOW  (P1.0)
 *    [0x90 0x00 0x00
 *
 * - get BUTTON state (P1.3)
 *    [0x90 0x01 [0x91 r
 *
 * For a quick start to setup the I2C slave, the TI USCI I2C slave
 * code from slaa383 was used and slightly modified to work on
 * the MSP430G2553 and the MSP-GCC. For detail on leagal issues
 * regarding the TI_USCI_I2C_slave code see "ti-usci-i2c-slave-legal.txt".
 *
 * NOTE: 100k extrnal pull-ups are needed on SDA/SDC.
 */

#include <msp430.h>
#include <legacymsp430.h>

#include "TI_USCI_I2C_slave.h"

/* callback for start condition */
void start_cb();

/* callback for bytes received */
void receive_cb(unsigned char receive);

/* callback to transmit bytes */
void transmit_cb(unsigned char volatile *receive);

/* Commands */
#define CMD_SETLED  0x00
#define CMD_GETBTN  0x01
#define CMD_GETKEY  0x02
#define CMD_UNKNOWN 0xFF

/* Parameters */
#define PAR_LEDOFF  0x00
#define PAR_LEDON   0x01
#define PAR_UNKNOWN 0xFF

/* Responses */
#define RES_ERROR   0xFF


/* last command */
unsigned char cmd = CMD_UNKNOWN;

/* last parameter */
unsigned char par = PAR_UNKNOWN;

/* response to send out on read req. */
unsigned char res = RES_ERROR;

unsigned char key = 0;

void process_cmd(unsigned char cmd, unsigned char par)
{
    res = RES_ERROR;

    switch(cmd) {
    case CMD_SETLED:
        if(par == PAR_LEDON) {
            P1OUT |= BIT0;
        } else if(par == PAR_LEDOFF) {
            P1OUT &= ~BIT0;
        }
        break;
    case CMD_GETBTN:
        if((P1IN & BIT3)) {
            res = 0x01;
        } else {
            res = 0x00;
        }
        break;
    case CMD_GETKEY:
        res = key;
        break;
    }
}

void start_cb()
{
    cmd = CMD_UNKNOWN;
    par = PAR_UNKNOWN;
}

void receive_cb(unsigned char receive)
{
    if(cmd == CMD_UNKNOWN) {

        cmd = receive;

        if(cmd == CMD_GETBTN || cmd == CMD_GETKEY) {
            process_cmd(cmd, PAR_UNKNOWN);
        }
    } else {
        par = receive;
        process_cmd(cmd, par);
    }
}

void transmit_cb(unsigned char volatile *byte)
{
    *byte = res;
}

char keymap_char[12] = {'1', '4', '7', '*', 
                        '2', '5', '8', '0',
                        '3', '6', '9', '#'};

scan()
{
    unsigned int o_pins[3] = {BIT0, BIT1, BIT2};
    unsigned int i_pins[4] = {BIT3, BIT4, BIT5, BIT6};
    int row, col;
    unsigned char tmp = 0;
    int i;

    for(row = 0; row < 3; ++row)
    {
        P2OUT = o_pins[row];
        for (i = 0; i < 100; ++i)
            P2IN;
        for(col = 0; col < 4; ++col)
        {
            if(P2IN & i_pins[col])
                tmp = keymap_char[row*4+col];
        }
        P2OUT = 0;
    }
    key = tmp;
}

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                      // Stop WDT
    P1DIR |= BIT0;                                 // Set P1.0 to output direction
    P1DIR &= ~BIT3;                                // Set P1.3 to input  direction
    P1REN |= BIT3; // Enable internal pullup on P1.3
    P1OUT &= ~BIT0;
 
    TI_USCI_I2C_slaveinit(start_cb, transmit_cb, receive_cb, 0x48);
    BCSCTL1 = CALBC1_16MHZ;
    DCOCTL  = CALDCO_16MHZ;

    __bis_SR_register(GIE);

    P2SEL = 0;
    P2REN = (BIT3 | BIT4 | BIT5 | BIT6);
    P2DIR = (BIT0 | BIT1 | BIT2);
    while(1) scan();

    return 0;
}

何故かポートの最初の読み込みが安定しないので、ダミーリードを入れてあります。こうするととりあえず正常に拾えます。keypadの問題かもしれません。

ArduinoにはKeypadのライブラリがありますが、C++ではないので使えません。

mruby-bsdiicで拾ってみます。

#!/usr/local/bin/mruby

MSPADDR = 0x48

t = BsdIic.new(0)

last = 0
loop do
  cur = t.read(MSPADDR, 1, 2)
  if cur != 0 && cur != last
    p cur.chr + ","
  end
  last = cur
  usleep 100_000
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?