Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] pic18f compare real time inetrrupt in UART

Status
Not open for further replies.

vilfred

Member level 1
Joined
Mar 21, 2018
Messages
37
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
368
Hi,
I'm not a good programmer, and iam new to pic world. I'm working in PIC18F65K22 to control a DC motor and stepper motor using UART at 9600bps. I've posted my code below. I need to receive and transmit a same character in UART to drive a specific function. But while simulating my code in proteus, i send a particular character and received an error value. Please correct me if iam doing any mistake in my code. Thanks


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
LIST P=18F65K22
            INCLUDE <P18F65K22.INC>
            
            
COUNTA EQU 01H
COUNTB EQU 02H
COUNTC EQU 03H    
 
            CBLOCK 0x20
            
            ENDC
            
            CONFIG WDTEN = OFF
            CONFIG MCLRE = OFF
            CONFIG XINST = OFF
            CONFIG DEBUG = OFF
            CONFIG FOSC = INTIO2
            CONFIG BOREN = ON
            CONFIG IESO = ON
        
            ORG 0x00
            
            MOVWF 0x00
            MOVWF ANSEL1
            
            MOVLW 0x66
            MOVWF OSCCON
            
            GOTO UART_INIT
 
UART_INIT       
                
                MOVLW D'12'        
                MOVWF SPBRG1        
        
                MOVLW B'00110000'  
                MOVWF PIE1
                
                MOVLW B'00110000'
                MOVWF PIR1
                
                MOVLW B'01100110'
                MOVWF TXSTA1        
        
                MOVLW B'11010000'
                MOVWF RCSTA1       
                
                BCF TRISC,6 
                BSF TRISC,7
                        
                        
MAIN            BTFSS PIR1,RCIF
                GOTO MAIN
                MOVWF RCREG1
                
                BCF RCSTA1,CREN
                BSF RCSTA1,CREN
                
                BTFSC TXSTA1,TXIF
                GOTO MAIN
                MOVWF TXREG1
 
                MOVLW 'A'
                CPFSLT RCREG1
                GOTO MAIN
                MOVF RCREG1,W
                MOVWF TXREG1
                GOTO DC1
                
                MOVLW 'B'
                CPFSLT RCREG1
                GOTO MAIN
                MOVF RCREG1,W
                MOVWF TXREG1
                GOTO SM
                
                
DC1             
                
                BCF TRISA,1
                BSF PORTA,1
                                
                MOVLW 0x00
                MOVWF TRISD
                
                BSF PORTD,0
                CALL DELAY
                BCF PORTD,1
                CALL DELAY
                
                BCF PORTA,1
                CALL DELAY
                BCF PORTD,0
                CALL DELAY
                BCF PORTA,1
                GOTO MAIN
SM              
                MOVLW 0x00
                MOVWF TRISB
                
                MOVLW B'00000001'
                MOVWF PORTB
                CALL DELAY
                MOVLW B'00000100'
                MOVWF PORTB
                CALL DELAY
                MOVLW B'00000010'
                MOVWF PORTB
                CALL DELAY
                MOVLW B'00001000'
                MOVWF PORTB
                
                GOTO MAIN
 
DELAY       
                MOVLW D'168'
                MOVWF COUNTA
                MOVLW D'24'
                MOVWF COUNTB
                MOVLW D'10'
                MOVWF COUNTC
LOOP
                DECFSZ COUNTA,1
                GOTO LOOP
                DECFSZ COUNTB,1
                GOTO LOOP
                DECFSZ COUNTC,1
                GOTO LOOP
                RETURN
 
                GOTO MAIN
                
                END

 
Last edited by a moderator:

hello,



Code:
MAIN            BTFSS PIR1,RCIF
                   GOTO MAIN
                   MOVF RCREG1 ;  //  read the register
                  ; not write to register MOVWF RCREG1

; it is better to read RCREG1 , and store it into a variable , for later treatement


Code:
   ; to do if error  RCSTA1.OERR
              ; so must test this flag 
               ; BCF RCSTA1,CREN
               ; BSF RCSTA1,CREN
                
  MAIN1:
               BTFSC TXSTA1,TXIF
                GOTO MAIN1    ; no necessary to go at the beginning !


Code:
                MOVLW 'A'
                CPFSLT RCREG1      <- value into this register could not be the same as the one read at the beginning !

...
 
Also:
wherever you use a 'bsf PORTx' or 'bcf PORTx', change the PORT to LAT. PIC18 can use PORT output instructions but it is better to write to the corresponding LAT register instead.

You seem to be using system registers to store values instead of user RAM. You should change
Code:
COUNTA EQU 01H
COUNTB EQU 02H
COUNTC EQU 03H
   
            CBLOCK 0x20
            
            ENDC
to
Code:
            CBLOCK 0x20
COUNTA
COUNTB
COUNTC
            ENDC
This lets the assembler allocate the variable addresses within the 'CBLOCK' rather than you fixing the addresses yourself.

Note that your code does not use interrupts at all and you could probably make it more versatile by using relocatable rather than absolute memory models.

Brian.
 
Thanks...I thought enabling the interrupt is enough to receive the real time input through uart terminal.

BSF INTCON,GIE ;global interrupt enable
BSF INTCON,PEIE ; peripheral interrupt enable

I got one more confusion regarding equating the real time input from uart to specific value which i used as a control to drive motor. Is the following instruction is correct for equating a real time interrupt value with control variable?


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MAIN        BTFSS PIR1,RCIF    ;checking the receiver flag
                GOTO MAIN
                MOVWF RCREG1
                MOVLW 'A'           ; load character 'A' to work register
                CPFSEQ RCREG1   ; comparing work register value with received value
                GOTO MAIN
                GOTO DC_MOTOR
 
DC_MOOTR     
                MOVLW 0x00
                MOVWF TRISD   ;setting portd as output
                
                
                BSF LATD,0    ; enable dc motor in clockwise direction
                CALL DELAY
                BCF LATD,1
                
                GOTO MAIN


sorry if made any mistake in my sentence.
 
Last edited by a moderator:

Thanks...I thought enabling the interrupt is enough to receive the real time input through uart terminal.
That is only part of the method.
Code:
MAIN        BTFSS PIR1,RCIF    ;checking the receiver flag
                GOTO MAIN
                MOVWF RCREG1
isn't using the interrupt, what it does instead is keep looping back to 'MAIN' until the interrupt bit in PIR1 is set. That means you are polling it (waiting for the bit to set before continuing) instead of triggering an interrupt.

The difference is that if you use an interrupt, instead of checking for RCIF to be set by the UART, you continue with the rest of the program and a character arriving in the UART starts a hardware process of suspending the program, saving some registers so it can resume afterwards, then jumping to a section of code called an ISR (Interrupt Service Routine) to read and process the character that arrived. When the ISR finishes, it returns to the place in code you were running. Essentially, it lets you run two programs 'simultaneously', the main code and the ISR code and the PIC switches seamlessly between them when necessary.

So you need to write an ISR, it is quite simple and should only need a few lines of code. I strongly suggest you start with the template code provided by Microchip and add your own code to it. The template already has the ISR framework in it so all you have to do is read RCREG inside it and handle the received character.

Just to warn you - because an interrupt will be triggered whenever a character arrives or if other interrupts are enabled, it is wise to keep the ISR code as short as possible. When you are in an ISR, further interrupts are disabled (there is a way of handling a second interrupt in PIC18F devices but I won't go into that here) so there is a risk of missing subsequent interrupt triggers until the ISR finishes. The best way to avoid this problem is to save the RCREG value to another variable then set a flag to tell the main program the interrupt happened. When the main program checks the flag, it knows there is new data in the saved variable and it can deal with it without blocking the ISR.

Brian.
 
your guidance drives my code in a right path thanks.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top