CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Can't read data with SPI using PIC16f18346
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 7688
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 5:04 am     Reply with quote

just an observation....

I was curious about memset() so I copied PCMp's program,edited for the 46K22 and compiled fine. I then added a simple for,next loop to stuff '0' into the elements of the buffer.
That chunk of code is 14 words long.

The memset() code is 20+- words long with a lot of branches and tests.

I understand that memset() is a 'generic' or 'one tool does all' kind of function but to simply 'zero an array', my hard code looks more efficient and faster.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 7:12 am     Reply with quote

memset is a lot quicker. Did the same test, memset takes
671 machine cycles, zeroing the array with for/next, takes 1839.....

Bit puzzled by your reference to memset having a lot of branches and tests.
Compiled for the 46K22:
Code:

35:                memset(misoBuf, 0x00, sizeof(misoBuf));
  01F2    6AEA     CLRF 0xfea, ACCESS
  01F4    0E05     MOVLW 0x5
  01F6    6EE9     MOVWF 0xfe9, ACCESS
  01F8    6A00     CLRF 0, ACCESS
  01FA    6A02     CLRF 0x2, ACCESS
  01FC    0E83     MOVLW 0x83
  01FE    6E01     MOVWF 0x1, ACCESS
  0200    D74F     BRA 0xa0
36: 

No tests or branches.
temtronic



Joined: 01 Jul 2010
Posts: 7688
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 10:29 am     Reply with quote

Code:


35:                memset(misoBuf, 0x00, sizeof(misoBuf));
  0344    6AEA     CLRF 0xfea, ACCESS
  0346    0E05     MOVLW 0x5
  0348    6EE9     MOVWF 0xfe9, ACCESS
  034A    6B89     CLRF 0x89, BANKED
  034C    6B8B     CLRF 0x8b, BANKED
  034E    0E83     MOVLW 0x83
  0350    6F8A     MOVWF 0x8a, BANKED
  0352    D6A2     BRA 0x98
36:               
37:                printf("\r\n");
  0354    0E0D     MOVLW 0xd


  0098    678A     TSTFSZ 0x8a, BANKED
  009A    D003     BRA 0xa2
  009C    678B     TSTFSZ 0x8b, BANKED
  009E    D002     BRA 0xa4
  00A0    D007     BRA 0xb0
  00A2    2B8B     INCF 0x8b, F, BANKED
  00A4    C089     MOVFF 0x89, 0xfee
  00A8    2F8A     DECFSZ 0x8a, F, BANKED
  00AA    D7FC     BRA 0xa4
  00AC    2F8B     DECFSZ 0x8b, F, BANKED
  00AE    D7FA     BRA 0xa4
  00B0    EFAA     GOTO 0x354




here's what I got...
I'm not too sure what's happening.. I'd have thought it's simply 'drop down' , not do the branch to 0x0098....then a hard goto 0x354( the next line of C code...

one of life's curiousities ?

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 1:02 pm     Reply with quote

No,
If you look at what the jump goes to, it is a basic 'block fill' assembler
routine, requiring a start address, count, and value to put into the cells.
It's written as efficiently as is possible for the processor. The code
simply sets up the registers and jumps to this.
Now the for loop approach takes three times as many actual operations
(addressing a memory cell, writing a value to this, incrementing the cell,
decrementing the counter, testing and looping). The routine from memset,
avoids having to readdress the cell on each loop. Result, much quicker.
So it is larger (setup and function), but operationally much quicker.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 11:44 pm     Reply with quote

PCM programmer wrote:
Working with Ttelmah, I was able to get MPLAB X vs. 5.30 to display printf
statements in the UART1 tab of the MPLAB X Simulator.

I installed CCS vs. 5.076 (same as your version). I compiled the
test program shown below and it worked fine. It displayed this output.
This shows that memset() did zero the array correctly.
Code:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,


0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,

Test program:
Code:

#include <16F18346.h>
#fuses NOWDT
#use delay (internal=4M)
#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7
#use rs232(baud=9600, UART1, ERRORS)


BYTE misoBuf[131] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,
109,110,111,112,113,114,115,116,117,118,119,120,
121,122,123,124,125,126,127,128,129,130
};

//======================================
void main()
{         
int8 i;

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       printf("\r\n");

    printf("%u,", misoBuf[i]);
   }


memset(misoBuf, 0x00, sizeof(misoBuf));

printf("\r\n");
printf("\r\n");

for(i=0; i<sizeof(misoBuf); i++)
   {
    if(i%16 == 0)
       printf("\r\n");


    printf("%u,", misoBuf[i]);
   }

while(TRUE);
}




Hi,
I copied the code you wrote and I run it. I didn't change anything. But I get wrong result.

Code:
BYTE misoBuf[131] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,
109,110,111,112,113,114,115,116,117,118,119,120,
121,122,123,124,125,126,127,128,129,130
};


When I wrote like above, I get result as below.

Code:
"\x 0\x 1\x 2\x 3\x 4\x 5\x 6\x 7\x 8\x 9\x a\x b\x c\x d\x e\x f\x 10\x 11\x 12\x 13\x 14\x 15\x 16\x 17\x 18\x 19\x 1a\x 1b\x 1c\x 1d\x 1e\x 1f\x 20\x 21\x 22\x 23\x 24\x 25\x 26\x 27\x 28\x 29\x 2a\x 2b\x 2c\x 2d\x 2e\x 2f\x 30\x 31\x 32\x 33\x 34\x 35\x 36\x 37\x 38\x 39\x 3a\x 3b\x 3c\x 3d\x 3e\x 3f\x 40\x 41\x 42\x 43\x 44\x 45\x 46\x 47\x 48\x 49\x 4a\x 4b\x 4c\x 4d\x 4e\x 0\x 88\x 88\x 88\x 88\x 88\x 88\x 0\x 33\x 20\x 0\x 84\x 21\x 8\x 42\x 0\x 0\x 0\x 75\x 18\x 83\x 20\x d4\x 0\x 1\x ff\x 0\x 1\x 3f\x f0\x ff\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 16\x 0\x 0\x 0\x 1\x 11\x 0\x 0\x 0\x 4f\x 50\x 51\x 52"


I don't have any rs232 module, so I debugged the code. I looked register and I saw it. Why didnt it load true data in register? And when I looked register after memset, I saw again it didnt work correctly.

Code:
"\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 88\x 88\x 88\x 88\x 88\x 88\x 0\x 0\x 20\x 0\x 84\x 21\x 8\x 42\x 0\x 0\x 0\x 75\x 1c\x 84\x 20\x d4\x 0\x 0\x 0\x 0\x 1\x 3f\x f0\x ff\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 0\x 16\x 0\x 0\x 0\x 1\x 11\x 0\x 0\x 0\x 0\x 0\x 0\x 0"
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 1:31 am     Reply with quote

Type this into https://www.ebay.com/
Quote:
usb to rs232 TTL UART

Find one that is near your country or city so it arrives quickly. Buy it.

Here is an example:
https://www.ebay.com/itm/USB-To-RS232-TTL-UART-PL2303HX-Converter-USB-to-COM-Arduino-Cable-Adapter-Module/222528693981

Scroll down and you'll see a schematic of how to connect it to a
microcontroller. They use Arduino as an example but it will work
with a PIC too.
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 1:36 am     Reply with quote

Your debugger may not actually be accessing the memory correctly.
So what you are seeing may be a debugger issue, not an actual memory
issue.

Historically, any variable that is 'split' across multiple pages in the memory
can give this behaviour. Look at the .sym file for your code.
Look for the definition for misoBuf. I suspect you are going to see that it
actually uses addresses across two pages of memory (it has to, since it
is more than 128 bytes in length).
The debugger in MPLAB, does not correctly handle multi page variables.
So what is happening is that the variable perhaps has 70 bytes in one page
and 61 bytes in a second, and when you display it's 'contents', instead of
splitting the access to these two sets of addresses, the debugger instead
pulls successive values from the first address.

You need to use the address from the .sym file, and the number of bytes
in each location, and look at these 'manually', to see what the variable
actually contains.

So the variable is probably working perfectly, but the 'view' you are
getting from the debugger is wrong. That MPLAB does not handle variables
split like this, correctly has been reported here before.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 5:33 am     Reply with quote

PCM programmer wrote:
Type this into https://www.ebay.com/
Quote:
usb to rs232 TTL UART

Find one that is near your country or city so it arrives quickly. Buy it.

Here is an example:
https://www.ebay.com/itm/USB-To-RS232-TTL-UART-PL2303HX-Converter-USB-to-COM-Arduino-Cable-Adapter-Module/222528693981

Scroll down and you'll see a schematic of how to connect it to a
microcontroller. They use Arduino as an example but it will work
with a PIC too.


I found a RS232 module which is working with 5V. My processor can work with 5V, but since the module I use as a slave communicates with 3.3V, I also apply 3.3V as the supply voltage to my processor. MPLABX gives a voltage error when I connect RS232 with 5V support.
temtronic



Joined: 01 Jul 2010
Posts: 7688
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 5:39 am     Reply with quote

You actually need a USB <> TTL module to directly connect to a PIC, unless you've already got a 'MAX232' device soldered to the PIC's serial lines.
The $2 modules I buy have both 5v and 3v pins.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 6:04 am     Reply with quote

temtronic wrote:
You actually need a USB <> TTL module to directly connect to a PIC, unless you've already got a 'MAX232' device soldered to the PIC's serial lines.
The $2 modules I buy have both 5v and 3v pins.


I'm using this as a master microcontroller with PIC16F18346: https://www.microchip.com/promo/curiosity-development-boards

I was hoping it wouldn't need anything additional parts.
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 6:15 am     Reply with quote

Really, having serial I/O, is an essential 'tool' for development.

Search on ebay, for "USB to TTL serial 5v 3.3v". This should display the
modules you need. They are so cheap, that it costs far more not to have
one!...
temtronic



Joined: 01 Jul 2010
Posts: 7688
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 8:16 am     Reply with quote

If you're connecting the PIC16F18346 to the 'curiousity board', you should be able to do direct connections between then, if less than a foot apart, maybe more of less depending on baudrate. Just be SURE to connect grounds, so 3 wires are needed.
L.T.



Joined: 24 Jul 2020
Posts: 50

View user's profile Send private message

PostPosted: Thu Aug 20, 2020 12:52 am     Reply with quote

Hey there,

Thank you so much for your help. I found my fault of using memset function. I have defined a variable in the function when I had to define it globally.

I have a new problem. I watched transmitted and received on oscilloscope using both MSP and PIC.
As I said earlier, I have a demo code for running the PGA460 for MSP. And it works perfectly. I thoroughly analyzed the signals and found that I had a frequency problem with SPI communication. Processor frequency in MSP is set to 16MHz and SPI baud rate is set to 16MHz / 16 = 1MHz. For the PIC, I chose the frequency as 16MHz and the baud as 1MHz. However, as I saw on the oscilloscope, the frequencies read very differently from those of the MSP. While 2-3 data used for communication are not sent consecutively by the master (MSP), the PIC sends them all in succession. I guess this is because the frequency is wrong.

You can see the screenshot of my oscilloscope.Blue is transmitted, yellow is received signal.

In MSP, the first signal you see below is sent and the answer is received.
[img]https://imgur.com/oub1g7T[/img]

Then, the data requesting distance data is sent by MSP and the answer comes.
[img]https://imgur.com/oub1g7T[/img]

Below, you can see the data of the PIC processor's SPI communication. As you can see, the MSP sent all the data it sent piece by piece. However, PIC sent them all in a row. There is a lot of difference between the frequencies of MSP and PIC.
[img]https://imgur.com/AA15Bly[/img]

You can see my settings for SPI communication below.
Code:
#include "16F18346.h"
#use delay(internal=16000000)
#use spi(DI=PIN_B4, DO=PIN_C7, CLK=PIN_B6, LSB_FIRST, baud=1000000, MODE=2, stream=PGA)


There is no other difference between the codes.
Ttelmah



Joined: 11 Mar 2010
Posts: 16429

View user's profile Send private message

PostPosted: Thu Aug 20, 2020 1:52 am     Reply with quote

The reason it is sending so slow, is you are not using the hardware SPI.
Software SPI takes a lot of instructions per bit, and at only 4MIPS, can
only do a much slower rate than you are asking for:
Code:

#include "16F18346.h"
#use delay(internal=16000000)
#PIN_SELECT SCK1=PIN_B6
#PIN_SELECT SDO1=PIN_C7
#PIN_SELECT SDI1=PIN_B4
#use spi(SSP1, baud=1000000, MODE=2, stream=PGA)


This then forces the hardware SPI to be used.

However this then means the bit order will be wrong. The hardware SSP,
does not support LSB_FIRST. Look in the code library, there is a routine
to reverse the bit order of a byte. You will have to use this for every byte
you send, and then again for every byte you receive.
Understand that the standard for SPI, is for the MSb yo be sent first.
The PIC hardware does this.
You could send LSb first, using the UART. In synchronous mode this
is the order bits are sent. But you want to use the SPI.... Sad

The sending all in succession is down to your code. The MSP must be pausing, or waiting for something to happen before sending the next byte.
PCM programmer



Joined: 06 Sep 2003
Posts: 21232

View user's profile Send private message

PostPosted: Thu Aug 20, 2020 2:07 am     Reply with quote

He has a bit reversal routine. It's this clever code in his first post.
Code:
// MSB --> LSB
_data = (((_data & 0b11110000)>>4) | ((_data & 0b00001111)<<4));
_data = (((_data & 0b11001100)>>2) | ((_data & 0b00110011)<<2));
_data = (((_data & 0b10101010)>>1) | ((_data & 0b01010101)<<1));
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 4 of 7

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group