Sida 1 av 1

Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 10:41:24
av jfri
Har ett fungerande program för en 16F690 som skriver ut Hello world till ett PC terminalprogram vis PC serieporten. Kör det i Low Pin count demokortet. Samma program vägrar att fungera på en 16F676. Här skrivs bara skräptecken ut. Använder terminalprogrammet Realterm:serial capture and binary terminal med samma inställningar i båda fallen 9600 baud 8N1. Och med 676 indikeras error i Realterm förutom att tecken mottages. Enligt databladen är båda default klockfrekvenserna 4 MHz. En simulering i MPLAB sim ger samma resultat på TX pinnen för båda programmen. Så jag förstår ingenting. Samma hårdvara samma programdelar bara specifika PIC skiljer. Både det på 16F690 fungerande programmet och den icke fungerande 16F676 implementeringen listas nedan

Kod: Markera allt

 include <p16f690.inc>
    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
BAUD		EQU	.39
BAUD1		EQU	.30
BAUDX		EQU	.29
BAUDY		EQU	.30
BAUDS		EQU	.32

	cblock	0x20
XmtReg
Count
DlyCnt
offset
W_temp
    endc

 org 0
 
main
 	BCF   STATUS,RP0 					;Bank 0
	BCF   STATUS,RP1 					;
	CLRF  PORTC 						;Init PORTC
	BSF   STATUS,RP1						;BANK 2
	CLRF  ANSEL
	BSF   STATUS,RP0 					;Bank 1
	BCF   STATUS,RP1
	MOVLW b'11010000'					;Set RC5  as output and all DS to output
	MOVWF TRISC 						;
	BCF   STATUS,RP0 					;Bank 0
	bsf	  PORTC,5
	clrf  offset
loop
	Call  HelloWorld
	goto  loop

HelloWorld	
nextchar
	movlw HIGH Text
	movwf PCLATH
	movf  offset,0
	Call  Text
	Call  Printbyte
	incf  offset,1
	movf  offset,0
	sublw .13
	btfsc STATUS,Z
	goto  break
	goto  nextchar
break
	clrf  offset
	return

Printbyte
	movwf W_temp
	movwf XmtReg
Xmtr
	movlw 8
	movwf Count
	bcf	  PORTC,5
	Call  Delay1	
X_next
	bcf   STATUS,C
	rrf	  XmtReg,1
	btfsc STATUS,C
    	bsf   PORTC,5
	btfss STATUS,C
	bcf	  PORTC,5
    	Call  DelayX
    	Decfsz Count,1
    	goto  X_next
X_stop
	bsf	  PORTC,5
	Call  DelayS
	movf  W_temp,0
	return
DelayS
	movlw BAUDS
    	goto  SAVE
DelayY
	movlw BAUDY
	goto  SAVE
DelayX
	movlw BAUDX
	goto  SAVE
Delay1
	movlw BAUD1
	goto  SAVE
Delay
	movwf BAUD
SAVE
	movwf DlyCnt
redo_1
	decfsz DlyCnt,1
	goto   redo_1
	return

 org 0x300
 Text
	addwf	PCL,1
	retlw	'H'
	retlw	'e'
	retlw	'l'
	retlw	'l'
	retlw	'o'
	retlw	' '
	retlw	'W'
	retlw	'o'
	retlw	'r'
	retlw	'l'
	retlw	'd'
	retlw	'\r'
	retlw   	'\n'

 end

Kod: Markera allt

include <p16f676.inc>
   __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF  & _BODEN_OFF )
BAUD		EQU	.39
BAUD1		EQU	.30
BAUDX		EQU	.29
BAUDY		EQU	.30
BAUDS		EQU	.32

	cblock	0x20
XmtReg
Count
DlyCnt
offset
W_temp
    endc
  
   org 0
   
main
	bcf 		STATUS,RP0 						;Bank 0
	clrf 		PORTC 								;Init PORTC
	bsf 		STATUS,RP0 						;Bank 1
	clrf 		ANSEL 								;digital I/O
	MOVLW b'11010000'						;Set RC5  as output and all DS to output
	movwf 	TRISC 								
	bcf 		STATUS,RP0 						;Bank 0
	bsf	  	PORTC,5
	clrf  	offset
loop
	Call  	HelloWorld
	goto  	loop

HelloWorld
nextchar
	movlw HIGH Text
	movwf PCLATH
	movf  offset,0
	Call  Text
	Call  Printbyte
	incf  offset,1
	movf  offset,0
	sublw .13
	btfsc STATUS,Z
	goto  break
	goto  nextchar
break
	clrf  offset
	return
Printbyte
	movwf W_temp
	movwf XmtReg
Xmtr
	movlw 8
	movwf Count
	bcf	  PORTC,5
	Call  Delay1	
X_next
	bcf   STATUS,C
	rrf	  XmtReg,1
	btfsc STATUS,C
    	bsf   PORTC,5
	btfss STATUS,C
	bcf	  PORTC,5
    	Call  DelayX
    	Decfsz Count,1
    	goto  X_next
X_stop
	bsf	  PORTC,5
	Call  DelayS
	movf  W_temp,0
	return
DelayS
	movlw BAUDS
    	goto  SAVE
DelayY
	movlw BAUDY
	goto  SAVE
DelayX
	movlw BAUDX
	goto  SAVE
Delay1
	movlw BAUD1
	goto  SAVE
Delay
	movwf BAUD
SAVE
	movwf DlyCnt
redo_1
	decfsz DlyCnt,1
	goto   redo_1
	return

 org 0x300
 
 Text
	addwf	PCL,1
	retlw	'H'
	retlw	'e'
	retlw	'l'
	retlw	'l'
	retlw	'o'
	retlw	' '
	retlw	'W'
	retlw	'o'
	retlw	'r'
	retlw	'l'
	retlw	'd'
	retlw	'\r'
	retlw   	'\n'

 end
	

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 10:58:01
av sodjan
> Samma program vägrar att fungera på en 16F676.

Och varför skulle det fungera ?
RTFM !

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 11:10:38
av jfri
Jag har alltså anpassat det till 16F676 med avseende på att 16F690 har fyra minnes bankar jämfört med två för 16F676.
Include filerna är givetvis specifika för resp PIC.
RC5 kan och konfigureras som utgång i båda fall (inbyggd USART i 16F690 är inte vad som används). Dessa rutiner har en gång fungerat på en 16F84.
Så om klockfrekvensen i båda fall är 4 MHz varför borde det inte fungera?

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 11:23:25
av sodjan
> med avseende på att 16F690 har fyra minnes bankar jämfört med två för 16F676.

Kör med BANKSEL så behöver du inte anpassa någonting alls när det gäller just det.
BANKSEL genererar rätt BCF/BSF styrt av det faktiska antalet banker i alla lägen.
Det finns *aldrig* någon anledning att själv hålla på och försöka få till BCF/BSF
mot bank-bitarna rätt. Möjligheterna till att göra fel är väldigt stora.

> Så om klockfrekvensen i båda fall är 4 MHz varför borde det inte fungera?

Du har inte läst databladen och jämfört processorerna ordentligt. Har du
t.ex kollat hur den interna oscillatorn fungerar i båda processorerna ? Se kapitel
9.2.5.1 i databladet för 16F676. Det är en möjlig orsak till det fenomen som du ser.

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 13:11:49
av jfri
Ditt förslag att kalibrera oscillatorn fungerade.

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 13:35:03
av sodjan
Fint ! :-)

Och det var igentligen inte *mitt* förslag, det kom från databladet...

Har du kollat upp BANKSEL ?

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 14:42:54
av jfri
Min kod är nu modifierad med BANKSEL enligt nedan. En undran är dock om man nu inte lätt lägger in onödiga instruktioner för att välja en bank som redan är vald? T.ex har jag ingen BANKSEL före initiering av TRISC eftersom BANKSEL ANSEL väljer Bank1. Om jag lagt till BANKSEL TRISC före skrivning till TRISC hade då inte koden gjorts några instruktioner större än nödvändigt och en programrad större?

Kod: Markera allt

main
	BANKSEL	OSCCAL
	call 			3FFh 				;Get the cal value
	movwf 		OSCCAL 					;Calibrate
	
	BANKSEL	PORTC
	clrf 			PORTC 				;Init PORTC
	BANKSEL	ANSEL
	clrf 			ANSEL 				;digital I/O
	MOVLW	 b'11000000'					;Set RC5  as output and all DS to output
	movwf 		             TRISC 								
	BANKSEL	PORTC
	bsf	  		PORTC,5
	bsf			PORTC,4    ;tänder en LED	
	clrf  		offset
loop
	Call  		HelloWorld
	btfsc		PORTA,5						;Poll switch på RA5
	goto			$-1
	goto  		loop

Re: Printrutin för 16F690 kan inte fås fungera på 16F676

Postat: 1 december 2010, 16:20:04
av sodjan
Du behöver inte lägga till BANKSEL om du är *helt säker* på att det inte behövs.
På samma sätt som att du inte behöver göra BCF/BSF mot RP0/RP1 om du
är helt säker på att det inte behövs.

Fördelen med BANKSEL är att du inte behöver bry dig och du behöver inte slå
upp i vilken bank som det ena eller det andra registret ligger, det sköter BANKSEL.

Du behöver alltå inte *veta* att ANSEL och TRISC ligger i samma bank !
Det är igentligen helt ointressant och oviktigt.

> Om jag lagt till BANKSEL TRISC före skrivning till TRISC hade då inte koden gjorts
> några instruktioner större än nödvändigt och en programrad större?

Och exakt *vad* har det för betydelse ? Ingen alls, speciellt inte i initieringskoden
som i alla fall bara körs en gång varje gång spänningen slås på...

Under utveckling/felsökning så är det knappast någon nackdel att ha för många
BANKSEL. Man kan trimma det efteråt när allt fungerar, om det alls behövs alltså.

Det finns teknik för att automatisera det hela så att MPASM även håller reda på
vilken bank som för tillfället är vald och enbart genererar kod *om det behövs*.
Det är dock en hel del mer komplext. T.ex Olin Lathrops utvecklingsmiljö för PIC
assembler fungerer så. Om du är intresserad så kan du söka efter "Macro DBANKIF"
i denna fil : http://www.embedinc.com/pic/std.ins.aspic.htm.

Kod: Markera allt

;********************
;
;   Macro DBANKIF <adr>
;
;   Set the register bank for direct access to address ADR.  This macro
;   sets the RP0, RP1 bits of STATUS appropriately.  The bank bits are
;   not set if they are assumed to already be set correctly as indicated
;   by the assembler variable CURRDB.  CURRDB is updated to the new
;   setting.
;
;   On 18 family processors, this macro sets BSR.  No code is emitted
;   and the bank setting is not altered if ADR is within the access bank,
;   and can therefore be accessed regardless of the BSR setting.
;
dbankif  macro   adr
         local   newbank, ii

newbank  set     bankof(adr) ;find 0-N desired bank number

;*****
;
...
...
;*****
;
;   16 family devices.
;
  if fam_16
    if nregbanks <= 1        ;this processor only has one register bank ?
         exitm
      endif
ii       set     (adr) & h'7F' ;make address offset within bank

    if (ii >= commregs_first) && (ii <= commregs_last) ;in unbanked region ?
         exitm
      endif

    if nregbanks > 1         ;bank bit 0 is meaningful ?
      if (currdb < 0) || (currdb > 3) || ((currdb & 1) != (newbank & 1)) ;need update ?
        if newbank & 1
         bsf     status, rp0
          else
         bcf     status, rp0
          endif
        endif
      endif

    if nregbanks > 2         ;bank bit 1 is meaningful ?
      if (currdb < 0) || (currdb > 3) || ((currdb & 2) != (newbank & 2)) ;need update ?
        if newbank & 2
         bsf     status, rp1
          else
         bcf     status, rp1
          endif
        endif
      endif

currdb   set     newbank     ;update current bank assumption
         exitm
    endif                    ;end of 16Cxxx case

;*****
...
...

         endm
;