PICでI2Cを試す(ソースコード)

PIC16F1827のデータシートを読んだけどけっこうなページ数でよくわからない。
「スレーブ・モードで1バイトを受信するだけ」という単純な仕様として、まずは必要な設定を見極めたい。
手元の参考書をいろいろ調べて、最終的には後閑さんのPIC16Fガイドブックを参考に書いてみた。

/* 
 * File:   main.c
 * Author: sakai
 *
 * Created on 2015/05/02, 6:06
 */

#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

unsigned char flag = 0;
unsigned char data;
unsigned char data_flag = 0;

static void interrupt intr(void) {
    // 割り込み
    if (SSP1IF == 1) {
        if (SSP1STAT & 0b00010000) {    // Stop bit
            RA3 = 1;
        }
        if (SSP1STAT & 0b00001000) {    // Start bit
            RA2 = 1;
        }
        if (SSP1STAT & 0b00000100) {    // R/W
            RA6 = 1;
        } else {
            RA7 = 1;
        }
        if (SSP1STAT & 0b00000001) {    // Buffer Full
            RA0 = 1;
        } else {
            RA0 = 0;
        }
        if ((SSP1STAT & 0b00000001) && ((SSP1STAT & 0b00000100) == 0)) {
            // Write & Buffer Full
            data = SSP1BUF;
            data_flag = 1;
        }
        SSP1CON1 = 0b11111110;
        SSP1IF = 0; // クリア
        flag = 1;
    }
}

/*
 * 
 */
int main(int argc, char** argv) {
    OSCCON = 0b11110000;  // 内蔵オシレーターで32MHzで動かす
    // A, Bポートの設定
    ANSELA = 0;
    ANSELB = 0;
    TRISA = 0b00000000;
    TRISB = 0b00010010;
    PORTA = 0b00000000;
    PORTB = 0b00000000;
    // I2Cスレーブモードの設定
    SSP1ADD = 0x40; // アドレス=0x20
    SSP1CON1 = 0b11111110;  // Slave 7bit address
    SSP1CON2 = 0b10000001;  // SEN:1 clock stretch enable -> CKP:0
    SSP1STAT = 0b00000000;
    // 割り込み可能に設定
    PIE1     = 0b00001000;
    INTCON   = 0b11000000;
    
    while (1) {
        RA4 = 0;
        __delay_ms(100);
        RA4 = 1;
        __delay_ms(100);
        if (flag) {
            __delay_ms(1000);
            PORTA = 0b00000000;
            flag = 0;
        }
        if (data_flag) {
            if (data == 0x30) {
                PORTA = 0b00000001;
            } else if (data == 0x31) {
                PORTA = 0b00000010;
            } else if (data == 0x32) {
                PORTA = 0b00000100;
            } else if (data == 0x33) {
                PORTA = 0b00001000;
            } else {
                PORTA = 0b00001111;
            }
            data_flag = 0;
        }
    }
    return (EXIT_SUCCESS);
}

カテゴリー: PIC, 作業 タグ: , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください