Forum: Mikrocontroller und Digitale Elektronik PIC Port I/O mit HiTech C


von Detlef _. (detlef_a)


Lesenswert?

Liebe Freunde des PIC,

ich programmiere einen PIC 16F1825 mit Hi-Tech C und bin auf diesem uC 
blutiger Anfänger.

Ich möchte eine rote LED an PORTC und eine grüne LED an PORTA kurz 
aufblinken lassen, der Code ist unten angehängt. Wenn ich das nur mit 
PORTC mache, blinkt die LED einmal kurz auf, dann Pause, alles gut. Auch 
alles gut, wenn ich nur PORTA anspreche: kurzes aufblinken, dann Pause.

Wenn ich beide LEDs nacheinander kurz aufblinken lassen will, blinken 
beide nicht jeweils einmal auf sondern _zweimal_.

Bin völlig ratlos. Nehme an, bei mir ex. noch grundsätzliches 
Mißverständnis über die Ports des PIC.

THX 4 help
Cheers
Detlef


int k ;

TRISA = 0;
TRISC = 0;

PORTA=0x0;
PORTC=0x0;

for(;;)
{

for(k=0;k<1000;k++) _nop();
PORTC=0xff;
for(k=0;k<1000;k++) _nop();
PORTC=0x0;

for(k=0;k<1000;k++) _nop();
PORTA=0xff;
for(k=0;k<1000;k++) _nop();
PORTA=0x0;


for(k=0;k<5*1000;k++) _nop();
}

von Willi (Gast)


Lesenswert?

High-tech-Compiler verträgt sich nicht mit low-tech-Programmierstil....
Es könnte sein, dass die high-tech-Geschichte erkennt, dass die 
Schleifen logisch nutzlos sind und dementsprechend ersatzlos eliminiert 
wird.

von Lorin J. (Gast)


Lesenswert?

Hallo

Ich möchte kurz bemerken, dass ich normalerweise mit pic16fxxx arbeite. 
Aber mir stellt sich die Frage wiso du den ganzen PORT veränderst wenn 
du auch nur ein Pin könntest?

Willi schrieb:
> High-tech-Compiler verträgt sich nicht mit low-tech-Programmierstil....
> Es könnte sein, dass die high-tech-Geschichte erkennt, dass die
> Schleifen logisch nutzlos sind und dementsprechend ersatzlos eliminiert
> wird.

Ja meine Erfahrung sagt das selbe :)

so wie ich das sehe sind diese Schleifen nur ein delay oder?
Wenn ja kannst du auch __delay_ms(x); schreiben. (für x natürlich die 
anzahl ms)


Ich bin mir nicht 100% sicher aber probier mal: volatile int k;
dann sollte der Compiler nichts mehr "wegoptimieren"


Liebe Grüsse
Lorin

von Chris (Gast)


Lesenswert?

Wo hast du denn _nop() definiert ?
Hi-Tech definiert NOP eigentlich mit NOP() bzw im Zweifelsfall
solltest du CLRWDT() benutzen.

von Erich (Gast)


Lesenswert?

Du musst die eingebauten "Delay" Funktionen benutzen,
wobei der Wert für  _XTAL_FREQ  deiner wirklichen Taktrate des uC 
entsprechen muss, damit es stimmt.



#ifndef _XTAL_FREQ
 // This definition is required to calibrate __delay_us() and 
__delay_ms()
 #define _XTAL_FREQ 500000    // benötigt für "delay"
#endif

      __delay_ms(5);

von Detlef _. (detlef_a)


Lesenswert?

Danke für die Antworten.

Die delays sind nicht das Problem, der Compiler optimiert die nicht weg. 
Das _nop() ist in einem pic.h definiert und ich weiß auch, dass 
Verzögerung auf diese Art schlechter Stil ist.

Der gepostete Code ist ein runtergekochtes Beispiel, ein ganzes Port 
setzen funktioniert nicht und ein Einzelbit setzen geht auch nicht.

Konkret:

Für die Ports kenne ich die Register TRISx, PORTx und LATx, muß ich noch 
andere bespaßen?

APFCON0/1 verstehe ich allerdings nicht, muß ich da ran? Das ist cap. 
12.1 im PIC16F1825 Datenblatt.

Wie sage ich, dass die pins general purpose i/o sind nund nicht mit 
anderen Funktionen belegt sind, welches Register ist das?

Ich hoffe da auf die PICracks.

THX
Cheers
Detlef

von Lorin J. (Gast)


Lesenswert?

Each port has three standard registers for its operation.
These registers are:
• TRISx registers (data direction)
• PORTx registers (reads the levels on the pins of
the device)
• LATx registers (output latch)
Some ports may have one or more of the following
additional registers. These registers are:
• ANSELx (analog select)
• WPUx (weak pull-up)
• INLVLx (input level control)


The ANSELA register (Register 12-6) is used to
configure the Input mode of an I/O pin to analog.
Setting the appropriate ANSELA bit high will cause all
digital reads on the pin to be read as ‘0’ and allow
analog functions on the pin to operate correctly.

ANSELx = 0xff;


bit 7-6 Unimplemented: Read as ‘0’
bit 5-0 WPUA<5:0>: Weak Pull-up Register bits
1 = Pull-up enabled
0 = Pull-up disabled

WPUx = 0x00;


bit 7-6 Unimplemented: Read as ‘0’
bit 5-0 INLVLA<5:0>: PORTA Input Level Select bits
For RA<5:0> pins, respectively
1 = ST input used for port reads and interrupt-on-change
0 = TTL input used for port reads and interrupt-on-change


Da bin ich mir nicht ganz sicher aber ich würde auf INLVLA = 0x00; 
tippen

Liebe Grüsse
Lorin

von Lorin J. (Gast)


Lesenswert?

Hier noch die Funktionen von APFCON0/1

APFCON0:

bit 7 RXDTSEL: Pin Selection bit
  For 14 Pin Devices (PIC16(L)F1825):
  0 = RX/DT function is on RC5
  1 = RX/DT function is on RA1
  For 20 Pin Devices (PIC16(L)F1829):
  0 = RX/DT function is on RB5
  1 = RX/DT function is on RC5
bit 6 SDO1SEL: Pin Selection bit
  For 14 Pin Devices (PIC16(L)F1825):
  0 = SDO1 function is on RC2
  1 = SDO1 function is on RA4
  For 20 Pin Devices (PIC16(L)F1829):
  Bit is read-only, ‘0’
  SDO1 function is always on RC7.
bit 5 SS1SEL: Pin Selection bit
  For 14 Pin Devices (PIC16(L)F1825):
  0 = SS1 function is on RC3
  1 = SS1 function is on RA3
  For 20 Pin Devices (PIC16(L)F1829):
  Bit is read-only, ‘0’
  SS1 function is always on RC6.
bit 4 Unimplemented: Read as ‘0’
bit 3 T1GSEL: Pin Selection bit
  0 = T1G function is on RA4
  1 = T1G function is on RA3
bit 2 TXCKSEL: Pin Selection bit
  For 14 Pin Devices (PIC16(L)F1825):
  0 = TX/CK function is on RC4
  1 = TX/CK function is on RA0
  For 20 Pin Devices (PIC16(L)F1829):
  0 = TX/CK function is on RB7
  1 = TX/CK function is on RC4
bit 1-0 Unimplemented: Read as ‘0’


APFCON1:

Note 1: PIC16(L)F1829 only.



Ich nehme an du kannst APFCON0 = 0x00;
und APFCON1 gibt es bei dir scheinbar gar nicht.

von Detlef _. (detlef_a)


Lesenswert?

Die Geschichte scheint ein Compiler bug gewesen zu sein. Ich habe den 
int-Counter durch zwei ineinandergeschachtelte char-Counter ersetzt, 
dann ging alles. Hatte mir auch das produzierte Assemblerfile angesehen, 
die Zählerei mit dem int wurde sehr wirr übersetzt.

Soweit, so gut erstmal. Habe dann im eigentlichen Prgramm alle ints 
durch chars umspielt und bin dann wieder in eine komische Sache 
reingelaufen.

Langer Rede kurzer Sinn: Der Hi-Tech Compiler scheint seinem Namen keine 
Ehre zu machen. Microchip scheint den ja auch für neuere Produkte 
abgeschossen zu haben, das habe ich für meinen Teil auch erstmal getan.

Frage: Gibts noch alternative C-Compiler für den PIC16 , der Microchip 
eigene geht ja wohl erst ab PIC18? Habe eigentlich keine Lust, PIC 
Assembler zu lernen.

Hat der Hi-Tech C Compiler in der PIC-Community einen schlechten Ruf, 
gibt es Strategien, die Macken zu umschiffen?

Danke, PICracks!
Cheers
Detlef

von Meister E. (edson)


Lesenswert?

Detlef _a schrieb:
> Frage: Gibts noch alternative C-Compiler für den PIC16 , der Microchip
> eigene geht ja wohl erst ab PIC18?

Dann musst du zu MPLABX wechseln, der XC8 kennt alle 8-Bit Familien von 
Microchip.

von Jens M. (Gast)


Lesenswert?

Detlef _a schrieb:
> Frage: Gibts noch alternative C-Compiler für den PIC16 , der Microchip
> eigene geht ja wohl erst ab PIC18? Habe eigentlich keine Lust, PIC
> Assembler zu lernen.

Das ganze MPLAB zeugs war und ist ein Krampf, aber er ist nun mal der 
"offiziellste".

>
> Hat der Hi-Tech C Compiler in der PIC-Community einen schlechten Ruf,

nein.

> gibt es Strategien, die Macken zu umschiffen?

Es gibt nichts anders ausser Foren lesen und sich durchbeißen

Für meine Zwecke habe ich den hier

http://www.mikroe.com/mikroc/pic/

ausgewählt.  Die Demo ist recht großzügig.

von Klaus (Gast)


Lesenswert?

Detlef _a schrieb:
> Die Geschichte scheint ein Compiler bug gewesen zu sein. Ich habe den
> int-Counter durch zwei ineinandergeschachtelte char-Counter ersetzt,
> dann ging alles.

Na das ist ja krass. Ein C-Compiler der keine ints kann. Wahrscheinlich 
braucht man auf so kleinen Prozessoren eigentlich keine ints, deshalb 
ist das noch keinem aufgefallen.

Meister Eder schrieb:
> Dann musst du zu MPLABX wechseln, der XC8 kennt alle 8-Bit Familien von
> Microchip.

Und den HI-Tech Compiler haben die von Microchip auch noch gekauft und 
nennen den jetzt XC8.

MfG Klaus

von Meister E. (edson)


Lesenswert?

Klaus schrieb:
> Na das ist ja krass. Ein C-Compiler der keine ints kann. Wahrscheinlich
> braucht man auf so kleinen Prozessoren eigentlich keine ints, deshalb
> ist das noch keinem aufgefallen.

Compiler-Bug, ja klar.

> Meister Eder schrieb:
>> Dann musst du zu MPLABX wechseln, der XC8 kennt alle 8-Bit Familien von
>> Microchip.
>
> Und den HI-Tech Compiler haben die von Microchip auch noch gekauft und
> nennen den jetzt XC8.

Woher nimmst du die "Info", dass der XC8 ein zusammengestoppelter 
Hi-Tech ist?

von Chris (Gast)


Lesenswert?

Dann zeig mal den Code (compilierbar) sowie den produzierten ASM.
Ich möchte den Compiler Bug sehen. Ansonsten hat der Compiler einen sehr
guten Ruf.

von Klaus (Gast)


Lesenswert?

Meister Eder schrieb:
> Woher nimmst du die "Info", dass der XC8 ein zusammengestoppelter
> Hi-Tech ist?

Aus einer Plichtmitteilung für die Börse:

> Microchip Technology Acquires HI-TECH Software
> CHANDLER, Ariz., March 9, 2009 [NASDAQ: MCHP] — Microchip Technology
> Inc., a leading provider of microcontroller and analog semiconductors,
> today announced it has acquired HI-TECH Software, a world-class
> provider of development tools for embedded systems based in
> Brisbane, Australia.

MfG Klaus

von Meister E. (edson)


Lesenswert?

Klaus schrieb:
> Aus einer Plichtmitteilung für die Börse:

War mir schon bekannt, dass Microchip Hi-Tech aufgekauft hat. Die 
Information, dass der XC8 dem Hi-Tech Compiler entspräche, steckt da 
aber nicht drin. Ist ja auch nicht der Fall, einfach mal in die 
Handbücher schauen.

von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

>>Dann zeig mal den Code (compilierbar) sowie den produzierten ASM.
>>Ich möchte den Compiler Bug sehen. Ansonsten hat der Compiler einen sehr
>>guten Ruf.

Die funktionierenden Versionen habe ich angehängt.
Wenn ich
for(c1=0;c1<8;c1++) for(c2=0;c2<255;c2++) _nop();
durch
for(k=0;k<2000;k++) _nop();
(k ist integer) ersetzt habe, ging es nicht mehr. Den Assembler verstehe 
ich nicht richtig, kann also nicht sagen, wo es hakt.

Ich weiß, dass man gerne eigene Fehleistungen und Inkompetenzen auf 
einen Compilerfehler abschieben will. Aber das will ich nicht, obwohl 
ich vor langer Zeit schon mal selbständig einen bekanten  bug im gcc 
gefunden habe: Beitrag "Frage zur Parameterübergabe im Stack"  :-)))

Ich kuck mir den XC8 an, danke für den tip.
Nen PIC frontend für den gcc gibts nicht, nee??

Cheers
Detlef

von Chris (Gast)


Lesenswert?

Kannst du auch bitte den Code für den ASM Code für die nicht 
funktionierende Version posten. Bei mir geben die char und int versionen 
dasselbe Ergebnis
im Simulator aus, benutze aber eine etwas ältere Version des Hitech C 
Compiler.

for(k=0;k<2000;k++) _nop(); ist auf Pic sehr ineffizient.

k=2000; do _nop(); while(--k); ist die optimierte Version.

Bei unsigend char wird do zu einem Label und das while(--k) zu
decfsz _k
goto   do_lbl

ob der Compiler

for(k=2000;--k;) ist besser, generiert im Vergleich aber suboptimalen
Code, da es das for in eine while Schleife umwandelt, welches 
zusätzliche
Gotos braucht.

Es gab mal ein GCC Frontend, die Codegröße war fürchterlich.
SDCC soll verwendbar sein.

von Meister E. (edson)


Lesenswert?

Detlef _a schrieb:
> Ich kuck mir den XC8 an, danke für den tip.
> Nen PIC frontend für den gcc gibts nicht, nee??

Gern geschehen. Es gab wohl mal eins, denke aber nicht dass alle und vor 
allem die neueren PICs dort unterstützt werden. Ich würde auf jeden Fall 
empfehlen jetzt die Microchip-Tools zu verwenden, da in Form des XC8 
einiges konsolidiert wurde.

von Chris (Gast)


Lesenswert?


von Klaus (Gast)


Lesenswert?

Meister Eder schrieb:
> Ist ja auch nicht der Fall, einfach mal in die
> Handbücher schauen.

Na denn:

> 1.2. Previous Versions
> The previous version MPLAB XC8 C compiler was 1.11, released October 2012.
> The last released version of HI-TECH C Compiler for PIC10/12/16 MCUs was
> 9.83, released in September 2011. The previous HI-TECH C Compiler for
> PIC18 MCUs was 9.80, released in October 2011.

Der HI-TECH Compiler ist also eine ältere Version des XC8.

MfG Klaus

von Detlef _. (detlef_a)


Lesenswert?

>>>>> http://www.microchip.com/forums/m668751.aspx XC8

Ja, diese branch-Orgien, die hier beklagt werden, sind auch in meinem 
asm-File zu sehen. Nicht schön.

>>Für meine Zwecke habe ich den hier
>>http://www.mikroe.com/mikroc/pic/
>>ausgewählt.

Vielen Dank für den Hinweis, das Ding habe ich mal ausprobiert, macht 
nen guten Eindruck, hinten mal produzierten Assembler Code angehängt. 
Alles dran, was man braucht: Interrupts und asm-Instruktionen, die auf 
C-Variablen zugreifen können.

Mit dem Ding mach ich mal weiter, mal kucken ob ich damit durchkomme.

THX, PICracks !

Cheers
Detlef



;MyProject1.c,212 ::     for(k=0;k<2000;k++) asm nop;
  CLRF       R1+0
  CLRF       R1+1
L_main9:
  MOVLW      128
  XORWF      R1+1, 0
  MOVWF      R0
  MOVLW      128
  XORLW      7
  SUBWF      R0, 0
  BTFSS      STATUS+0, 2
  GOTO       L__main35
  MOVLW      208
  SUBWF      R1+0, 0
L__main35:
  BTFSC      STATUS+0, 0
  GOTO       L_main10
  NOP
  INCF       R1+0, 1
  BTFSC      STATUS+0, 2
  INCF       R1+1, 1
  GOTO       L_main9

von Meister E. (edson)


Lesenswert?

Klaus schrieb:
> Der HI-TECH Compiler ist also eine ältere Version des XC8.

"Der HI-Tech Compiler" waren zwei Softwarepakete. Unter XC8 gibt es 
nur noch einen Entwicklungszweig, für den jetzt ein einziger Hersteller 
verantwortlich ist. Für mich macht das einen wesentlichen Unterschied, 
weshalb ich deine Behauptung "XC8 ist der alte Hi-Tech" so nicht stehen 
lassen wollte.

von Chris (Gast)


Lesenswert?

Es scheint, als meint der Compiler, die Variable ist signed int sowie
signed char .
Teste mal ein
#define int short

ob das einen Unterschied macht, int war bein Hitech immer schon zu 
vermeiden.

Ansonten:
PORTA=LATA | (1<<5);
Dies ist schlecht, optimiert generiert es mindestens 3 Instruktionen und
zerstört W sowie Satus Register,
richtig wäre folgende Zeile, welche eine Instruktion macht und W + 
Status
bleibt erhalten.
LATA |= (1<<5);

Auch anstelle von PORTA=0x0;
sollte man LATA=0; verwenden.

von Erich (Gast)


Lesenswert?

>   LATA |= (1<<5);

Ja, so isses richtig.
Aber ein "W" Register gibt es nicht in Programmiersprache C.
Deshalb ist es auch wurschtpiepegal wie das der Compiler hinkriegt.

Die Feinheiten des uC muss man schon kennen.
Denn ob asm oder C , immer gilt das GIGO Prinzip.

(was in der "en" Version von Wikipedia besser erklärt ist als bei "de").

Gruss

von Detlef _. (detlef_a)


Lesenswert?

Hallo liebe Programmierer des PIC mit 'C',

diesen C-Compiler habe ich jetzt ausführlicher benutzt mit nem 300 
Zeilen Programm, das die hardware eines 16F1825 bespaßt:

http://www.mikroe.com/mikroc/pic/
(Danke, Jens Martin für den Tip.)

Der funktioniert wirklich gut, schnörkelloses Teil ohne Gedöns; tut, was 
er soll: C übersetzen. Assembler sieht gut aus, zu optimieren gibts bei 
dem Programm nix  (das tu ich selber ;-) ). Das kann der Compiler aber 
auch nicht so gut, glaube ich .

Ich bin jedenfalls zufrieden und freue mich, dass ich mir die 
Programmierung in Assembler im 'goto-style' und mit 'skip if carry set' 
nicht reinziehen muß.

gute Nacht
Cheers
Detlef

von Didi S. (kokisan2000)


Lesenswert?

Ich habe in den letzten Jahren so ca. 100 Projekte mit den HiTech 
Compilern stabil auf den Weg gebracht. Die australischen Entwickler 
haben da wirklich sehr gute Arbeit geleistet und der Code war 
hocheffizient. Die HiTech Compiler waren die letzten Jahre absoluter 
Klassenprimus! Das war Microchip wohl leider ein Dorn im Auge da ihr 
eigener Compiler in einer niedrigeren Performance Klasse spielte. Kurzum 
wurde die Firma HiTech übernommen und die PICC Serie eingestampft. Die 
letzte Version 9.83 ist ein einziger Krampf, da der Compiler instabil 
läuft und extrem viele Fehler hat. Für mich wirkt es, als ob die 
Entwickler bei Hitech die Übernahme sabotiert haben. Viele Funktionen, 
die über viele Jahre gut funktionierten, machen bei der 9.83 Version 
plötzlich schlapp, so zum Beispiele die Makros, um interne EEPROMs zu 
beschreiben.

Wohl oder übel habe ich auf die hauseigenen Compiler von Microchip 
gewechselt. Die Performance ist leider schlechter und der Syntax nicht 
ganz kompatibel. So wie das aussieht, wurden die Vorteile von den HiTech 
Compilern zumindest bisher nicht in den XC8 eingebaut. Vielleicht kommt 
das ja noch, vielleicht hat Microchip aber auch nur einen lästigen 
Konkurrenten von der Platte gestoßen ;-)

Gruß
kokisan

von Detlef _. (detlef_a)


Lesenswert?

Ich hatte nach dem Ruf des 'HiTech'-Compilers gefragt, der sei gut, 
wurde gesagt.

Obige Einlassung klingt jetzt ganz anders, ich hatte auch 9.83 benutzt.

Das Ding ist ne Krücke, absolut unbrauchbar. MPlab benutze ich zum 
Programmieren der PICs, das scheint auch gut vermackelt zu sein.

Da bin ich mit winavr und atmel studio für AVR Anderes gewohnt, das 
funktioniert doch wesentlich geschmeidiger.

Insbesondere ist mir unverständlich, dass microchip für die schlappen 49 
oder 47 Maschinenbefehle des PIC kein gutes gcc frontend basteln kann.

Naja.
Wieder was beigelernt.

Nochmal gute Nacht
Cheers
Detlef

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.