@@ -0,0 +1,3 @@ | |||
#SPI Library for Teensy# | |||
http://www.pjrc.com/teensy/teensyduino.html |
@@ -0,0 +1,68 @@ | |||
/* | |||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> | |||
* SPI Master library for arduino. | |||
* | |||
* This file is free software; you can redistribute it and/or modify | |||
* it under the terms of either the GNU General Public License version 2 | |||
* or the GNU Lesser General Public License version 2.1, both as | |||
* published by the Free Software Foundation. | |||
*/ | |||
#include "pins_arduino.h" | |||
#include "SPI.h" | |||
SPIClass SPI; | |||
void SPIClass::begin() { | |||
// Set SS to high so a connected chip will be "deselected" by default | |||
digitalWrite(SS, HIGH); | |||
// When the SS pin is set as OUTPUT, it can be used as | |||
// a general purpose output port (it doesn't influence | |||
// SPI operations). | |||
pinMode(SS, OUTPUT); | |||
// Warning: if the SS pin ever becomes a LOW INPUT then SPI | |||
// automatically switches to Slave, so the data direction of | |||
// the SS pin MUST be kept as OUTPUT. | |||
SPCR |= _BV(MSTR); | |||
SPCR |= _BV(SPE); | |||
// Set direction register for SCK and MOSI pin. | |||
// MISO pin automatically overrides to INPUT. | |||
// By doing this AFTER enabling SPI, we avoid accidentally | |||
// clocking in a single bit since the lines go directly | |||
// from "input" to SPI control. | |||
// http://code.google.com/p/arduino/issues/detail?id=888 | |||
#ifdef __AVR__ | |||
pinMode(SCK, OUTPUT); | |||
pinMode(MOSI, OUTPUT); | |||
#endif | |||
} | |||
void SPIClass::end() { | |||
SPCR &= ~_BV(SPE); | |||
} | |||
void SPIClass::setBitOrder(uint8_t bitOrder) | |||
{ | |||
if(bitOrder == LSBFIRST) { | |||
SPCR |= _BV(DORD); | |||
} else { | |||
SPCR &= ~(_BV(DORD)); | |||
} | |||
} | |||
void SPIClass::setDataMode(uint8_t mode) | |||
{ | |||
SPCR = (SPCR & ~SPI_MODE_MASK) | mode; | |||
} | |||
void SPIClass::setClockDivider(uint8_t rate) | |||
{ | |||
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); | |||
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); | |||
} | |||
@@ -0,0 +1,75 @@ | |||
/* | |||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> | |||
* SPI Master library for arduino. | |||
* | |||
* This file is free software; you can redistribute it and/or modify | |||
* it under the terms of either the GNU General Public License version 2 | |||
* or the GNU Lesser General Public License version 2.1, both as | |||
* published by the Free Software Foundation. | |||
*/ | |||
#ifndef _SPI_H_INCLUDED | |||
#define _SPI_H_INCLUDED | |||
#include <stdio.h> | |||
#include <Arduino.h> | |||
#include <avr/pgmspace.h> | |||
#define SPI_CLOCK_DIV4 0x00 | |||
#define SPI_CLOCK_DIV16 0x01 | |||
#define SPI_CLOCK_DIV64 0x02 | |||
#define SPI_CLOCK_DIV128 0x03 | |||
#define SPI_CLOCK_DIV2 0x04 | |||
#define SPI_CLOCK_DIV8 0x05 | |||
#define SPI_CLOCK_DIV32 0x06 | |||
//#define SPI_CLOCK_DIV64 0x07 | |||
#define SPI_MODE0 0x00 | |||
#define SPI_MODE1 0x04 | |||
#define SPI_MODE2 0x08 | |||
#define SPI_MODE3 0x0C | |||
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR | |||
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR | |||
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR | |||
class SPIClass { | |||
public: | |||
inline static byte transfer(byte _data); | |||
// SPI Configuration methods | |||
inline static void attachInterrupt(); | |||
inline static void detachInterrupt(); // Default | |||
static void begin(); // Default | |||
static void end(); | |||
static void setBitOrder(uint8_t); | |||
static void setDataMode(uint8_t); | |||
static void setClockDivider(uint8_t); | |||
#if defined(__arm__) && defined(CORE_TEENSY) | |||
inline void setMOSI(uint8_t pin) __attribute__((always_inline)) { SPCR.setMOSI(pin); } | |||
inline void setMISO(uint8_t pin) __attribute__((always_inline)) { SPCR.setMISO(pin); } | |||
inline void setSCK(uint8_t pin) __attribute__((always_inline)) { SPCR.setSCK(pin); } | |||
#endif | |||
}; | |||
extern SPIClass SPI; | |||
byte SPIClass::transfer(byte _data) { | |||
SPDR = _data; | |||
while (!(SPSR & _BV(SPIF))) | |||
; | |||
return SPDR; | |||
} | |||
void SPIClass::attachInterrupt() { | |||
SPCR |= _BV(SPIE); | |||
} | |||
void SPIClass::detachInterrupt() { | |||
SPCR &= ~_BV(SPIE); | |||
} | |||
#endif |
@@ -0,0 +1,143 @@ | |||
/* | |||
SCP1000 Barometric Pressure Sensor Display | |||
Shows the output of a Barometric Pressure Sensor on a | |||
Uses the SPI library. For details on the sensor, see: | |||
http://www.sparkfun.com/commerce/product_info.php?products_id=8161 | |||
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ | |||
This sketch adapted from Nathan Seidle's SCP1000 example for PIC: | |||
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip | |||
Circuit: | |||
SCP1000 sensor attached to pins 6, 7, 10 - 13: | |||
DRDY: pin 6 | |||
CSB: pin 7 | |||
MOSI: pin 11 | |||
MISO: pin 12 | |||
SCK: pin 13 | |||
created 31 July 2010 | |||
modified 14 August 2010 | |||
by Tom Igoe | |||
*/ | |||
// the sensor communicates using SPI, so include the library: | |||
#include <SPI.h> | |||
//Sensor's memory register addresses: | |||
const int PRESSURE = 0x1F; //3 most significant bits of pressure | |||
const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure | |||
const int TEMPERATURE = 0x21; //16 bit temperature reading | |||
const byte READ = 0b11111100; // SCP1000's read command | |||
const byte WRITE = 0b00000010; // SCP1000's write command | |||
// pins used for the connection with the sensor | |||
// the other you need are controlled by the SPI library): | |||
const int dataReadyPin = 6; | |||
const int chipSelectPin = 7; | |||
void setup() { | |||
Serial.begin(9600); | |||
// start the SPI library: | |||
SPI.begin(); | |||
// initalize the data ready and chip select pins: | |||
pinMode(dataReadyPin, INPUT); | |||
pinMode(chipSelectPin, OUTPUT); | |||
//Configure SCP1000 for low noise configuration: | |||
writeRegister(0x02, 0x2D); | |||
writeRegister(0x01, 0x03); | |||
writeRegister(0x03, 0x02); | |||
// give the sensor time to set up: | |||
delay(100); | |||
} | |||
void loop() { | |||
//Select High Resolution Mode | |||
writeRegister(0x03, 0x0A); | |||
// don't do anything until the data ready pin is high: | |||
if (digitalRead(dataReadyPin) == HIGH) { | |||
//Read the temperature data | |||
int tempData = readRegister(0x21, 2); | |||
// convert the temperature to celsius and display it: | |||
float realTemp = (float)tempData / 20.0; | |||
Serial.print("Temp[C]="); | |||
Serial.print(realTemp); | |||
//Read the pressure data highest 3 bits: | |||
byte pressure_data_high = readRegister(0x1F, 1); | |||
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 | |||
//Read the pressure data lower 16 bits: | |||
unsigned int pressure_data_low = readRegister(0x20, 2); | |||
//combine the two parts into one 19-bit number: | |||
long pressure = ((pressure_data_high << 16) | pressure_data_low)/4; | |||
// display the temperature: | |||
Serial.println("\tPressure [Pa]=" + String(pressure)); | |||
} | |||
} | |||
//Read from or write to register from the SCP1000: | |||
unsigned int readRegister(byte thisRegister, int bytesToRead ) { | |||
byte inByte = 0; // incoming byte from the SPI | |||
unsigned int result = 0; // result to return | |||
Serial.print(thisRegister, BIN); | |||
Serial.print("\t"); | |||
// SCP1000 expects the register name in the upper 6 bits | |||
// of the byte. So shift the bits left by two bits: | |||
thisRegister = thisRegister << 2; | |||
// now combine the address and the command into one byte | |||
byte dataToSend = thisRegister & READ; | |||
Serial.println(thisRegister, BIN); | |||
// take the chip select low to select the device: | |||
digitalWrite(chipSelectPin, LOW); | |||
// send the device the register you want to read: | |||
SPI.transfer(dataToSend); | |||
// send a value of 0 to read the first byte returned: | |||
result = SPI.transfer(0x00); | |||
// decrement the number of bytes left to read: | |||
bytesToRead--; | |||
// if you still have another byte to read: | |||
if (bytesToRead > 0) { | |||
// shift the first byte left, then get the second byte: | |||
result = result << 8; | |||
inByte = SPI.transfer(0x00); | |||
// combine the byte you just got with the previous one: | |||
result = result | inByte; | |||
// decrement the number of bytes left to read: | |||
bytesToRead--; | |||
} | |||
// take the chip select high to de-select: | |||
digitalWrite(chipSelectPin, HIGH); | |||
// return the result: | |||
return(result); | |||
} | |||
//Sends a write command to SCP1000 | |||
void writeRegister(byte thisRegister, byte thisValue) { | |||
// SCP1000 expects the register address in the upper 6 bits | |||
// of the byte. So shift the bits left by two bits: | |||
thisRegister = thisRegister << 2; | |||
// now combine the register address and the command into one byte: | |||
byte dataToSend = thisRegister | WRITE; | |||
// take the chip select low to select the device: | |||
digitalWrite(chipSelectPin, LOW); | |||
SPI.transfer(dataToSend); //Send register location | |||
SPI.transfer(thisValue); //Send value to record into register | |||
// take the chip select high to de-select: | |||
digitalWrite(chipSelectPin, HIGH); | |||
} | |||
@@ -0,0 +1,143 @@ | |||
/* | |||
SCP1000 Barometric Pressure Sensor Display | |||
Shows the output of a Barometric Pressure Sensor on a | |||
Uses the SPI library. For details on the sensor, see: | |||
http://www.sparkfun.com/commerce/product_info.php?products_id=8161 | |||
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ | |||
This sketch adapted from Nathan Seidle's SCP1000 example for PIC: | |||
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip | |||
Circuit: | |||
SCP1000 sensor attached to pins 6, 7, 10 - 13: | |||
DRDY: pin 6 | |||
CSB: pin 7 | |||
MOSI: pin 11 | |||
MISO: pin 12 | |||
SCK: pin 13 | |||
created 31 July 2010 | |||
modified 14 August 2010 | |||
by Tom Igoe | |||
*/ | |||
// the sensor communicates using SPI, so include the library: | |||
#include <SPI.h> | |||
//Sensor's memory register addresses: | |||
const int PRESSURE = 0x1F; //3 most significant bits of pressure | |||
const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure | |||
const int TEMPERATURE = 0x21; //16 bit temperature reading | |||
cont byte READ = 0b00000000; // SCP1000's read command | |||
const byte WRITE = 0b00000010; // SCP1000's write command | |||
// pins used for the connection with the sensor | |||
// the other you need are controlled by the SPI library): | |||
const int dataReadyPin = 6; | |||
const int chipSelectPin = 7; | |||
void setup() { | |||
Serial.begin(9600); | |||
// start the SPI library: | |||
SPI.begin(); | |||
// initalize the data ready and chip select pins: | |||
pinMode(dataReadyPin, INPUT); | |||
pinMode(chipSelectPin, OUTPUT); | |||
//Configure SCP1000 for low noise configuration: | |||
writeRegister(0x02, 0x2D); | |||
writeRegister(0x01, 0x03); | |||
writeRegister(0x03, 0x02); | |||
// give the sensor time to set up: | |||
delay(100); | |||
} | |||
void loop() { | |||
//Select High Resolution Mode | |||
writeRegister(0x03, 0x0A); | |||
// don't do anything until the data ready pin is high: | |||
if (digitalRead(dataReadyPin) == HIGH) { | |||
//Read the temperature data | |||
int tempData = readRegister(0x21, 2); | |||
// convert the temperature to celsius and display it: | |||
float realTemp = (float)tempData / 20.0; | |||
Serial.print("Temp[C]="); | |||
Serial.print(realTemp); | |||
//Read the pressure data highest 3 bits: | |||
byte pressure_data_high = readRegister(0x1F, 1); | |||
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 | |||
//Read the pressure data lower 16 bits: | |||
unsigned int pressure_data_low = readRegister(0x20, 2); | |||
//combine the two parts into one 19-bit number: | |||
long pressure = ((pressure_data_high << 16) | pressure_data_low)/4; | |||
// display the temperature: | |||
Serial.println("\tPressure [Pa]=" + String(pressure)); | |||
} | |||
} | |||
//Read from or write to register from the SCP1000: | |||
unsigned int readRegister(byte thisRegister, int bytesToRead ) { | |||
byte inByte = 0; // incoming byte from the SPI | |||
unsigned int result = 0; // result to return | |||
// SCP1000 expects the register name in the upper 6 bits | |||
// of the byte. So shift the bits left by two bits: | |||
thisRegister = thisRegister << 2; | |||
// now combine the address and the command into one byte | |||
dataToSend = thisRegister & READ; | |||
// take the chip select low to select the device: | |||
digitalWrite(chipSelectPin, LOW); | |||
// send the device the register you want to read: | |||
SPI.transfer(dataToSend); | |||
// send a value of 0 to read the first byte returned: | |||
result = SPI.transfer(0x00); | |||
// decrement the number of bytes left to read: | |||
bytesToRead--; | |||
// if you still have another byte to read: | |||
if (bytesToRead > 0) { | |||
// shift the first byte left, then get the second byte: | |||
result = result << 8; | |||
inByte = SPI.transfer(0x00); | |||
// combine the byte you just got with the previous one: | |||
result = result | inByte; | |||
// decrement the number of bytes left to read: | |||
bytesToRead--; | |||
} | |||
// take the chip select high to de-select: | |||
digitalWrite(chipSelectPin, HIGH); | |||
// return the result: | |||
return(result); | |||
} | |||
//Sends a write command to SCP1000 | |||
void writeRegister(byte thisRegister, byte thisValue) { | |||
// SCP1000 expects the register address in the upper 6 bits | |||
// of the byte. So shift the bits left by two bits: | |||
thisRegister = thisRegister << 2; | |||
// now combine the register address and the command into one byte: | |||
dataToSend = thisRegister | WRITE; | |||
// take the chip select low to select the device: | |||
digitalWrite(chipSelectPin, LOW); | |||
SPI.transfer(dataToSend); //Send register location | |||
SPI.transfer(thisValue); //Send value to record into register | |||
// take the chip select high to de-select: | |||
digitalWrite(chipSelectPin, HIGH); | |||
} | |||
@@ -0,0 +1,71 @@ | |||
/* | |||
Digital Pot Control | |||
This example controls an Analog Devices AD5206 digital potentiometer. | |||
The AD5206 has 6 potentiometer channels. Each channel's pins are labeled | |||
A - connect this to voltage | |||
W - this is the pot's wiper, which changes when you set it | |||
B - connect this to ground. | |||
The AD5206 is SPI-compatible,and to command it, you send two bytes, | |||
one with the channel number (0 - 5) and one with the resistance value for the | |||
channel (0 - 255). | |||
The circuit: | |||
* All A pins of AD5206 connected to +5V | |||
* All B pins of AD5206 connected to ground | |||
* An LED and a 220-ohm resisor in series connected from each W pin to ground | |||
* CS - to digital pin 10 (SS pin) | |||
* SDI - to digital pin 11 (MOSI pin) | |||
* CLK - to digital pin 13 (SCK pin) | |||
created 10 Aug 2010 | |||
by Tom Igoe | |||
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 | |||
*/ | |||
// inslude the SPI library: | |||
#include <SPI.h> | |||
// set pin 10 as the slave select for the digital pot: | |||
const int slaveSelectPin = 10; | |||
void setup() { | |||
// set the slaveSelectPin as an output: | |||
pinMode (slaveSelectPin, OUTPUT); | |||
// initialize SPI: | |||
SPI.begin(); | |||
} | |||
void loop() { | |||
// go through the six channels of the digital pot: | |||
for (int channel = 0; channel < 6; channel++) { | |||
// change the resistance on this channel from min to max: | |||
for (int level = 0; level < 255; level++) { | |||
digitalPotWrite(channel, level); | |||
delay(10); | |||
} | |||
// wait a second at the top: | |||
delay(100); | |||
// change the resistance on this channel from max to min: | |||
for (int level = 0; level < 255; level++) { | |||
digitalPotWrite(channel, 255 - level); | |||
delay(10); | |||
} | |||
} | |||
} | |||
void digitalPotWrite(int address, int value) { | |||
// take the SS pin low to select the chip: | |||
digitalWrite(slaveSelectPin,LOW); | |||
// send in the address and value via SPI: | |||
SPI.transfer(address); | |||
SPI.transfer(value); | |||
// take the SS pin high to de-select the chip: | |||
digitalWrite(slaveSelectPin,HIGH); | |||
} |
@@ -0,0 +1,39 @@ | |||
####################################### | |||
# Syntax Coloring Map SPI | |||
####################################### | |||
####################################### | |||
# Datatypes (KEYWORD1) | |||
####################################### | |||
SPI KEYWORD1 | |||
####################################### | |||
# Methods and Functions (KEYWORD2) | |||
####################################### | |||
begin KEYWORD2 | |||
end KEYWORD2 | |||
transfer KEYWORD2 | |||
setBitOrder KEYWORD2 | |||
setDataMode KEYWORD2 | |||
setClockDivider KEYWORD2 | |||
setMOSI KEYWORD2 | |||
setMISO KEYWORD2 | |||
setSCK KEYWORD2 | |||
####################################### | |||
# Constants (LITERAL1) | |||
####################################### | |||
SPI_CLOCK_DIV4 LITERAL1 | |||
SPI_CLOCK_DIV16 LITERAL1 | |||
SPI_CLOCK_DIV64 LITERAL1 | |||
SPI_CLOCK_DIV128 LITERAL1 | |||
SPI_CLOCK_DIV2 LITERAL1 | |||
SPI_CLOCK_DIV8 LITERAL1 | |||
SPI_CLOCK_DIV32 LITERAL1 | |||
SPI_CLOCK_DIV64 LITERAL1 | |||
SPI_MODE0 LITERAL1 | |||
SPI_MODE1 LITERAL1 | |||
SPI_MODE2 LITERAL1 | |||
SPI_MODE3 LITERAL1 |