1

I am setting up a frequency counter on the PIC18F4585, which sends the frequency out via 8bit SPI.

I'm setting up a frequency counter in my PICF4584 that will calculate the frequency of a square wave going into timer/counter1, samples for 8ms timed by timer/counter0, and then sent to another MCU via SPI. I don't have the SPI input pin SDI connected because I won't send any data back, but for some reason I am not outputting data. I learned MCU's through the AVR line so the way PIC does things is a little different to me and I think I might have missed something basic.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <xc.h>

volatile int count;

void timer0_init() //for sampling period 64 prescaler@ 8MHz -> 1000 ticks per 8ms
{
    T0CON |= (1<<7); //Timer1 on
    T0CON |= (1<<2) | (1<<0); //64 prescaler

    TMR0 = 64535; //interrupt initiated on overflow, 1000 ticks until overflow
}

void timer1_init() //for frequency counting
{
    T1CON |= (1<<7); //16 bit operation
    T1CON |= (1<<1); //Timer1 clock source external RC0/T1OSO/T13CKI on rising edge
    T1CON |= (1<<0); //Enables Timer1
    T1CON |= (1<<6); //Device clock source is derived from Timer1 oscillator
}

void SPI_init()
{
    //TRIS 0 is default output, TRIS 1 is input
    TRISC &= ~(1<<3);
    TRISC &= ~(1<<5);
    TRISA |= (1<<5);
    PORTA |= (1<<5);

    SSPSTAT |= (1<<7); //Input data sampled at end of output time
    SSPSTAT |= (1<<6); //Clock: transmit occurs on active to idle

    SSPCON1 |= (1<<5); //SCK, SDO, SDI, and SS are serial port pins
    SSPCON1 |= (1<<0); //Fosc/16

}

void interrupt_init()
{
    INTCON |= (1<<7); //global interrupt enable
    INTCON |= (1<<7); //Enables high priority interrupts
    INTCON |= (1<<5); //enables Timer0 overflow
}

void __interrupt () ISR(void)
{
   count =  TMR1;
   count = (count)/.008;

   /*SPI TRANSMIT*/
   PORTA &= ~(1<<5); //Slave Select goes low
   SSPBUF = count;
   PORTA |= (1<<5);

   /*RESET TIMERS AND INTERRUPTS*/
   TMR1 = 0;
   TMR0 = 64343; 
   INTCON &= ~(1<<2);
}



int main() {
    interrupt_init();
    timer0_init();
    timer1_init();
    SPI_init();
    while(1)
    {
    }
}

Jaywalk
  • 145
  • 6
  • Might be wise to do the timer and spi init functions _before_ enabling their interrupts. – AShelly Apr 23 '19 at 17:54
  • Your code has too many problems. Please try to learn more about the PIC18F family and PIC interrupt handlers in particular. – Dan1138 Apr 23 '19 at 21:48
  • Is there anything particularly glaring that you notice @dan1138? I've implemented this on an AVR but I'm not sure what to do for the PIC. – Jaywalk Apr 23 '19 at 22:13
  • Here you are mixing float and int: count = (count)/.008; – Mike Apr 24 '19 at 05:47
  • @Jaywalk, Unless you have a compelling need for frustration just keep using the AVR. The PIC18F family of 8-bit controllers is about the best Microchip could do before they purchased Atmel. Your most glaring display of naivete is your method for handling PIC18F interrupts. In this regard the PIC18F is nothing like the AVR and you will discover that the PIC18F is really old school. – Dan1138 Apr 26 '19 at 02:04
  • My need is for a CAN transmitter on the device, which isn't available on AVR devices as far as I have seen. I'm going to read through the data sheet on this PIC, but I do plan on using AVRs as much as I can. You might note that I'm not using the CAN here but that is only because I need to demonstrate this and I dont have a CAN reciever to do so. – Jaywalk Apr 26 '19 at 02:28

0 Answers0