Ich habe ein ziemlich seltsames Problem mit XC8 auf einem PIC18F27K40-Mikrocontroller. Auf einem PIC16F1778 funktioniert es . Ich habe definiert:
void uart_putch(unsigned char byte) {
while (!PIR3bits.TX1IF);
TX1REG = byte;
}
Wenn ich in meiner main
Schleife anrufe uart_putch('a');
, funktioniert das gut. Wenn ich jedoch definiere const char c = 'a';
und aufrufe uart_putch(c);
, funktioniert es nicht. Es druckt etwas, wenn auch kein a
- ich denke, es sind 0x00
Charaktere, die ich von bekomme hexdump -x /dev/ttyUSB0
. Dies ist kein Problem mit der seriellen Schnittstelle meines Computers; Ich habe mit einem Zielfernrohr nachgesehen und das Signal ist anders (links funktioniert, rechts nicht):
Der Code ist einfach:
void main(void) {
init(); // Sets up ports and UART control registers
while (1) {
uart_putch('a'); // or c
}
}
Was auch nicht funktioniert, ist die Verwendung einer der Zeichenfolgenfunktionen ( puts
, printf
, etc.), die meiner Meinung nach verwandt sind - daher habe ich in dieser Frage ein minimales Arbeitsbeispiel mit Zeichen erstellt.
Die generierte Assembly, wenn ich eine Variable verwende, c
hat:
_c:
db low(061h)
global __end_of_c
_main:
; ...
movlw low((_c))
movwf tblptrl
if 1 ;There is more than 1 active tblptr byte
movlw high((_c))
movwf tblptrh
endif
if 1 ;There are 3 active tblptr bytes
movlw low highword((_c))
movwf tblptru
endif
tblrd *
movf tablat,w
call _putch
Und mit einer Konstanten hat es im _main
Block:
movlw (061h)&0ffh
call _putch
Ich verwende MPLAB XC8 C Compiler V1.41 (24. Januar 2017) mit Teilunterstützungsversion 1.41.
Die relevanten Teile meines Makefiles:
CC:=xc8
CFLAGS:=-I. --chip=18F27K40 -Q -Wall
SRC:=main.c uart.c
DEP:=uart.h
PRS:=$(subst .c,.p1,$(SRC))
OBJ:=main.hex
all: $(OBJ)
$(OBJ): $(PRS)
$(CC) $(CFLAGS) $^
$(PRS): %.p1: %.c $(DEP)
$(CC) $(CFLAGS) -o$@ --pass1 $<
Jede Hilfe, um dies zum Laufen zu bringen, wäre sehr willkommen.
Ihr Programm ist in Ordnung, es ist ein Fehler auf dem PIC18F27K40.
Siehe http://ww1.microchip.com/downloads/en/DeviceDoc/80000713A.pdf
Verwenden Sie XC8-Compilier V1.41 und mplabx IDE, wählen Sie XC8 Global options / XC8 linker und wählen Sie "Additional options", fügen Sie dann +nvmreg
das Errata-Feld hinzu und alles wird gut.
Auszug aus dem verlinkten Dokument, Stichworte fett markiert:
TBLRD erfordert, dass der NVMREG-Wert auf den entsprechenden Speicher zeigt
Die betroffenen Siliziumversionen der PIC18FXXK40-Bausteine erfordern fälschlicherweise, dass die
NVMREG<1:0>
Bits imNVMCON
Register für denTBLRD
Zugriff auf die verschiedenen Speicherbereiche gesetzt werden. Das Problem tritt am deutlichsten in kompilierten C-Programmen auf, wenn der Benutzer einen konstanten Typ definiert und der CompilerTBLRD
Anweisungen verwendet , um die Daten aus dem Programm-Flash-Speicher (PFM) abzurufen. Das Problem wird auch offensichtlich, wenn der Benutzer ein Array im RAM definiert, für das der Compiler Startcode erstellt, der vor ausgeführtmain()
wird undTBLRD
Anweisungen zum Initialisieren des RAM von PFM verwendet.
const-Zeichen werden im Programmspeicher (Flash) gespeichert, und es sieht so aus, als ob der Compiler sieht, dass Sie es nicht als Variable verwenden (da es sich nie ändert) und es in den Programmspeicher optimiert, unabhängig davon, ob Sie const verwenden oder nicht.
Versuchen Sie, es als zu deklarieren volatile char c= 'a';
. Dadurch wird es erzwungen, dass es im SRAM statt im Flash gespeichert wird.
Warum ist das wichtig?
Bei PIC18s wird die Verwendung der db-Direktive (Datenbyte zum Speichern eines Bytes im Programmspeicher) mit einer ungeraden Anzahl von Bytes (wie in Ihrem Fall) automatisch mit Nullen aufgefüllt. Dieses Verhalten unterscheidet sich von dem des PIC16, weshalb es wahrscheinlich auf dem einen funktioniert, auf dem anderen jedoch nicht. Aus diesem Grund funktionieren im Flash-Speicher gespeicherte Strings oder Zeichen auch nicht mit den Standard-String-Funktionen wie strcpy oder printf. Etwas im Programmspeicher zu speichern ist nicht automatisch typsicher.
Basierend auf der Assembly ist es ziemlich klar, dass die falschen 8 Bytes geladen werden. Das ist 0x00, also sendet es korrekt 0x00 (wie Sie es gründlich bestätigt haben).
Es kann schwierig sein, vorherzusagen, was Sie heutzutage mit der wahnsinnigen Menge an Compiler-Optimierung erreichen werden, daher bin ich mir nicht sicher, ob dies funktionieren wird. Der flüchtige Trick sollte funktionieren, aber wenn Sie wirklich wollen, dass er im Flash gespeichert wird, versuchen Sie Folgendes:
TXREG = data & 0xff;
oder evtl
TXREG = data & 0x0ff;
Ich weiß, dass das theoretisch nichts bringen sollte. Aber wir versuchen, die Assembly-Ausgabe des Compilers so zu ändern, dass sie das tut, was wir wollen, und nicht irgendwie, aber nicht wirklich, was wir wollen.
Aus dem MPASM-Benutzerhandbuch:
Ich empfehle auch , es sich selbst sowie code_pack im PDF anzusehen. Seite 65.
trosley
Rohat Kılıç
SoreDakeNoKoto
Benutzer17592
unsigned char
,char
,const unsigned char
und versuchtconst char
.Benutzer17592
void putch(char data)
ist eigentlich die Signatur, die Sie verwenden sollten, um das stdout-Verhalten zu überschreiben (siehe MLAB XC8-Benutzerhandbuch, 3.5.7).MarkU
byteTx
stattdessen das Argument umbenennen? Ich mache mir Sorgen, dassbyte
dies an anderer Stelle als Datentyp definiert werden könnte. (Scheint so, als würde das eine Compiler-Diagnose generieren, aber hier geht eindeutig etwas Seltsames vor.) Und als weiterer Test, verhält esputch(0x61)
sich genauso schlecht wieputch('a')
? Ich frage mich, ob der Tabellenlesebefehl 8-Bit- oder 16-Bit-Daten liest. Das PIC-W-Register hat jedoch nur 8 Bit, richtig?Benutzer17592
byteTx
, außer dass dieser Name auch in der Assembly geändert wird. Die Verwendung0x61
von statt'a'
(bei der Variablenzuweisung oder demputch
Aufruf) macht keinen Unterschied. Heute Nachmittag zu Hause werde ich versuchen, den gleichen Code auf einem völlig anderen Prozessor auszuführen, um zu sehen, ob er dort funktioniert, und die Assembly vergleichen, wenn dies der Fall ist.dom
_main
aufgenommen haben, da sie fehltcall _putch
.Benutzer17592
xc8 --pass1
und dann alle mit einem einfachen Aufruf von verknüpftxc8
.Jon
Benutzer17592
Benutzer17592