この左図を見て下さい、
---------------------------------------------------------------------
#define SCK 13 // クロック信号出力ピン
#define RCK 10 // ラッチ動作出力ピン
#define SI 11 // データ信号出力ピン
void setup() {
pinMode(SCK, OUTPUT) ; // 制御するピンは全て出力に設定する
pinMode(RCK, OUTPUT) ;
pinMode(SI, OUTPUT) ;
delay(3000) ; // 3S後開始
}
void loop() {
digitalWrite(RCK, LOW) ;
shiftOut(SI, SCK, MSBFIRST, 5) ; // 5=0b00000101(0x05) 8ビット出力する
digitalWrite(RCK, HIGH) ; // ラッチ信号を出す
while(1) ; // 処理中断
}
---------------------------------------------------------------------
Arduinoの標準関数でshiftOut()関数が有るのでそれを利用したスケッチです。
---------------------------------------------------------------------
#include "pins_arduino.h"
#include <SPI.h>
void setup() {
SPI.begin() ; // SPIを行う為の初期化
SPI.setBitOrder(MSBFIRST) ; // ビットオーダー
SPI.setClockDivider(SPI_CLOCK_DIV16) ;// クロックをシステムクロックの1/16で使用(16MHz/16)
SPI.setDataMode(SPI_MODE0) ; // クロック極性0(LOW) クロック位相0(LOW)
digitalWrite(SS,LOW) ; // SS(CS)ラインをLOWにする
delay(3000) ; // 3S後開始
}
void loop() {
digitalWrite(SS, LOW) ;
SPI.transfer(5) ; // 5=0b00000101(0x05) 8ビット出力する
digitalWrite(SS, HIGH) ; // ラッチ信号を出す
while(1) ; // 処理中断
}
---------------------------------------------------------------------
今度はSPIでスケッチしてみました。
---------------------------------------------------------------------
void loop() {
int i ;
for (i = 0 ; i < 8 ; i++) {
digitalWrite(SS,LOW) ;
SPI.transfer(1 << i) ;
digitalWrite(SS,HIGH) ;
delay(100);
}
}
---------------------------------------------------------------------
秋月電子のLCDオシロキットで波形を見てみましょう
SCK(Arduinoの13番ピン)の出力です。
SPIの速度をSPIライブラリで設定可能な最高の速度での観測


---------------------------------------------------------------------
#include <xc.h>
#define _XTAL_FREQ 16000000 // delay用に必要(クロック16MHzを指定)
#define RCK RA4 // ラッチ信号出力ピン
#define SCK RA1 // クロック動作出力ピン
#define SI RA0 // データ信号出力ピン
char shiftData ; // 74HC595に出力するシフトデータ
// コンフィギュレーション1の設定
#pragma config FOSC = INTOSC // 内部クロック使用する(INTOSC)
#pragma config WDTE = OFF // ウオッチドッグタイマー無し(OFF)
#pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する(ON)
#pragma config MCLRE = OFF // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(OFF)
#pragma config CP = OFF // プログラムメモリーを保護しない(OFF)
#pragma config CPD = OFF // データメモリーを保護しない(OFF)
#pragma config BOREN = ON // 電源電圧降下常時監視機能ON(ON)
#pragma config CLKOUTEN = OFF // CLKOUTピンをRA4ピンで使用する(OFF)
#pragma config IESO = OFF // 外部・内部クロックの切替えでの起動はなし(OFF)
#pragma config FCMEN = OFF // 外部クロック監視しない(OFF)
// コンフィギュレーション2の設定
#pragma config WRT = OFF // Flashメモリーを保護しない(OFF)
#pragma config PLLEN = OFF // 動作クロックを32MHzでは動作させない(OFF)
#pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON)
#pragma config BORV = HI // 電源電圧降下常時監視電圧(2.5V)設定(HI)
#pragma config LVP = OFF // 低電圧プログラミング機能使用しない(OFF)
// Arduinoの様にプログラムで処理して見た
// bitOrder: 0=LSBFIRST 1=MSBFIRST
void shiftOut(int bitOrder, char value)
{
int x , i ;
for (i=0 ; i < 8 ; i++) {
SCK = 0 ;
if (bitOrder == 0) x = i ; // 0ビット目から順次出力
else x = 7-i ; // 7ビット目から順次出力
if (value & (1 << x)) x = 1 ;
else x = 0 ;
SI = x ; // データビットのセット
SCK = 1 ; // データ読み取り開始の指示
}
}
// 出力するシフトデータのビットを操作する処理 *1)
void bitShiftData(int bitPosition, int bitValue, char *value)
{
if (bitValue == 0) *value = *value & ~(1 << bitPosition) ; // ビットリセット
else *value = *value | (1 << bitPosition) ; // ビットセット
}
// メインの処理
void main()
{
int i ;
OSCCON = 0b01111010 ; // 内部クロックは16MHzとする
ANSELA = 0b00000000 ; // アナログは使用しない(すべてデジタルI/Oに割当てる)
TRISA = 0b00001100 ; // RA2ピン以外を全て出力に割当てる(RA3は入力専用)
PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする)
__delay_ms(3000) ; // 3秒後に開始
RCK = 0 ;
shiftOut(1,5) ; // MSBFIRST 5=0b00000101(0x05) 8ビット出力する
RCK = 1 ; // ラッチ信号を出す
while(1) ; // 処理中断
}
---------------------------------------------------------------------
PIC用shiftOut()関数を作成して見ました。
同じ16MHz動作でもArduinoはSCK出力が15usで
char shiftData ; // 74HC595に出力するシフトデータ
shiftData = 0 ;
bitShiftData(1,1,&shiftData) ; // 1ビット目をセットする
RCK = 0 ;
shiftOut(1,shiftData) ; // 8ビット出力する
RCK = 1 ; // ラッチ信号を出す
※ Arduinoもこの関数をこのまま利用出来ます。
---------------------------------------------------------------------
#define CLK 13 // クロック信号出力ピン
#define STB 10 // ラッチ動作出力ピン
#define DATA 11 // データ信号出力ピン
void setup() {
pinMode(CLK, OUTPUT) ; // 制御するピンは全て出力に設定する
pinMode(STB, OUTPUT) ;
pinMode(DATA, OUTPUT) ;
digitalWrite(STB, HIGH) ;
delay(3000) ; // 3S後開始
}
void loop() {
shiftOut(DATA, CLK, MSBFIRST, 5) ; // 5=0b00000101(0x05) 8ビット出力する
digitalWrite(STB, LOW) ; // ラッチ信号を出す
digitalWrite(STB, HIGH) ;
while(1) ; // 処理中断
}
---------------------------------------------------------------------
Arduinoの標準関数でshiftOut()関数が有るのでそれを利用したスケッチです。
---------------------------------------------------------------------
#define CLK 13 // クロック信号出力ピン
#define STB 10 // ラッチ動作出力ピン
#define DATA 11 // データ信号出力ピン
#define CLR 9 // リセット出力ピン
void setup() {
pinMode(CLK, OUTPUT) ; // 制御するピンは全て出力に設定する
pinMode(STB, OUTPUT) ;
pinMode(DATA, OUTPUT) ;
pinMode(CLR, OUTPUT) ;
digitalWrite(STB, HIGH) ;
digitalWrite(CLR, HIGH) ;// リセット解除
delay(3000) ; // 3S後開始
}
void loop() {
shiftOut(DATA, CLK, MSBFIRST, 5) ; // 5=0b00000101(0x05) 8ビット出力する
digitalWrite(STB, LOW) ; // ラッチ信号を出す
digitalWrite(STB, HIGH) ;
while(1) ; // 処理中断
}
---------------------------------------------------------------------
追記(*4) 2016/01/20
MPLAB X用に記事変更(*3) 2015/10/30
追記(*2) 2012/03/30
追記(*1) 2012/02/28
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.