![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
bhtt
Joined: 08 Jan 2006 Posts: 2
|
Is asm code of CCS C instruction "ouput_low() "wro |
Posted: Sun Jan 08, 2006 1:45 pm |
|
|
hi;
I'm doing a project, and i use CCS C 3.235 to write code for 16f877A. Here is the header of my project.
#include <16F877.h>
#fuses HS, NOLVP, NOWDT, NOPROTECT
#device *=16 ADC=10
#use delay(clock=20250000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7)
#include <stdlib.h>
#include <string.h>
#define DIR4 PIN_D0
#define PWM4 PIN_C2
#define DIR5_CAM PIN_D1
#define PWM5_CAM PIN_C1
#define DIR3 PIN_D2
#define PWM3 PIN_D3
#define DIR1 PIN_D4
#define PWM1 PIN_D5
#define DIR2 PIN_D6
#define PWM2 PIN_D7
#define LIGHT PIN_E0
#define CAMERA PIN_E1
And here is the CCS code in my project
void den_bat()
{
output_low(LIGHT);
}
When I check the C/ASM list of this instruction. It is like this :
....................
.................... void den_bat()
.................... {
.................... output_low(LIGHT);
*
0176: BSF 03.5
0177: BCF 09.0
0178: BCF 03.5
0179: BCF 09.0
I think it is incorrect in line 0177, it must be "BCF 89.0" because the address of TRISE register in 16f877A is 0x89.
And another asm code I think is incorrect :
.................... setup_adc(ADC_CLOCK_DIV_32);
*
0253: BCF 1F.6
0254: BSF 1F.7
0255: BSF 03.5
0256: BSF 1F.7
0257: BCF 03.5
0258: BSF 1F.0
.................... setup_adc_ports(AN0_AN1_AN3);
0259: BSF 03.5
025A: BCF 1F.0
025B: BCF 1F.1
025C: BSF 1F.2
025D: BCF 1F.3
.................... set_adc_channel(0);
025E: MOVLW 00
025F: MOVWF 78
0260: BCF 03.5
0261: MOVF 1F,W
0262: ANDLW C7
0263: IORWF 78,W
0264: MOVWF 1F
I think the correct ASM codes for these instruction are :
.............................. setup_adc(ADC_CLOCK_DIV_32);
#asm
BCF 0x03,5 //BANK0 : ADCON0
BCF 0x1F,6
BSF 0x1F,7
BSF 0x03,5 // BANK1: ADCON1
BSF 0x9F,7 //RIGHT JUSTIFIED
BCF 0x03,5
BSF 0x1F,0 //TURN ON ADC
#endasm
..............................setup_adc_ports( AN0_AN1_AN3 );
#asm
BSF 0x03,5
BCF 0x9F,0
BCF 0x9F,1
BSF 0x9F,2
BCF 0x9F,3
#ENDASM
.....................................set_adc_channel(0);
#ASM
BSF 0x03,5 //BANK1
BCF 0x1F,3 //CHANNEL 0
#ENDASM
Am I right? |
|
![](templates/subSilver/images/spacer.gif) |
ak6dn Guest
|
Re: Is asm code of CCS C instruction "output_low()" |
Posted: Sun Jan 08, 2006 3:05 pm |
|
|
bhtt wrote: | hi;
void den_bat()
{
output_low(LIGHT);
}
When I check the C/ASM list of this instruction. It is like this :
....................
.................... void den_bat()
.................... {
.................... output_low(LIGHT);
*
0176: BSF 03.5
0177: BCF 09.0
0178: BCF 03.5
0179: BCF 09.0
I think it is incorrect in line 0177, it must be "BCF 89.0" because the address of TRISE register in 16f877A is 0x89.
Am I right? |
You are incorrect. The BCS/BCF instructions only have a 7bit direct operand field; only registers 0x00-0x7F can be directly accessed. The instruction "BCF 89.0" is ILLEGAL.
The CCS compiler is doing the right thing to access the DIRECTION bit in register 0x89 (setting/clearing the page bit in the status register).
Same answer applies to your other observation. |
|
![](templates/subSilver/images/spacer.gif) |
bhtt
Joined: 08 Jan 2006 Posts: 2
|
|
Posted: Mon Jan 09, 2006 2:39 am |
|
|
no, I don't think I was incorrect because I tried to use these asm codes instead of the instruction output_low(LIGHT) :
//............................output_low(LIGHT);
#asm
BSF 0x03,5
BCF 0x89,0
BCF 0x03,5
BCF 0x09,0
#endasm
And it worked. If you don't believe me, try it.
But in fact, the instruction also show the same result as that of those asm codes.
So, if you say it is correct, let's look at it carefully .
0176: BSF 03.5 //bank1 , right?
0177: BCF 09.0// clear bit0 of register 0x09 (portE), but we are in
//bank1 and 0x09 is in bank 0
0178: BCF 03.5 //I agree with the rest.
0179: BCF 09.0
About the asm code of setup_adc(ADC_CLOCK_DIV_32) , I looked up the datasheet of PIC16f87XA, in the section A/D Converter module.
To setup Fosc/32, bit 7,6 of ADCON0(0x1Fh) is 10, and bit 6 of ADCON1(0x9Fh) is 0,
So, let's look at the asm code of setup_adc(ADC_CLOCK_DIV_32):
0253: BCF 1F.6 // bit 6 of ADCON0 is 0
0254: BSF 1F.7 // bit7 of ADCON0 is 1
0255: BSF 03.5 // bank1
0256: BSF 1F.7 // bit 7 of ADCON0 is 1 again, but how can you access
//bank0 if you are in bank1 now.
0257: BCF 03.5
0258: BSF 1F.0
And about
//.................... setup_adc_ports(AN0_AN1_AN3);
0259: BSF 03.5 //bank1
025A: BCF 1F.0 // 025A to 025D: 9F instead of 1F because the
//AD configuration Control bits is in bit3- bit0 of ADCON1
// which is 0x9F.
025B: BCF 1F.1
025C: BSF 1F.2
025D: BCF 1F.3
And about set_adc_channel(AN0), I really don't know why it give out so much codes, I don't understand these codes, I think just 2 asm codes like I do is enough. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Mon Jan 09, 2006 3:42 am |
|
|
I'm sorry, but you are incorrect.
The original responder is correct, that to access 'address 0x89', you actually have to set the page register, then access address 09. The 'assembler', is actually more than a basic assembler, and automatically bank switches for you. If you look at what your assembler code generates, you will see:
Code: |
.................... #asm
.................... BSF 0x03,5
003F: BSF 03.5
.................... BCF 0x89,0
0040: BCF 09.0
.................... BCF 0x03,5
0041: BCF 03.5
.................... BCF 0x09,0
0042: BCF 03.5
0043: BCF 09.0
|
The assembler, knows it cannot handle address '89', so trims if to just 09, and if the page was not already selected, would automatically do the BSF 03,5 as well. Since the high page is already accessed, it does not bother to add a BSF 03,5(your instruction is actually uneccessary here). Notice though, on lines 42, and 43, that when you access address 9, after address 89, it adds it's own bank switch, because it knows to change to the low page.
If you code:
[/code]
#asm
BCF 0x89,0
BCF 0x09,0
BSF 0x89,0
BSF 0x09,0
#endasm
[/code]
And then look at the assembler generated, you will see:
Code: |
.................... BCF 0x89,0
003F: BCF 09.0
.................... BCF 0x09,0
0040: BCF 03.5
0041: BCF 09.0
.................... BSF 0x89,0
0042: BSF 03.5
0043: BSF 09.0
.................... BSF 0x09,0
0044: BCF 03.5
0045: BSF 09.0
.................... #endasm
|
Notice how the compiler, is automatically switching banks for you.
The internal assembler in CCS, handles such automatic page addressing, just as the compiler does. The original code generated for the output_low instruction is correct.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|