Работа над программой для dcPIC33 (очевидно, написанной на c) с использованием компилятора XC16 и MPLABX v2.10 IDE. Я реализовал некоторые функции, одной из которых является отправка строк текста на UART, чтобы я мог видеть последовательный вывод с помощью последовательного терминала. Моя проблема находится в этой строке.
UART_Write_Text("Starting ADXL345 test...fdsbjugbbjkdsf");
Который, когда вы смотрите на приведенный ниже код, должен запускаться только один раз, однако он всегда повторяется в терминале, как если бы int main зацикливался, хотя у main есть цикл while внизу, чтобы он не заканчивался, я просто не вижу как ему удается так зацикливаться.
/*
* File: main2.c
* Author: nedu
*
* Created on 14 July 2014, 15:57
*/
#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#if __XC16_VERSION < 1011
#warning "Please upgrade to XC16 v1.11 or newer."
#endif
#pragma config ICS = PGD3 // ICD Communication Channel Select bits (Communicate on PGEC3 and PGED3)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
// FPOR
#pragma config ALTI2C1 = OFF // Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF // Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
#pragma config WDTWIN = WIN25 // Watchdog Window Select bits (WDT Window is 25% of WDT period)
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
#pragma config PLLKEN = ON // PLL Lock Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
// FOSC
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (XT Crystal Oscillator Mode)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = OFF // Peripheral pin select configuration (Allow multiple reconfigurations)
#pragma config FCKSM = CSECMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
// FOSCSEL
#pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
// FGS
#pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
#pragma config GCP = OFF // General Segment Code-Protect bit (General Segment Code protect is Disabled)
#define FP 40000000
#define BAUDRATE 9600
#define BRGVAL ((FP/BAUDRATE)/16)-1
#define DELAY_105uS asm volatile ("REPEAT, #4201"); Nop(); // 105uS delay
unsigned int i;
char *temp[40];
#include "spi.h"
#include "ADXL345.h"
void delay_ms(long ms){
unsigned long x = 0;
for(x = 0; x <= ((FP/24000))*ms; x++)
Nop();
}
void __attribute__((__interrupt__)) _U1TXInterrupt(void)
{
IFS0bits.U1TXIF = 0; // Clear TX Interrupt flag
}
void UART_Write(char data)
{
while(!U1STAbits.TRMT);
U1TXREG = data;
}
void UART_Write_Text(char *text)
{
int i;
UART_Write('\n');
UART_Write('\r');
for(i=0;text[i]!='\0';i++)
UART_Write(text[i]);
}
void InitClock(){
PLLFBD=63; // M=65
CLKDIVbits.PLLPOST=0; // N2=2
CLKDIVbits.PLLPRE=1; // N1=3
// Initiate Clock Switch to FRC oscillator with PLL (NOSC=0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(OSCCON | 0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while (OSCCONbits.LOCK!= 1);
}
void InitUart(){
U1MODEbits.STSEL = 0; // 1-Stop bit
U1MODEbits.PDSEL = 0; // No Parity, 8-Data bits
U1MODEbits.ABAUD = 0; // Auto-Baud disabled
U1MODEbits.BRGH = 0; // Standard-Speed mode
U1BRG = BRGVAL; // Baud Rate setting for 9600
U1STAbits.UTXISEL0 = 0; // Interrupt after one TX character is transmitted
U1STAbits.UTXISEL1 = 0;
IEC0bits.U1TXIE = 1; // Enable UART TX interrupt
RPOR4bits.RP43R = 1; //RP43/RB11 as U1TX
RPINR18bits.U1RXR = 42; //RP42/RB10 as U1RX
U1MODEbits.UARTEN = 1; // Enable UART
U1STAbits.UTXEN = 1; // Enable UART TX
/* Wait at least 105 microseconds (1/9600) before sending first char */
DELAY_105uS
}
int main(void)
{
InitClock();
InitUart();
spi_init();
UART_Write_Text("Starting ADXL345 test...fdsbjugbbjkdsf");
enable_adxl345();
int id = adxl345_devID();
sprintf(temp, "Device ID is: 0x%02x", id);
UART_Write_Text(temp);
UART_Write_Text("Done");
/*
//Go into standby mode to configure the device.
setPowerControl(0x00);
//Full resolution, +/-16g, 4mg/LSB.
setDataFormatControl(0x0B);
//3.2kHz data rate.
setDataRate(ADXL345_3200HZ);
//Measurement mode.
setPowerControl(0x08);
*/
int* readings[3] = {0,0,0};
getOutput(readings);
int inter = 7;
while(1)
{
delay_ms(1000);
/*UART_Write_Text("Starting ADXL345 test...");*/
sprintf(temp, "%i, %i, %i", inter, (int) readings[1], (int) readings[2]);
UART_Write_Text("WORK");
}
return 0;
}
Я просто не могу понять это, надеюсь, кто-то может указать мне правильное направление?
ОБНОВЛЕНИЕ: удалось исправить мою проблему, причиной сбоя программы был цикл for в функции UART_Write_Text() (тот, что закомментирован ниже).
void UART_Write(char data)
{
while(!U1STAbits.TRMT);
U1TXREG = data;
}
void UART_Write_Text(char *text)
{
int i;
UART_Write('\n');
UART_Write('\r');
for(i=0;i<25;i++)
UART_Write(text[i]);
/*
for(i=0;text[i]!='\0';i++)
UART_Write(text[i]);
*/
}
Условие цикла for text[I]!='\0', я использовал '\0', чтобы остановить цикл в конце char[], однако я предполагал, что '\0' означает char, который = NULL, когда чтобы условие действительно выполнялось, на самом деле должно было быть = '\ 0'.
Хотя ни одному ответу не удалось уловить это, я хотел бы поблагодарить всех, кто потратил свое время, чтобы попытаться помочь мне в этом, и я проголосовал за вас всех, поскольку все ваши ответы помогли мне понять C в целом, так как у меня есть возможность чтобы пометить вопрос как отвеченный, я собираюсь отметить ответ «gmch», поскольку его объяснение разницы между массивом переменных и массивом указателей на указанные переменные, на мой взгляд, является звездным :).
#define DELAY_105uS asm volatile ("REPEAT, #4201"); Nop(); // 105uS delay
не гарантируется корректная работа; вы не можете предположить, что компилятор создаст инструкциюNOP
сразу после инструкцииREPEAT
, поэтому правильный подход — поместитьNOP
внутриasm()
- person Jason S   schedule 04.06.2015