|
|
View previous topic :: View next topic |
Author |
Message |
mindstorm88
Joined: 06 Dec 2006 Posts: 102 Location: Montreal , Canada
|
Faster simulated port ?? |
Posted: Mon Mar 15, 2010 10:21 am |
|
|
Hi guys , just fooling around a bit , and would like to know if there a faster way to do it ? I'm using a macro to create an 8 bit port, but to transfer data to that port takes 96.5 uSec. Any faster way ??
Code: |
#include <16F684.h>
//#device adc=10
#fuses NOWDT,INTRC_IO,BROWNOUT,NOMCLR
#use delay(clock=8000000)
const unsigned char sine_table[256] = {127,130,133,136,139,
143,146,149,152,155,158,161,164,167,
170,173,176,178,181,184,187,190,192,195,198,200,203,205,
208,210,212,215,217,219,221,223,225,227,229,231,233,234,
236,238,239,240,242,243,244,245,247,248,249,249,250,251,
252,252,253,253,253,254,254,254,254,254,254,254,253,253,
253,252,252,251,250,249,249,248,247,245,244,243,242,240,
239,238,236,234,233,231,229,227,225,223,221,219,217,215,
212,210,208,205,203,200,198,195,192,190,187,184,181,178,
176,173,170,167,164,161,158,155,152,149,146,143,139,136,
133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,
87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,
37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,
5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,
11,12,14,15,16,18,20,21,23,25,27,29,31,33,35,37,39,42,44,
46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,
99,102,105,108,111,115,118,121,124};
// spare pins
#bit RC0 = 7.0
#bit RC1 = 7.1
#bit RC2 = 7.2
#bit RC3 = 7.3
#bit RC4 = 7.4
#bit RC5 = 7.5
#bit RA1 = 5.1
#bit RA2 = 5.2
// MACRO
// DAC_PORT from spare pins
#define DAC_PORT(x)\
RA1 = x & 1;\
RA2 = (x>>1)& 1;\
RC0 = (x>>2)& 1;\
RC1 = (x>>3)& 1;\
RC2 = (x>>4)& 1;\
RC3 = (x>>5)& 1;\
RC4 = (x>>6)& 1;\
RC5 = (x>>7)& 1;\
BYTE sine_index;
//=============================================
// main
//=============================================
void main()
{
set_tris_c(0b00000000);
set_tris_a(0b00000000);
sine_index=0;
while(1)
{
DAC_PORT(sine_table[sine_index]); // takes 96.5 usec
if(++sine_index==256)
sine_index=0;
}
}
|
If you have a better subject name for this topic lmk !!! |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Mon Mar 15, 2010 11:54 am |
|
|
I'm not expert in CCS
You should try to use a bigger pic, where you have a full 8 bit port.
Check your disassembly list, I'm sure the port translation take a few cycle. I find C is best for complex programs, ASM for speed and code space saving.
Try to write a segment in ASM and optimize it.
This 18F code in ASM will change the port in .600 us if you run 40Mhz or 1.2 us at 20 Mhz and 3 us at 8 Mhz
Code: | ;******************************************************************************
;Start of main program
Main: ;********************
banksel trisb
movlw 0x00
movwf trisb
banksel portb
clrf portb
;********************
movlw high(sin_table)
movwf tblptrh
movlw low(sin_table)
movwf tblptrl
send_sin:
;********************
tblrd*+ * 0.00 us
movf tablat,w
movwf portb
goto send_sin * 0.400 us + 200 ns to return
;********************
sin_table:
db .27,.130,.133,.136,.139
db .143,.146,.149,.152,.155,.158,.161,.164,.167
db .170,.173,.176,.178,.181,.184,.187,.190,.192,.195,.198,.200,.203,.205
db .208,.210,.212,.215,.217,.219,.221,.223,.225,.227,.229,.231,.233,.234
db .236,.238,.239,.240,.242,.243,.244,.245,.247,.248,.249,.249,.250,.251
db .252,.252,.253,.253,.253,.254,.254,.254,.254,.254,.254,.254,.253,.253
db .253,.252,.252,.251,.250,.249,.249,.248,.247,.245,.244,.243,.242,.240
db .239,.238,.236,.234,.233,.231,.229,.227,.225,.223,.221,.219,.217,.215
db .212,.210,.208,.205,.203,.200,.198,.195,.192,.190,.187,.184,.181,.178
db .176,.173,.170,.167,.164,.161,.158,.155,.152,.149,.146,.143,.139,.136
db .133,.130,.127,.124,.121,.118,.115,.111,.108,.105,.102,.99,.96,.93,.90
db .87,.84,.81,.78,.76,.73,.70,.67,.64,.62,.59,.56,.54,.51,.49,.46,.44,.42,.39
db .37,.35,.33,.31,.29,.27,.25,.23,.21,.20,.18,.16,.15,.14,.12,.11,.10,.9,.7,.6
db .5,.5,.4,.3,.2,.2,.1,.1,.1,.0,.0,.0,.0,.0,.0,.0,.1,.1,.1,.2,.2,.3,.4,.5,.5,.6,.7,.9,.10
db .11,.12,.14,.15,.16,.18,.20,.21,.23,.25,.27,.29,.31,.33,.35,.37,.39,.42,.44
db .46,.49,.51,.54,.56,.59,.62,.64,.67,.70,.73,.76,.78,.81,.84,.87,.90,.93,.96
db .99,.102,.105,.108,.111,.115,.118,.121,.124
END |
|
|
|
mindstorm88
Joined: 06 Dec 2006 Posts: 102 Location: Montreal , Canada
|
|
Posted: Mon Mar 15, 2010 1:21 pm |
|
|
dezso wrote: | You should try to use a bigger pic, where you have a full 8 bit port.
|
I agree %100 with you , but just want to know if there a way to improve with this pic !! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 15, 2010 1:35 pm |
|
|
Use #fast_io to get rid of the TRIS in the ASM code. This reduces the
instruction count. You can see this by looking at the .LST file.
Then notice that most of your bits are in PortC. So use output_c()to do
them all at once. Do the two remaining bits with output_bit(). Example:
Code: |
#use fast_io(A)
#use fast_io(C)
void main()
{
int8 temp;
set_tris_c(0b00000000);
set_tris_a(0b00000000);
sine_index=0;
while(1)
{
temp = sine_table[sine_index];
output_c(temp >> 2); // Bits 7-2
output_bit(PIN_A2, bit_test(temp, 1)); // Bit 1
output_bit(PIN_A1, bit_test(temp, 0)); // Bit 0
|
The .LST file shows the result:
Code: |
.................... output_c(temp >> 2); // Bits 7-2
0125: RRF 25,W
0126: MOVWF 26
0127: RRF 26,F
0128: MOVLW 3F
0129: ANDWF 26,F
012A: MOVF 26,W
012B: MOVWF 07
.................... output_bit(PIN_A2, bit_test(temp, 1)); // Bit 1
012C: BTFSC 25.1
012D: GOTO 130
012E: BCF 05.2
012F: GOTO 131
0130: BSF 05.2
.................... output_bit(PIN_A1, bit_test(temp, 0)); // Bit 0
0131: BTFSC 25.0
0132: GOTO 135
0133: BCF 05.1
0134: GOTO 136
0135: BSF 05.1 |
|
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Mon Mar 15, 2010 1:48 pm |
|
|
You could save a little time by setting the two pins in port A like this:
Code: |
output_bit(PIN_A2, 0);
if (bit_test(temp, 1))
output_bit(PIN_A2, 1);
|
That's if it's OK to set them low, then high again whenever a 1 gets sent out.
But really, the best thing would be to put all 8 outputs on the same port. It would be faster, and all the bits would change at one time. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Mon Mar 15, 2010 8:01 pm |
|
|
I was just thinking, the write to the designated port will occur in 2 or more write cycle, your sine wave will be very choppy since the portc update before porta or vice verse.
Like .233 will output to 0b11101001, portc 0b111010 will set your R2R to a specific voltage than in a few us later porta add 0b01 to the final voltage. |
|
|
mindstorm88
Joined: 06 Dec 2006 Posts: 102 Location: Montreal , Canada
|
|
Posted: Tue Mar 16, 2010 4:58 am |
|
|
PCM way reduce from 96 uSec to 18 uSec , this give a very crude wave that could be cleaned by a good filter !!! Thanks guys all this is a very good learning experience !!! |
|
|
|
|
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
|