WVProfessor said:Is anyone around? Is this the only thread this month?
I need help with a PIC16F88 usart firmware in receive mode.
I got the usart to transmit easily (compared to this problem).
I am having trouble with the usart receiver. Then when that works I will try the I2C circuit to talk to a flash eeprom.
I wrote some code that fails.
Those instructions might be a bit confusing. To clarify: Before pasting your code, click the # icon in the menu above the reply text window. Then paste.kchriste said:Use the code tags by highlighting your code and clicking the # icon in the reply window. This will preserve the code formatting making it easier for us to read.
EDIT: This morning I pulled out my Blueroom **broken link removed** and wrote a RS232 receive routine to go with the init and transmit routines already in the code below. Init, transmit and receive routines are in bold blue. It's tested and works fine at 9600-8-N-1.I need help with a PIC16F88 usart firmware in receive mode. I got the usart to transmit easily (compared to this problem). I am having trouble with the usart receiver.
list p=16F88
include <p16f88.inc>
__CONFIG _CONFIG1,_INTRC_IO & _WDT_OFF & _LVP_OFF & _MCLR_ON & _BODEN_OFF
ERRORLEVEL 0, -302
cblock 0x20
d1,d2,d3,dec1,dec2,count,num
endc
org 0x0000
goto init
text addwf PCL,F
retlw 'F'
retlw 'i'
retlw 'r'
retlw 'e'
retlw 'f'
retlw 'l'
retlw 'y'
retlw ' '
retlw '1'
retlw '6'
retlw 'F'
retlw '8'
retlw '8'
retlw 0x0d
retlw 0x0a
retlw 0x00
init
banksel OSCCON ;bank 1
movlw b'01110010' ;internal 8mhz osc
movwf OSCCON
stable btfss OSCCON,IOFS ;oscillator stable?
goto stable ;no, wait
movlw b'10111110'
movwf TRISA
movlw b'00100100' ;set portb for serial I/O
movwf TRISB
clrf ANSEL ;all digital input
banksel PORTA ;bank 0
clrf count
call rs_init
main movf count,W
call text
andlw 0xff
next_ch btfsc STATUS,Z
goto recv
call rs_send
incf count,F
goto main
recv call receive ;get a byte
movwf num
btfss num,5
goto recv
red1 movlw b'01000000'
movwf PORTA
call delay
green1 movlw b'00000001'
movwf PORTA
call delay
clrf count
goto main
[B][COLOR="Blue"];Sends byte in W to RS232
rs_send movwf TXREG
banksel TRISA ;bank 1
sdloop btfss TXSTA,TRMT
goto sdloop
banksel PORTA ;bank 0
return
;* Wait for a char from RS232 - return in W
receive btfss PIR1,RCIF ;wait for a byte from RS232
goto receive
movf RCREG,W ;return received byte in W
return
rs_init
banksel TRISB ;bank 1
movlw .12 ;set for 9600 baud @ 8MHz clock
movwf SPBRG
bcf TXSTA,BRGH ;clear Baud Rate Select Bit (low speed)
bcf TXSTA,SYNC ;asynchronous mode
bsf TXSTA,TXEN ;transmit enable
banksel PORTA ;bank 0
bsf RCSTA,SPEN ;serial port enable
nop
bsf RCSTA,CREN ;enable receive
return[/COLOR][/B]
delay movlw 0xff
movwf d1
movlw 0x80
movwf d2
delay_0 decfsz d1, f
goto $+2
decfsz d2, f
goto delay_0
return
end
LIST p=16F88
ERRORLEVEL -302
__CONFIG H'2007', B'11111100110000' ; 3F30H the _CONFIG 1 directive.
__CONFIG H'2008', B'00000000000011' ; 0003H
; Storage
CBLOCK 20h ; bank 0 storage
tick ; delay counter
char ; char to transmit
bitctr ; bit counter
ENDC
CBLOCK 0A0h ; bank 1 storage
GenCount ; generic counter/temp register
Mem_Loc_high ; EEPROM high memory address
Mem_Loc_low ; EEPROM low memory address
Data_Buf ; EEPROM data buffer
OutputByte ; EEPROM output byte
flags ; flag bit register
inx ; message index
ENDC
; Defines
#define SDA 86h,2 ; SDA = data = RB2
#define SCL 86h,1 ; SCL = clock = RB1
#define BANK0 BCF 3,5 ; Select bank 0
#define BANK1 BSF 3,5 ; Select bank 1
;Equates
status EQU 03h ; status register (duplicated all banks)
PORTA EQU 05h ; port A register
PORTB EQU 06h ; port B register
PIR1 EQU 0Ch ; flags
sspcon EQU 14h ;*I2C control
RCSTA EQU 18h ; in bank0
TXREG EQU 19h ; Transmit data
RCREG EQU 1AH ; Receive data
adcon0 EQU 1Fh ;*A/D channel control
TRISA EQU 85h ; data direction A
TRISB EQU 86h ; data direction B
INTCON EQU 0Bh ;*Interrupt control
OSCON EQU 8Fh ; OSCCON controls clock speed
OSCTUNE EQU 90h ; Frequency control
TXSTA EQU 98h ; in bank1
SPBRG EQU 99h ; in bank1
ANSEL EQU 9Bh ; a/d line property
adcon1 EQU 9Fh ;*A/D format control
c EQU 0 ; carry bit
z EQU 2 ; zero bit
rp0 EQU 5 ; 0,1 bank select bit
rp1 EQU 6 ; 2,3 bank select bit
pcl EQU 2 ; program counter low byte
WRITE EQU 0A0h ; EEPROM write command
READ EQU 0A1h ; EEPROM read command
xmit EQU 0 ; RA0 is COM1 transmit pin
NULL EQU 0 ; null byte, message terminator
EOF EQU 0 ; also using 0 as end of file here
CR EQU d'13' ; carriage return
LF EQU d'10' ; line feed
;*******
; Main *
;*******
ORG 0000h
Start BCF status,rp1 ; banks 0 & 1 only
BANK0
kilint bcf INTCON,7 ;*turn gie off
btfsc INTCON,7 ;*MicroChip recommends this check!
goto kilint ;*!!! GOTCHA !!! without this check
;*you are not sure gie is cleared!
clrf sspcon ;*I2C control
clrf 0Ch ;*pir1 clear peripheral flags
clrf 0Dh ;*pir2 all of them
clrf PORTA ;*clear all i/o registers...
clrf PORTB
movlw 00h ;*set all i/o as digital. no analog.
movwf adcon0
BANK1
clrf 8Ch ;*pie1 disable peripheral interrupts
clrf 8Dh ;*pie2 all of them
movlw b'10001111' ;*set right justified
movwf adcon1
MOVLW 24h ;set portb direction for i/o pins
MOVWF TRISB ;*0=output 1=input
;* rB5 output _uart_TX
;*!!! rB5 output _uart_tx. Actually an output,
;*!!! BUT for UART use rB5 MUST be programmed
;*!!! as an INPUT! (How wonderfully counter-intuitive!)
MOVLW 0x43
MOVWF 81h ;*Option register p18
CLRF 8Bh ;*intcon no interrupts used.
MOVLW 0x26 ;was 04 set BRGH clear SYNC
MOVWF TXSTA
MOVLW 0x19 ;Set SPBRG to 25d=19h d'25' or .25
MOVWF SPBRG
MOVLW 60h ; speed up clock 0110 0000=60h
MOVWF OSCON ; OSCCON= H'8F' makes 4MHz
MOVLW 01h ; speed up clock 00 0001 =0.00375
MOVWF OSCTUNE ; OSCTUNE=90h
BANK0
MOVLW 0x43 ; A
MOVWF char ; is in BANK0
; CLRF PORTA ; Why?
; CLRF ANSEL ; ANSEL is at 9B default 1 is analog
MOVLW 90h ;Set SPEN and set CREN in RCSTA
MOVWF RCSTA
movf RCREG,w ;*clear uart receiver
movf RCREG,w ;* including fifo
movf RCREG,w ;* which is three deep.
movlw 0 ;*any character will do.
movwf TXREG ;*send out dummy character
;* to get transmit flag valid!
LOOP CALL RX
CALL TX
GOTO LOOP
;******************************************
; My replacement for RecvPC is RX *
; Received character is put in char. *
;******************************************
RX BANK0
BTFSC RCSTA,1 ; OERR is overrun error
CALL err ; error routine
BTFSC RCSTA,2 ; FERR is framing error ignore
CALL err
BTFSS PIR1,5 ; Test RCIF to see if a word is in.
XXX GOTO RX ; 1 means full=received
MOVF RCREG,w ; Get receive data 0 goes to w, 1 goes to f
MOVWF char
RETURN
err BCF RCSTA,4 ;clear CREN in RCSTA
movf RCREG,w ;flush fifo
movf RCREG,w ; all three elements.
movf RCREG,w
BSF RCSTA,4 ; set CREN in RCSTA
RETURN
;******************************************
; My replacement for SendPC is TX *
; The ASCII term to transmit is in char *
; 4MHz and 9.6 means SPBRG = 25. *
; No interrupts so check every millisecond if max speed *
; Send a character to the PC com port *
;******************************************
TX BANK0
BTFSS PIR1,4 ;check the TXIF bit in PIR1 (1 means empty)
GOTO $-1
MOVF char,w ; get char
; MOVLW 0X41 It sends the letter A just fine when this is swapped in.
MOVWF TXREG ; Put char in TXREG
RETURN ; wait 1 clock before checking PIR1
END
WVProfessor said:If you add this line:Code:LIST p=16F88 ERRORLEVEL -302 __CONFIG H'2007', B'11111100110000' ; 3F30H the _CONFIG 1 directive. __CONFIG H'2008', B'00000000000011' ; 0003H
just below your LIST directive, you don't need all this stuffCode:include <p16f88.inc>
Code:;Equates status EQU 03h ; status register (duplicated all banks) PORTA EQU 05h ; port A register PORTB EQU 06h ; port B register PIR1 EQU 0Ch ; flags sspcon EQU 14h ;*I2C control RCSTA EQU 18h ; in bank0 TXREG EQU 19h ; Transmit data RCREG EQU 1AH ; Receive data adcon0 EQU 1Fh ;*A/D channel control TRISA EQU 85h ; data direction A TRISB EQU 86h ; data direction B INTCON EQU 0Bh ;*Interrupt control OSCON EQU 8Fh ; OSCCON controls clock speed OSCTUNE EQU 90h ; Frequency control TXSTA EQU 98h ; in bank1 SPBRG EQU 99h ; in bank1 ANSEL EQU 9Bh ; a/d line property adcon1 EQU 9Fh ;*A/D format control
You can use the banksel directive to change this:
to this:Code:ORG 0000h Start BCF status,rp1 ; banks 0 & 1 only
Code:ORG 0000h Start banksel PORTA ;bank 0 [COLOR="Red"]or[/COLOR] banksel TRISA ;bank 1 [COLOR="Red"]and so on...[/COLOR]
Include files come with MPLAB. Navigate to (typically) c:\program files\microchip\mpasm suite, open the p16f88.inc file and have a look (there's an include file for every model of PIC - use the appropriate one for your PIC). Get in the habit of using those equate symbols (they match the ones you see in the datasheet) instead of the actual hex numbers in your code. Makes the code much more readable and less prone to errors. You'll spend much less time trying to remember what the numbers are and be able to tell at a glance what registers you're manipulating.WVProfessor said:Wow, this is almost real time.
Where can I get the file <p16f88.inc>?
I looked all over the Microchip site.
WVProfessor said:The MPLAB/MPASM stuff requires a modern computer like an XP machine. I have only a Pentium II.
WVProfessor said:The MPLAB/MPASM stuff requires a modern computer like an XP machine. I have only a Pentium II.
Computers are cheap these days. For $300ish you can have a new "package" machine that, while not any kind of speed demon by today's standards, is perfectly capable of running just about anything you can throw at it.WVProfessor said:The MPLAB/MPASM stuff requires a modern computer like an XP machine. I have only a Pentium II.
WVProfessor said:I think the I2C hardware in the PIC16F88 can't work as master.
Nigel Goodwin said:No need for it to, I2C master is simple in software - you only need hardware support for slave.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?