|
|
View previous topic :: View next topic |
Author |
Message |
dneale
Joined: 25 Nov 2009 Posts: 9 Location: Albuquerque NM
|
24F Direct Working Register Access |
Posted: Thu Jun 24, 2010 4:00 pm |
|
|
Hi,
I'm trying to optimize some SPI access code. The SPI part works fine.
However I would like to bring the data directly into a working register but haven't found a method that works.
When I access the register directly I only get the lower byte of the 16 bit register. So for example a shift left of the lower byte does not flow into the upper byte.
Does anyone know how to access the working registers short of an ASM block?
The following code snippet works when I enable the RAM variable definitions in the source file but not when I disable those RAM definitions and enable the working register pointers in the header file. Nothing I can find enables the pointers as 16 bit pointers even though they point to
16 bit registers.
Thanks for your assistance
Code: |
#include <WorkingRegisterAccess.h>
#include "stdlib.h"
#use rs232(UART2,baud=9600,parity=N,bits=8)
/* Print n as a binary number */
void printbitssimple(int16 n) {
unsigned int16 i,m;
m = (sizeof(n) * 8 - 1);
i = 1<<m;
while (i > 0) {
if (n & i)
printf("1");
else
printf("0");
if (!(m%4))
printf("|");
m-=1;
i >>= 1;
}
printf("\n\r");
}
void main()
{
boolean debug = 1;
// Using the following variable definitions works, i.e. data in ram
int16 wreg10, wreg11, wreg12, wreg13, wreg14;
// Using the defines in the header file, i.e., data in working registers,
// only accesses the lower byte of the working register so it does not work?
char strg[3];
setup_wdt(WDT_OFF);
setup_timer1(TMR_DISABLED|TMR_DIV_BY_256);
// The following routine reads the data from both channels of //
// two ADC chips for 48 samples and a dwell of up to twenty //
// for each channel //
// Read the data into four registers for speed
// Returned Data format
// 14 bits, MSB first, first channel, 14 bits, MSB first, second channel,
// and 4 bits of garbage
// wreg10 = spi_read(0);//read first byte of the results
printf("Enter the first decimal value (0-255)\n\r");
gets(strg);
printf("%s\n\r",strg);
wreg10 = atoi(strg);
printf("First HEX byte is %02X\n\r",wreg10);
// wreg11 = spi_read(0);//read second byte of the results
printf("Enter the second decimal value (0-255)\n\r");
gets(strg);
printf("%s\n\r",strg);
wreg11 = atoi(strg);
printf("Second HEX byte is %02x\n\r",wreg11);
// wreg12 = spi_read(0);//read third byte of the results
printf("Enter the third decimal value (0-255)\n\r");
gets(strg);
printf("%s\n\r",strg);
wreg12 = atoi(strg);
printf("Third HEX byte is %02X\n\r",wreg12);
// wreg13 =spi_read(0);//read fourth byte of the results
printf("Enter the fourth decimal value (0-255)\n\r");
gets(strg);
printf("%s\n\r",strg);
wreg13 = atoi(strg);
printf("Fourth HEX byte is %02x\n\r",wreg13);
wreg14 = wreg11;// save a copy of the second byte for second value
// For example entering 138, 208, 35 and 128 results in -7500 and +568
// Reassemble data for first amplitude value in proper bit positions for 16 bit
// signed integer data. First value is in the eight bits of wreg10, and
// the upper six bits of wreg11. Finally check the sign bit for a 14 bit
// integer and set the upper two bits if the value is negative
if(debug)
printbitssimple(wreg10);
wreg10 <<= 6;
if(debug)
printbitssimple(wreg10);
wreg11 >>= 2;
if(debug)
printbitssimple(wreg11);
wreg10 += wreg11;
if(debug)
printbitssimple(wreg10);
if(wreg10 > 8191)
wreg10 |= 0xC000;// Set a negative value!!!
if(debug)
printbitssimple(wreg10);
printf("Value #1 =%d\n\r",wreg10);
// Reassemble data for second amplitude value in proper bit positions for
// 16 bit signed integer data. The second value is in the last two bits of
// wreg14, the eight bits of wreg12 and the top four bits of wreg13. Finally
// check the sign bit for a 14 bit integer and set the remaining two high
// bits if the value is negative.
// printbitssimple(wreg14);
wreg14 &= 0x03;
// printbitssimple(wreg14);
wreg14 <<= 12;
// printbitssimple(wreg14);
wreg12 <<= 4;
// printbitssimple(wreg12);
wreg14 += wreg12;
// printbitssimple(wreg14);
wreg13 >>= 4;
// printbitssimple(wreg13);
wreg14 += wreg13;
// printbitssimple(wreg14);
if(wreg14 > 8191)
wreg14 |= 0xC000;// Set a negative value!!!
printf("Value #2 =%d\n\r",wreg14);
// printf("Time = %lu microseconds.\n\r",time/10);
}
Header file
#include<24FJ128GA010.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES ICSP2 //ICD uses PGC2/PGD2 pins
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PR //Primary Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PR
#define timer1 *0x0100
#BIT SR_Neg = 0x42.3 //ALU Status Register negative result bit
#BIT SR_Cry = 0x42.0 //ALU Status Register carry result bit
/*
#define WREG10 *0x0014
#define WREG11 *0x0016
#define WREG12 *0x0018
#define WREG13 *0x001A
#define WREG14 *0x001C
*/
#device ICD=TRUE
#use delay(clock=8000000)
|
_________________ Dave N |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jun 24, 2010 5:23 pm |
|
|
I like the small example programs...
You could have reduced the code to two or three lines so we get the point.
I don't have PCWHD, but for a PIC18 you have the following 3 options: Code: | // option 1
#define WREG10 *(int16 *)0x0014
// option 2
int16 WREG11;
#locate WREG11=0x0014
// option 3
#word WREG12=0x0014
void main()
{
WREG10 = 0x10;
WREG11 = 0x11;
WREG12 = 0x12;
} |
Creating the following list file: Code: | .................... WREG10 = 0x10;
0018: CLRF 15
001A: MOVLW 10
001C: MOVWF 14
.................... WREG11 = 0x11;
001E: CLRF WREG11+1
0020: MOVLW 11
0022: MOVWF WREG11
.................... WREG12 = 0x12;
0024: CLRF WREG12+1
0026: MOVLW 12
0028: MOVWF WREG12 |
Option 2 and 3 are specific for the CCS compiler. Note that these last two options create a list file which is easier to read because the register names are known. |
|
|
dneale
Joined: 25 Nov 2009 Posts: 9 Location: Albuquerque NM
|
24F Direct Working Register Access |
Posted: Thu Jun 24, 2010 6:34 pm |
|
|
Thank you ckielstra.
You have been very helpful. I'll try your suggestions. Many of your previous responses have helped me better understand the CCS compiler and PIC hardware.
I must apologise for not including my compiler (PCD) and version (4.109) in the original post even after writing them down in preparation for the post.
Again many thanks,
Dave _________________ Dave N |
|
|
|
|
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
|