Ich verwende solchen Code auf PIC18F25K80, der mit dem xc8-Compiler kompiliert wurde:
unsigned long kline_kw1281_byte_time = 0;
void sendKline(void) {
klineWrite(0x9);
while (klineBusy());
kline_kw1281_byte_time = millis();
while (!klineAvailable()) {
if (kline_kw1281_byte_time_out()) {
mStatus = DISCONNECTED;
while(Busy1USART());
Write1USART(0x00);
return;
}
}
}
bit kline_kw1281_byte_time_out(void) {
unsigned long time_out = millis() - kline_kw1281_byte_time;
if (time_out > 20){
while(Busy1USART());
Write1USART(time_out);
return 1;
} else
return 0;
}
und ich habe ein seltsames Problem. In kline_kw1281_byte_time_out()
der Funktion habe ich eine wahre Aussage für, drucke time_out > 20
aber eine niedrigere Zahl als 20. Dies geschieht zufällig. Write1USART(time_out)
Die Funktion arbeitet die meiste Zeit korrekt.
das ist millis() Code:
#include <p18cxxx.h>
#include "timer0.h"
volatile unsigned long runtime_millis;
void initialize_timer0() {
T0CON = 0b11000011;
INTCONbits.TMR0IE = 1;
INTCON2bits.TMR0IP = 1; //set timer0 interrupt priority high
INTCONbits.TMR0IF = 0; //reset timer0 interrupt flag
}
void timer0(void) {
runtime_millis++;
TMR0L = 8;
INTCONbits.TMR0IF = 0;
}
unsigned long millis(void) {
return runtime_millis;
}
void delay(unsigned long ms) {
unsigned long cTime = runtime_millis;
while (runtime_millis - cTime < ms);
}
if (time_out > 20){
while(Busy1USART());
Write1USART(time_out);
Dies schreibt time_out
als ASCII-Zeichen in das USART-Modul. Wenn Sie „4“ über dem USART sehen, bedeutet dies, dass das ASCII-Zeichen „4“, Realwert 0x34
, gesendet wird. Und 0x34
, 52 dezimal, ist größer als 20.
Wenn Sie den Dezimalwert als Zeichenfolge in USART drucken möchten, können Sie dies tun:
#define putch Write1USART
printf("%ul", time_out);
Die printf()
Funktion formatiert time_out
als unsigned long (daher %ul
) und schreibt es Byte für Byte in putch()
. putch()
sollte daher die Signatur haben:
void putch(unsigned char);
Das #define
im obigen Beispiel stellt sicher, Write1USART()
dass für verwendet wird putch()
.
Wetterfahne
delay()
dem es fehlschlagen kann, wenn derruntime_millis
Zähler umbricht. Ein Compiler kann Code enthalten, der das Overflag testet und Ihnen die falsche Antwort gibt. Verwenden Sie besser ein Sprungbrettdo elapsed = runtime_millis - cTime; while (elapsed < ms);
. Seien Sie auch vorsichtig, wenn Sie einen Wert lesen, der unter Interrupt geändert wird, der größer als ein Prozessorregister ist, damit er sich nicht zwischen den erforderlichen mehreren Speicherlesevorgängen ändert. Deaktivieren Sie den Interrupt besser, während Sie den Zähler in eine andere Variable einlesen.Wille