|
|
View previous topic :: View next topic |
Author |
Message |
temtronic
Joined: 01 Jul 2010 Posts: 9099 Location: Greensville,Ontario
|
|
Posted: Mon Aug 17, 2020 5:04 am |
|
|
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: 19216
|
|
Posted: Mon Aug 17, 2020 7:12 am |
|
|
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: 9099 Location: Greensville,Ontario
|
|
Posted: Mon Aug 17, 2020 10:29 am |
|
|
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: 19216
|
|
Posted: Mon Aug 17, 2020 1:02 pm |
|
|
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: 62
|
|
Posted: Mon Aug 17, 2020 11:44 pm |
|
|
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: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19216
|
|
Posted: Tue Aug 18, 2020 1:36 am |
|
|
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: 62
|
|
Posted: Tue Aug 18, 2020 5:33 am |
|
|
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: 9099 Location: Greensville,Ontario
|
|
Posted: Tue Aug 18, 2020 5:39 am |
|
|
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: 62
|
|
Posted: Tue Aug 18, 2020 6:04 am |
|
|
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: 19216
|
|
Posted: Tue Aug 18, 2020 6:15 am |
|
|
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: 9099 Location: Greensville,Ontario
|
|
Posted: Tue Aug 18, 2020 8:16 am |
|
|
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: 62
|
|
Posted: Thu Aug 20, 2020 12:52 am |
|
|
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: 19216
|
|
Posted: Thu Aug 20, 2020 1:52 am |
|
|
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....
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: 21708
|
|
Posted: Thu Aug 20, 2020 2:07 am |
|
|
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)); |
|
|
|
|
|
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
|