ピン数の多いPIC16F1938を使ってI2Cのデータを表示するデバイスを作った。
次の回路図では7セグLEDのための抵抗に表示の関係で2kΩと書いてあるけど、実際には2.2kΩを使っている。しかし、これらは1kΩ以下くらいにすれば良かったと思っている。
7セグLEDは半透明なカバーが付いているし、特に桁が2桁あってダイナミック点灯にしているから暗くなりがちなので。
送信するバイト数を変えられるようにArduinoのスケッチを書き換えた。
#include <Wire.h> void setup() { // put your setup code here, to run once: Wire.begin(); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: if (Serial.available()) { delay(100); Wire.beginTransmission(0x20); while (Serial.available() > 0) { Wire.write(Serial.read()); } Wire.endTransmission(); } }
PICのソースコード。
/* * File: main.c * Author: sakai * * Created on 2015/05/05, 6:58 */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #define _XTAL_FREQ 32000000 #pragma config FOSC = INTOSC // INTOSCIO #pragma config CLKOUTEN = OFF #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config MCLRE = ON #pragma config BOREN = ON // Brown Out Detect #pragma config WDTE = OFF #pragma config CPD = OFF // Data Code Protection bit #pragma config CP = OFF #pragma config PWRTE = ON #pragma config PLLEN = OFF #pragma config STVREN = ON #pragma config WRT = OFF #pragma config BORV = HI #pragma config LVP = OFF #define MAX_BUFF (32) unsigned char flag = 0; unsigned char data[MAX_BUFF]; unsigned char data_flag = 0; unsigned char dp_flag = 0; unsigned char loop = 0; static void interrupt intr(void) { // 割り込み if (SSPIF == 1) { data[data_flag] = SSPSTAT; data_flag++; if (SSPSTAT & 0b00000001) { data[data_flag] = SSPBUF; data_flag++; } SSPCON1 = 0b11111110; SSPIF = 0; // クリア loop = 0; } } void display_digit(unsigned char b, int col) { PORTB = 0b00000000; unsigned char data_a; switch (b) { case 0: data_a = 0b00111111; break; case 1: data_a = 0b00100100; break; case 2: data_a = 0b01110011; break; case 3: data_a = 0b01110110; break; case 4: data_a = 0b01101100; break; case 5: data_a = 0b01011110; break; case 6: data_a = 0b01011111; break; case 7: data_a = 0b00110100; break; case 8: data_a = 0b01111111; break; case 9: data_a = 0b01111110; break; case 0x0a: data_a = 0b01111101; break; case 0x0b: data_a = 0b01001111; break; case 0x0c: data_a = 0b00011011; break; case 0x0d: data_a = 0b01100111; break; case 0x0e: data_a = 0b01011011; break; case 0x0f: data_a = 0b01011001; break; default: data_a = 0b00000000; break; } if (dp_flag & 1) { if (col == 1) { data_a |= 0b10000000; } } else if (dp_flag & 2) { if (col == 2) { data_a |= 0b10000000; } } PORTA = data_a; unsigned char data_b; if (col == 1) { data_b = 0b00000010; } else { data_b = 0b00000100; } if (dp_flag) { data_b |= 1; } PORTB = data_b; } /* * */ int main(int argc, char** argv) { OSCCON = 0b11110000; // A, Bポートの設定 ANSELA = 0; ANSELB = 0; TRISA = 0b00000000; TRISB = 0b00000000; PORTA = 0b00000000; PORTB = 0b00000000; // I2Cスレーブモードの設定 SSPADD = 0x40; // アドレス=0x20 SSPCON1 = 0b11111110; // Slave 7bit address SSPCON2 = 0b10000001; // SEN:1 clock stretch enable -> CKP:0 SSPSTAT = 0b00000000; // 割り込み可能に設定 PIE1 = 0b00001000; INTCON = 0b11000000; unsigned char index = 0; unsigned char clear_count = 0; while (1) { if (data_flag) { if (index == 0) { display_digit(data_flag>>4, 1); __delay_ms(2); display_digit(data_flag&0x0f, 2); __delay_ms(2); } else { unsigned char disp = data[index - 1]; display_digit(disp>>4, 1); __delay_ms(2); display_digit(disp&0x0f, 2); __delay_ms(2); } } else { display_digit(0x20, 1); __delay_ms(2); display_digit(0x20, 2); __delay_ms(2); } loop++; if (loop >= 150) { if (dp_flag == 0) { dp_flag = 2; } else { dp_flag = 0; } loop = 0; index++; if (index > data_flag) { index = 0; clear_count++; if (clear_count > 5) { clear_count = 0; data_flag = 0; } } } } return (EXIT_SUCCESS); }