View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 11, 2017 9:40 pm |
|
|
I don't know if you saw my post. I was going to suggest the manual
approach, but then I posted the "16-bit way" to do it. |
|
|
AidanHockey5
Joined: 11 Jun 2017 Posts: 10
|
|
Posted: Sun Jun 11, 2017 9:53 pm |
|
|
Awww. Try as I might, I don't think the 12F683 is going to cut it. A little disappointing, but ultimately, if anybody else in the future runs into this problem, look for a chip with hardware SPI support. Compared to the 12F683, the hardware SPI on the 16F690 worked immediately.
PCM, I gave your new function a go and sadly, the 6903 is still giving wonky values. If you're willing to share your ideas for a manual approach, I think I'd be willing to give it one last shot.
Thank you again for your help! It's been a long day of trial and error. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 11, 2017 10:05 pm |
|
|
The manual approach is what you did. Controlling \CS manually, while
running the software SPI in 8-bit mode.
A question. For the 12F683 test, did you incorporate all the changes given
so far, including putting the setup_timer_0(T0_INTERNAL) line at the
start of main() ?
I think this code should work:
Code: |
#include <12F683.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#use delay(internal=8MHz)
#USE SPI (MASTER, CLK=PIN_A4, DO=PIN_A5, ENABLE=PIN_A2, MSB_FIRST, BITS=16, MODE=0, BAUD=100000 )
#define byte unsigned char
void SetFrqManual(byte oct, int16 dac)
{
byte CNF = 0b00000000;
int16 BitMap = (oct << 12) | (dac << 2) | CNF;
spi_xfer(Bitmap);
}
void main()
{
setup_timer_0(T0_INTERNAL);
delay_ms(1000); //Debug delay for instruments to start up.
SetFrqManual(11, 830); //3.58MHz
while(TRUE); // Prevent PIC from going to sleep
} |
|
|
|
AidanHockey5
Joined: 11 Jun 2017 Posts: 10
|
|
Posted: Sun Jun 11, 2017 10:12 pm |
|
|
PCM programmer wrote: |
A question. For the 12F683 test, did you incorporate all the changes given
so far, including putting the setup_timer_0(T0_INTERNAL) line at the
start of main() ?
|
Yes I have. Alright, so I gave your code snippit a try and sadly... nope, the output values are still incorrect. This time the output frequency measures 1.7KHz.
I really do wonder what hardware SPI is doing differently. At least I've confirmed that my wiring is correct. Perhaps there is an issue with CCS' software SPI? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 11, 2017 10:39 pm |
|
|
I don't know. I can check it later in the week by testing the 16F690
version and the 12F683 version in hardware, and looking at the SPI signals
with my oscilloscope. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 21, 2017 5:52 am |
|
|
I worked on this again and immediately saw the problem.
The problem is, we have a byte parameter that is being shifted left
by 12. But that will just shift off the bits that we care about and give
us a result of 0. So the upper nybble is always 0, resulting in the wrong
frequency.
Quote: | void SetFrqManual(byte oct, int16 dac)
{
byte CNF = 0b00000000;
int16 BitMap = (oct << 12) | (dac << 2) | CNF;
spi_xfer(Bitmap);
} |
To fix the problem, we cast 'oct' to an int16. Then the left-shift works.
Quote: | Bitmap = ((int16)oct << 12) | (dac << 2) | CNF; |
I don't know why I didn't spot this earlier. I think it's because I never
use 'byte'. I always use 'int8'. Using 'int8' immediately reminds me of
the size. |
|
|
|