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);
}