Ι have a ds3234 RTC with which i successfully interacted via SPI using an Arduino Duemilanove.
I did this using the code below:
I then tried to program a PIC16F88 to take the place of Arduino. As i didn't want to program it in assembly, i started looking for a way to program it in C. After rejecting HI-TECH C compiler due to non-helpfull documentation, i ended up using CCS C compiler.
I tried to replicate the commands used in the Arduino program, as it had proven to be working all right. After several hours, i managed to blink a led using an external interrupt with my PIC, but no luck in using the SPI.
The code i have created so far is this:
The connections on the breadboard are:
ds3234 PIC16F88
SQW -> RB0
MISO -> RB1
MOSI -> RB2
CLK -> RB4
SS -> RB5
and i have a led connected in pin RA2.
The led blinks if i manually cause an external interrupt on RB0, so i now that my basic connections (oscillator, ground, vcc and led) and programming are correct.
However, an interrupt from the ds3234 never occurs, so there's something i'm not doing right with the SPI.
Any help will be appreciated.
I did this using the code below:
Rich (BB code):
#include <SPI.h>
#include <avr/sleep.h>
const int alarmPin = 2;
const int RTC_CS=10;
int count =0;
void setup()
{
RTC_init();
}
void loop(){
if (count >= 10) {
delay(100);
count = 0;
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
attachInterrupt(0,rtcAlarm, LOW); // use interrupt 0 (pin 2) and run function
// rtcAlarm when pin 2 gets LOW
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.
}
}
void RTC_init(){
pinMode(RTC_CS,OUTPUT); // chip select
// start the SPI library:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE1); // both mode 1 & 3 should work
//set control register
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x8E);
SPI.transfer(0x05); //00000110 EOSC/BBSQW/TEMPCONV/RS1/RS2/INTCN/A2IE/A1IE
digitalWrite(RTC_CS, HIGH);
delay(10);
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x8F);
SPI.transfer(0x0);
digitalWrite(RTC_CS, HIGH);
delay(10);
SetAlarm();
//Turn on internal pullup for INT/SQW pin
pinMode(alarmPin, INPUT);
digitalWrite(alarmPin, HIGH);
attachInterrupt(0, rtcAlarm, LOW);
}
void rtcAlarm(){
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x8F);
SPI.transfer(0x0);
digitalWrite(RTC_CS, HIGH);
}
void SetAlarm(){
delay(10);
digitalWrite(RTC_CS, LOW);
//Set Alarm 1 to once per sec
SPI.transfer(0x87);
SPI.transfer(0x80);
digitalWrite(RTC_CS, HIGH);
delay(10);
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x88);
SPI.transfer(0x80);
digitalWrite(RTC_CS, HIGH);
delay(10);
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x89);
SPI.transfer(0x80);
delay(10);
digitalWrite(RTC_CS, HIGH);
delay(10);
digitalWrite(RTC_CS, LOW);
SPI.transfer(0x8A);
SPI.transfer(0x80);
delay(10);
digitalWrite(RTC_CS, HIGH);
}
I tried to replicate the commands used in the Arduino program, as it had proven to be working all right. After several hours, i managed to blink a led using an external interrupt with my PIC, but no luck in using the SPI.
The code i have created so far is this:
Rich (BB code):
#include <16F88.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES FCMEN //Fail-safe clock monitor enabled
#use delay(clock=16000000)
#INT_EXT
void blink(){
output_high(PIN_A2);
delay_ms(1000);
output_low(PIN_A2);
delay_ms(1000);
clear_interrupt(INT_EXT);
output_low(PIN_B5);
spi_write(0x8F);
spi_write(0x0);
output_high(PIN_B5);
}
void setalarm()
{
output_low(PIN_B5);
spi_write(0x87);
spi_write(0x80);
output_high(PIN_B5);
delay_ms(10);
output_low(PIN_B5);
spi_write(0x88);
spi_write(0x80);
output_high(PIN_B5);
delay_ms(10);
output_low(PIN_B5);
spi_write(0x89);
spi_write(0x80);
output_high(PIN_B5);
delay_ms(10);
output_low(PIN_B5);
spi_write(0x8A);
spi_write(0x80);
output_high(PIN_B5);
}
void rtcinit()
{
output_high(PIN_B5);
spi_write(0x8E);
spi_write(0x05);
output_low(PIN_B5);
delay_ms(10);
output_high(PIN_B5);
spi_write(0x8F);
spi_write(0x00);
output_low(PIN_B5);
delay_ms(10);
setalarm();
}
void main()
{
output_low(PIN_B5);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
delay_ms(3000);
set_tris_a(0x00);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
rtcinit();
while(1){
}
}
ds3234 PIC16F88
SQW -> RB0
MISO -> RB1
MOSI -> RB2
CLK -> RB4
SS -> RB5
and i have a led connected in pin RA2.
The led blinks if i manually cause an external interrupt on RB0, so i now that my basic connections (oscillator, ground, vcc and led) and programming are correct.
However, an interrupt from the ds3234 never occurs, so there's something i'm not doing right with the SPI.
Any help will be appreciated.