Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Weird or what? USART problem

Status
Not open for further replies.

zhaniko93

New Member
Take a look at my program:
Code:
   ; W = 196 (32)
   ; S = 160 (64)
   ; A = 128 (96)
   ; D = 96 (128)
   ; N = 64 (160)

   #define K_win PORTA, 4
   #define K_ukan PORTA, 3
   #define K_marjvniv PORTA, 2
   #define K_marcxniv PORTA, 1 
   #define K_turbo PORTA, 0



   LIST P=16F628A, R=DEC    ; Use the PIC16F628 and decimal system

   #include "P16F628A.INC"  ; Include header file
   __config  _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _MCLRE_OFF 
   errorlevel -302



   goto Start
   org 0x4
   movwf WRKNG
   call ISR
   movfw WRKNG
   retfie


   cblock 0x20
      T1
      T2
      T3
      T4
      T5
      WRKNG
      TURBOO
   endc

 
Start  movlw 7 
   movwf CMCON          
   
   movlw b'11000000'
   movwf INTCON  

   clrf PORTA
   clrf PORTB

  banksel TRISA

   movlw b'00000110'       ; RB2(TX)=1 others are 0 
   movwf TRISB

  movlw b'00011111'
  movwf TRISA

;INTERRUPT
   movlw b'00100000'
   movwf PIE1

; Boot Baud Rate = 9600, No Parity, 1 Stop Bit 
; 
   movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps) 
   movwf SPBRG 
   movlw b'00100100'       ; brgh = high (2) 
   movwf TXSTA             ; enable Async Transmission, set brgh
   BANKSEL RCSTA
   movlw b'10010000'       ; enable Async Reception 
   movwf RCSTA 


   call message
loop  movlw 3
   btfss K_win
   addwf PCL, f
   call Dacda_
   movlw 32
   call Action

   movlw 3
   btfss K_ukan
   addwf PCL, f
   call Dacda_
   movlw 64
   call Action

   movlw 3
   btfss K_marjvniv
   addwf PCL, f
   movlw 96
   call Action
   call Dacda__

   movlw 3
   btfss K_marcxniv
   addwf PCL, f
   movlw 128
   call Action
   call Dacda__


   movlw 3
   btfss K_turbo
   addwf PCL, f
   movlw 160
   call Action
   call Dacda__

   goto loop 

; ------------------------------------------------------------- 
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING 
; ------------------------------------------------------------- 
; 
send    movwf TXREG             ; send data in W
   banksel TXSTA
   btfss TXSTA,TRMT        ; (1) transmission is complete if hi 
   goto $-1
   banksel PORTA
   return 


ISR  movf RCREG,W
   call send
   movwf T1

   sublw A'w'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 32
   call Action


   movfw T1
   sublw A's'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 64
   call Action

   movfw T1
   sublw A'a'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 96
   call Action

   movfw T1
   sublw A'd'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 128
   call Action

   movfw T1
   sublw A'n'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 160
   call Action

   return






Action   iorwf PORTB, f
   call Dacda
   call Dacda
   call Dacda
   call Dacda   ;<<<<<<<--------------------------------------------- THIS!!!!!!!!!!
   movlw b'00011111'
   andwf PORTB, f
   return


Del1 movlw 30
   movwf T2
   decfsz T2, f
   goto $-1
   return



message movlw A'J'
   call send
   movlw A'a'
   call send
   movlw A'K'
   call send
   movlw A'o'
   call send
   movlw A' '
   call send
   movlw A'V'
   call send
   movlw A'0'
   call send
   movlw A'.'
   call send
   movlw A'1'
   call send
   movlw 0x0D
   call send

   return


Dacda_ call Dacda
   call Dacda
   call Dacda
   call Dacda
   return

Dacda__ movlw 50
   movwf TURBOO
XAX   decfsz TURBOO, f
   call Dacda_
   decfsz TURBOO, f
   goto XAX
   return

Dacda movlw 200
   movwf T3
   decfsz T3, f
   call Del1
   decfsz T3, f
   goto $-3
   return




        END

The programs looks difficult but the problem, I think, doesn't need exploring the code.
when I simulate this in Proteus, everything is ok but if I click any of w, a, d, s or n buttons and just keep my finger on the button, everything stucks at fourth send of character. if I remove the <<<<THIS (call Dacda), even if I click and keep finger on button, everything runs ok... what's wrong? I have attached proteus file, this code is Pulti.asm and you can remove second PIC from proteus file (which requires dzrava.hex) I have tried many things but solving the problem already seems impossible to me becouse of my small experience. can any1 help me?
 

Attachments

  • JaKo 16f628 NEW.zip
    20.1 KB · Views: 125
I think you may have a stack problem, You call Action which calls Dacda__ which calls Dacda_ which calls Dacda which calls Del1. That is 5 calls deep and you also call it from the, already 2 level deep, ISR. This is a total of 12 stack calls and the stack can only handle 8 levels.

Some bad bits,
Code:
		[COLOR="red"]org	0	;add this[/COLOR]
		goto	Start
		org	0x4
		movwf	WRKNG
		call	ISR	[COLOR="red"];<--- move your ISR here.[/COLOR] 
		movfw	WRKNG
		retfie
Your ISR should be as short as possible and use as little of the stack as possible. Yours uses 7 levels of the stack and there are only 8 available. Also, NEVER call subroutines from the main code and the ISR as they will not function correctly. Set flags in the ISR and act on the flags in the main loop.


And why are you doing this,
Code:
loop		movlw	3
		btfss	K_win
		[COLOR="red"]addwf	PCL, f		;change to a goto NoAction[/COLOR] 
		call	Dacda_
		movlw	32
		call	Action
[COLOR="red"]NoAction				;add this label[/COLOR]
The reason the addwf PCL is so bad is that you have no idea if the code will straggle a page boundary. Using wierd instructions like this is also bad because other programmers may not realise what it is doing.

Mike.
 
Thanks mike, but can you answer several questions? P.S. I have debugged and stack overflow doesn't appear anywhere... anyway, I'll try to reduce "call"-s
1)org 0 ;add this why? it doesn't actually change anything...
2)sorry for my bad English, I can't understand what "straggle a page boundary" means, can you explain with simpler words?
3) why does the code work perfectly if I remove the fourth "call Dacda" and happens some kind of "error", which I couldn't find, if I add fourth call?
I agree that my code needs kinda "optimization", I'll do as much as I can after solving this problem : ))
 
3) why does the code work perfectly if I remove the fourth "call Dacda" and happens some kind of "error", which I couldn't find, if I add fourth call?

I'm guessing that an interrupt comes along during the 4th call and that causes a stack crash. Or, it pushes your addwf PCL over a page boundary, try replacing it with a nop and see if it still crashes.

Mike.
 
I have found out that some kind of USART error appears and can you tell me what does USART continuous receive mean? with simple english please :)
 
Hey I have optimized the code and explained the problem:
Code:
   ; W = 196 (32)
   ; S = 160 (64)
   ; A = 128 (96)
   ; D = 96 (128)
   ; N = 64 (160)

   #define K_win PORTA, 4
   #define K_ukan PORTA, 3
   #define K_marjvniv PORTA, 2
   #define K_marcxniv PORTA, 1 
   #define K_turbo PORTA, 0



   LIST P=16F628A, R=DEC    ; Use the PIC16F628 and decimal system

   #include "P16F628A.INC"  ; Include header file
   __config  _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _MCLRE_OFF 
   errorlevel -302



   goto Start
   org 0x4
   movwf WRKNG
   call ISR
   movfw WRKNG
   retfie


   cblock 0x20
      Top_Bit_Saver
      WRKNG
      Dely1
      Dely10
   endc

 
Start  movlw 7 
   movwf CMCON          
   
   movlw b'11000000'
   movwf INTCON  

   clrf PORTA
   clrf PORTB

  banksel TRISA

   movlw b'00000110'       ; RB2(TX)=1 others are 0 
   movwf TRISB

  movlw b'00011111'
  movwf TRISA

;INTERRUPT
   movlw b'00100000'
   movwf PIE1

; Boot Baud Rate = 9600, No Parity, 1 Stop Bit 
; 
   movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps) 
   movwf SPBRG 
   movlw b'00100100'       ; brgh = high (2) 
   movwf TXSTA             ; enable Async Transmission, set brgh
   BANKSEL RCSTA
   movlw b'10010000'       ; enable Async Reception 
   movwf RCSTA 


   call message
loop  movlw 4
   btfss K_win
   addwf PCL, f
   movlw 20
   call Delay10
   movlw 32
   call Action

   movlw 4
   btfss K_ukan
   addwf PCL, f
   movlw 20
   call Delay10
   movlw 64
   call Action

   movlw 5
   btfss K_marjvniv
   addwf PCL, f
   movlw 96
   call Action
   movlw 0xFF
   call Delay10
   call Delay10

   movlw 5
   btfss K_marcxniv
   addwf PCL, f
   movlw 128
   call Action
   movlw 0xFF
   call Delay10
   call Delay10


   movlw 5
   btfss K_turbo
   addwf PCL, f
   movlw 160
   call Action
   movlw 0xFF
   call Delay10
   call Delay10

   goto loop 

; ------------------------------------------------------------- 
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING 
; ------------------------------------------------------------- 
; 
send    movwf TXREG             ; send data in W
   banksel TXSTA
   btfss TXSTA,TRMT        ; (1) transmission is complete if hi 
   goto $-1
   banksel PORTA
   return 


ISR  BTFSC    RCSTA,OERR 
               GOTO    overerror            ;if overflow error... 


   movf RCREG,W
   call send
   movwf Top_Bit_Saver

   sublw A'w'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 32
   call Action


   movfw Top_Bit_Saver
   sublw A's'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 64
   call Action

   movfw Top_Bit_Saver
   sublw A'a'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 96
   call Action

   movfw Top_Bit_Saver
   sublw A'd'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 128
   call Action

   movfw Top_Bit_Saver
   sublw A'n'
   movlw 2
   btfss STATUS, Z
   addwf PCL, f
   movlw 160
   call Action

   return


Action   iorwf PORTB, f
   movlw 0x55
   call Delay10
   movlw b'00011111'
   andwf PORTB, f
   return






message movlw A'J'
   call send
   movlw A'a'
   call send
   movlw A'K'
   call send
   movlw A'o'
   call send
   movlw A' '
   call send
   movlw A'V'
   call send
   movlw A'0'
   call send
   movlw A'.'
   call send
   movlw A'1'
   call send
   movlw 0x0D
   call send

   return



   
Delay10 movwf Dely10
                 decfsz Dely10, w
                call Delay1
                decfsz Dely10, f
                goto $-3
                return

   

Delay1 movlw 0xFF
              movwf Dely1
              decfsz Dely1, w
              nop
              decfsz Dely1, f
              goto $-3
              return
overerror   
         bsf PORTA, 7
        nop
         goto $-1
               return
        END


the problem is Delay between receiovings. I mean, when PC sends string, I receive 1 char and than wait for movlw 0x55 call Delay10 Time, by which time PC sends another characters and something goes wrong. I dont understand the architecture of USART well and can any1 explain me? P.S. I think that thaks not overrun error becouse it never bsf PORTA, 7 (see the code). what should I do?
 
You've still got a completely spurious call in the ISR

Code:
org 0x4
   movwf WRKNG
   call ISR
   movfw WRKNG
   retfie

What for?, it's doesn't help anything.

As Mike has mentioned, ISR's need to be as short as possible, and include as few calls as possible (preferably none).

Remove the three middle lines above, and place the ISR directly there - no need for a call to it, and plenty of reasons not to do so.
 
I need it because I need to transfer characters with RF and it has very low operating frequency so cant it be solved? I want to solve the problem not escape from it.
 
Nigel
Thanks I will
 
I need it because I need to transfer characters with RF and it has very low operating frequency so cant it be solved? I want to solve the problem not escape from it.

If you're using RF the UART isn't really suitable anyway, you need Manchester coding (or similar) plain RS232 doesn't work very well. I don't see why you would ned delays, even if attempting to use the UART?.
 
I am decoding info from PC using USART, then making some operations on it and sending over RF to another PIC. The problem is that I'm using ht12E to encode Paralell information and then https://www.electro-tech-online.com/custompdfs/2011/01/1989.pdf this one to transmit. It says: Square wave modulation MAX 4Khz and if I don't put delay, it wont work. (Correct me if I'm wrong), because PIC works on 4Mhz (actually 1Mhz). So I need to put delay, and putting it rises some problem which I dont know how to solve. I don't understand why did you mention the Manchester coding, I'm using encoder IC so I don't need any codings.
 
I am decoding info from PC using USART, then making some operations on it and sending over RF to another PIC. The problem is that I'm using ht12E to encode Paralell information and then https://www.electro-tech-online.com/custompdfs/2011/01/1989-1.pdf this one to transmit. It says: Square wave modulation MAX 4Khz and if I don't put delay, it wont work. (Correct me if I'm wrong), because PIC works on 4Mhz (actually 1Mhz). So I need to put delay, and putting it rises some problem which I dont know how to solve. I don't understand why did you mention the Manchester coding, I'm using encoder IC so I don't need any codings.

The HT12E is a simple remote control encoder, NOT a data encoder for microcontrollers, I suspect this is why you're having so many problems, trying to bodge a solution using the completely wrong components.

If you want to use an external encoder/decoder (rather than just doing it in the PIC), then use a correct one, something like these:
 
I know what ht12E is and this is absolutely what I want. P.S. there are no such IC-s in shop in my country and why can't I do such way? I want to transmit just 4 bits, use ht12e to encode it for RF module and then transmit. I have such configuration **broken link removed** just have microcontroller pins instead switches
 
P.S. please download my files, open with proteus and click n several times, everything goes OK but if you click n and keep your finger on it, n is transmitted only two times and than something strange happens which I can't explain. please download and take a look.
 

Attachments

  • JaKo 16f628 NEW.zip
    20.1 KB · Views: 128
  • Dzrava.HEX
    1.3 KB · Views: 147
  • pulti.HEX
    969 bytes · Views: 155
  • pulti.asm
    3.9 KB · Views: 149
  • Dzrava.asm
    4.4 KB · Views: 147
if I click quickly several times, everything is ok but if I just keep my finger, something happens
 
I know what ht12E is and this is absolutely what I want. P.S. there are no such IC-s in shop in my country and why can't I do such way?

You can of course do it that way if you wish, but it's more complicated, it's clumsy, it's slow, it wastes I/O pins and it's more difficult to do. You're by no means the first here to do it this 'wrong way', and all have had huge problems - there's a reason why there's a 'right way' and a 'wrong way'.

Is there any reason you didn't just do it all in the PIC?, my tutorials cover that.

I don't use any simulators, and don't even have Proteus, so I can try your files for you.
 
Yes but theres only one shop in our city and **broken link removed** heres the list of ICs which are available :( But first of all what worries me is the strange problem in simulation, just USART problem which you can see if you download pulti.asm and if others have, .zip file too for simulation in ISIS.
Nigel
Thank you very much for remarkable efforts to help me but first of all I want to solve the USART problem, why it "stops responding" or something like that if I keep my finger on N, can you take a look at pulti.asm? I want to learn whats the problem and why, not just escape from it or solve it so that I dont understand why was it acting so....
 
hi z93,

When you keep the 'n' key pressed, the UART RX detects an OVER RUN error and then GOTO 'overerror' which is a never ending loop.

I would strongly would advise you to start a new program, this one has so many potential problems its going to give you grief.

Develop the UART and ISR initially and prove its operation, then start adding the other routines.

DONT keep calling multiple 'calls' from within the ISR and drop the unnecessary delays.
 
Last edited:
Well, actually the problem is that it DOESN'T goto overeror, because bsf PORTA, 7 is never set.......
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top