|
|
View previous topic :: View next topic |
Author |
Message |
arunkish
Joined: 23 Dec 2008 Posts: 83
|
RF CCS Problem |
Posted: Mon Apr 27, 2009 8:05 pm |
|
|
Hi All
I have a problem with RF Receiving Section. To tell you in depth. I had a code written in assembly that works perfectly and receives the data. I have rewritten the same code in CCS and that fails to work. I really can't find what the problem is and where the problem is. I guess there are some problems with the delays. I have the assembly and the converted CCS code below. Please can someone tell me where I have made the mistake.... Thanks in advance.
ASSEMBLY CODE
Code: | #define XTAL .4000000
#define RF_NBITS .64
#define RF_Full RXFlags,0 ; receive buffer full
#define RFBit RXFlags,1 ; sampled input value
TX_BUFF equ 0x40
RX_BYTE_PTR equ 0x40
CBLOCK RX_BYTE_PTR
rx_byte1
rx_byte2
rx_byte3
rx_byte4
rx_byte5
rx_byte6
rx_byte7
rx_byte8
RFP ;
RFbitc ;
RFsamp ;
RFState ;
RFSkip ;
RXFlags ;
pul_cnt
BIT_CNT
ERR_NO
ENDC
;----------------------------------------------------------------------
IntVector
movwf W_TEMP ; must have been placed in common bank
swapf STATUS,W
movwf STATUS_TEMP ;
BANK0
Async_ISR
movlw .50
subwf TMR0,F
bcf INTCON,T0IF ; interrupt served
; sample RF input pin
bcf RFBit
btfsc RFIn
bsf RFBit
AsyncRF
btfss INTCON,INTE
goto CHK_SKP
btfsc INTCON,INTF
goto SKP1
CHK_SKP
decf RFSkip,F
BNZ ExitIntShort ;
SKP1
btfsc RF_Full
goto ExitIntShort
movf PCLATH,W ; save PCLATH since we will use tables here
movwf PCLATH_TEMP
AsyncStateM
clrf PCLATH ; we assume this routine has been placed in page 0
movf RFState,W
andlw 07
addwf PCL,F
RFTable
goto TRFSYNC
goto TRFHALF
goto TRFBIT
goto TRFZERO
goto TRFCLOCK
goto RFRestore
goto RFRestore
goto RFRestore
RFTableEnd
;------------------------------------
TRFSYNC
btfss INTCON,INTE
goto RDIN
btfsc INTCON,INTF
goto TRFRise
RDIN
btfsc RFBit ;
goto TRFRise
incf RFsamp,F ;
incf RFSkip,F ;
btfsc INTCON,INTE ;
goto EXIT_INT
;Check min
movlw .35
subwf RFsamp,W
btfss STATUS,C
goto EXIT_INT ; check if valid preamble then nable int
bsf INTCON,INTE
bcf INTCON,INTF
; bsf LED2
goto EXIT_INT
TRFRise
btfss INTCON,INTE
goto RFRestore ;
bcf INTCON,INTE
bcf INTCON,INTF
movlw .50
subwf RFsamp,W
btfsc STATUS,C
goto RFRestore
movf RFsamp,w
movwf pul_cnt
; make ready for receiving the first bit
clrf RFbitc
movlw RX_BYTE_PTR
movwf RFP
movlw .2
movwf RFSkip ;
incf RFState,F
; bcf LED2
goto AsyncRFE
;------------------------------------
TRFHALF
btfss RFBit
goto RFRestore1
TRFNEXT movlw D'04' ; set a delay of a full bit ie 400us
TRFSKIP movwf RFSkip ;
incf RFState,F ; move on to next state
goto AsyncRFE
;------------------------------------
TRFBIT
movf FSR,W ; save FSR
movwf FSR_TEMP
movf RFP,W
movwf FSR ; point to current buffer
CLRC
btfss RFBit ; copy in bit (inverted)
SETC
rrf INDF,F ; rotate in buffer (Lsb first-> rotate right)
incf RFbitc,F ; count bits
movf FSR_TEMP,W ; restore FSR
movwf FSR
goto TRFNEXT ; move on next state
;------------------------------------
TRFZERO
btfsc RFBit ; end bit check fails
goto RFRestore3 ;
movlw 7
andwf RFbitc,W ; 8 bit read in?
SKPNZ
incf RFP,F ; next byte
movlw RF_NBITS
subwf RFbitc,W ; riceived them all?
BZ TRFFULL ;
; not yet finished, resync on next rising edge
TRFZN
bsf INTCON,INTE ;ENABLE EXTERNAL INTERRUPT
bcf INTCON,INTF ;CLR INTERRUPT FLAG
movlw D'3' ; next state without delays (skip=1)
movwf RFSkip ;
incf RFState,F ; move on to CLOCK
clrf RFsamp ; init resync counter
goto AsyncRFE
;
;---------------------------------------------------------
TRFFULL bsf RF_Full ; buffer full and ready
bcf INTCON,GIE ;ENABLE EXTERNAL INTERRUPT
goto RFRestore
;---------------------------------------------------------
TRFCLOCK
bcf INTCON,INTE ;DISABLE EXTERNAL INTERRUPT
btfss INTCON,INTF ;CLR INTERRUPT FLAG
goto RFRestore4 ; too long delay
bcf INTCON,INTF ;CLR INTERRUPT FLAG
; btfss RFBit ; waiting for rising edge
; goto RFRestore4 ; too long delay
movlw .205
movwf TMR0
bcf INTCON,T0IF ; interrupt served
movlw .02
movwf RFSkip ; set delay 1/2Te
movlw 1 ; move on to start bit state (1)
movwf RFState ;
goto EXIT_INT
;----------------------------------------------------------------------
;debugging point
RFRestore4
bsf ERR_FLAG
goto RFRestore ;next start bit error
RFRestore3 ;low bit error
clrf ERR_NO
bsf ERR_FLAG
; bsf DERR_LED
goto RFRestore
RFRestore2 ;mid bit error
RFRestore1
movlw 0xff
movwf ERR_NO
bsf ERR_FLAG
; bcf DERR_LED ;High bit error
goto RFRestore
; nop debugging point
;---------------------------------------------------------
RFRestore
; bsf LED2
movf RFbitc,w
movwf BIT_CNT
clrf RFState ; reset state machine
movlw .1
movwf RFSkip ; preload skip 1
clrf RFsamp
;-----------------------------------------------------------
;
AsyncRFE
EXIT_INT
movf PCLATH_TEMP,W ; restore PCLATH
movwf PCLATH
ExitIntShort
swapf STATUS_TEMP,W ; restore context
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
retfie ; exit re-enable interrupts
;----------------------------------------------------------------------
InitRX
clrf RFState ; init receiver
clrf RXFlags
movlw .1
movwf RFSkip ; no delays
clrf RFsamp ;
return
;----------------------------------------------------------------------
INIT_TIMER0
banksel TMR0
movlw D'205' ; LOAD VALUE FOR 100 MICRO SECONDS
movwf TMR0
banksel OPTION_REG
movlw B'10000000'
movwf OPTION_REG ;TIMER0 PRESCALER = 1:1,INTERNAL CLOCK & TIMER ON 200us
bsf OPTION_REG,INTEDG ;INTERRUPT ON RISING EDGE OF RB0\INT
clrf INTCON
bsf INTCON,T0IE ;ENABLE TIMER0 INTERRUPT
bcf INTCON,INTE ;DISABLE EXTERNAL INTERRUPT ENABLE
bcf INTCON,INTF ;CLR INTERRUPT FLAG
BANK0
return
;************************************************************
|
CCS CODE
Code: | #include<12f675.h>
#fuses NOBROWNOUT,NOWDT,INTRC_IO,NOPROTECT,NOMCLR,PUT
#use delay(clock=4000000)
#define PRODUCT_ID 0xaa //1.PRODUCT CODE 0xaa
#define DEVICE_ID 0x03 //2.SMOKE DETECTOR
#define PANEL_SL_HIGH 0x0b //3.SLNO HIGH 0-255
#define PANEL_SL_LOW 0x0b //4.SLNO LOW 0-255
#define SL_NO_HIGH 0x00 //5.SLNO HIGH 0-255
#define SL_NO_LOW 0x01 //6.SLNO HIGH 0-255
//============================================
void data_check(void);
void pwm(void);
#BYTE OPTION_REG = 0X81
#byte INTCON = 0x0B
#byte GPIO = 0x05
#byte gpio_tris = 0x85
#bit RX_PIN = GPIO.2
#bit siren = GPIO.0
#bit led = GPIO.1
#bit INTE = INTCON.4
#bit GIE = INTCON.7
#bit INTF = INTCON.1
#bit EDGE = OPTION_REG.6
byte pre,count,data,rx_data[8],i,rx_and,status;
long int k,j;
#bit data_hed=status.0
#bit tx_and=status.1
#bit int_dly=status.2
#bit data_che=status.3
//==============================================
#zero_ram
void main()
{
gpio_tris=0x3c;
GPIO=0X00;
data=0;
count=0;
pre=0;
GIE=1;
INTE=1;
INTF=0;
EDGE=1;
tx_and=0;
int_dly=1;
data_hed=0;
data_che=0;
rx_and=0x01;
for(i=0;i<=7;i++)
rx_data[i]=0;
led=1;
delay_ms(1000);
led=0;
i=0;
j=0;
k=0;
while(1)
{
data_check();
pwm();
}
}
//==============================================
#INT_EXT
void ext(void)
{
INTE=0;
INTF=0;
GIE=0;
if(pre<16)
{
delay_us(400);
++pre;
}
if(pre==16&&data_hed==0)
{
delay_us(4405);
data_hed=1;
}
if((pre==16)&&(data_hed==1))
{
delay_us(401);
if(!RX_PIN)
rx_data[data]=rx_data[data]|rx_and;
rx_and = rx_and<<1;
count++;
if(count==8)
{
rx_and=0x01;
count=0;
data++;
if(data==8)
{
if(rx_data[0]==PRODUCT_ID)
{
data_che=1;
delay_ms(600);
INTE=0;
data=0;
pre=0;
data_hed=0;
return;
}
else
{
for(i=0;i<=7;i++)
rx_data[i]=0;
}
data=0;
pre=0;
data_hed=0;
}
}
}
INTE=1;
GIE=1;
}
//==============================================
void data_check(void)
{
if(data_che)
{
if(rx_data[0]==PRODUCT_ID)
{
if(rx_data[1]==DEVICE_ID)
{
if(rx_data[5]==SL_NO_LOW)
{
tx_and=1;
led=1;
}
}
else if(rx_data[1]==0x05){tx_and=0;siren=0;led=0;}
}
data_che=0;
for(i=0;i<=7;i++)
rx_data[i]=0;
INTE=1;
GIE=1;
}
}
//=============================================
void pwm(void)
{
byte i;
if(tx_and)
{
while(i!=500)
{
siren=1;
delay_us(500);
siren=0;
delay_us(500);
i++;
}
i=0;
while(i!=500)
{
siren=1;
delay_us(500);
delay_us(250);
siren=0;
delay_us(500);
delay_us(250);
i++;
}
i=0;
}
}
//==============================================
|
|
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Tue Apr 28, 2009 12:22 am |
|
|
I quickly look at the code and first thing I saw that is not good, well is really bad actually, you use delays in ISR.
So it is no wonder that your PWM part is not working like it should. Try to rewrite whole thing. Use Timer ISR for PWM, that would be probably best practise. |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Tue Apr 28, 2009 1:06 am |
|
|
Thank you for your response. I didn't give much prefrence to the PWM part at this time. I just want the RX to work properly. Hopefully I will be correcting the PWM as you said. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Tue Apr 28, 2009 2:03 am |
|
|
Do you use rs232 protocol for reception or is this another protocol for receiving serial data?
You could use port A change interrupt. You could select an input pin on port A and then write your ISR around that. And in the ISR you could use timer to check how much time passed from one change to another. |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Tue Apr 28, 2009 8:01 pm |
|
|
Hi Bungee
I dont use RS232 protocol for receiving the data. I'm not much familiar with assembly and as I said you the posted assembly code works perfectly, but the code that I tried did not work. Please help!!
Thanks |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Wed Apr 29, 2009 1:15 am |
|
|
Well as I said in first post. You used delay in interrupt routine, but you don't use it in the assembly.
Why would you like to rewrite it to the CCS in the first place if the assembly works for you? |
|
|
|
|
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
|