首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >int无缘无故地循环?(PIC编程,XC16,MPLAB) dsPIC33EP

int无缘无故地循环?(PIC编程,XC16,MPLAB) dsPIC33EP
EN

Stack Overflow用户
提问于 2014-07-17 11:50:59
回答 3查看 2K关注 0票数 0

使用dcPIC33编译器和MPLABXv2.10IDE在XC16上运行程序(显然是用c++编码)。我实现了一些功能,其中一个功能是将文本字符串发送到uart,这样我就可以看到使用串行终端的串行输出。我的问题就在这条线上。

代码语言:javascript
复制
UART_Write_Text("Starting ADXL345 test...fdsbjugbbjkdsf");

但是,当您查看下面的代码时,它应该只运行一次,但是在终端中将永远重复,就好像int主循环一样,即使main在底部有一个while循环以防止它结束--我只是不知道它是如何设法这样循环的。

代码语言:javascript
复制
    /* 
 * 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;
}

我就是搞不懂,希望有人能给我指明正确的方向?

更新:成功地修复了我的问题,程序崩溃的原因是函数UART_Write_Text()中的for循环(下面注释掉的那个)。

代码语言:javascript
复制
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循环条件textI!= '\0‘,我使用'\0’在char[]的末尾停止循环,但是我假设'\0‘意味着一个字符= NULL,当条件要实际满足时,实际上必须=’\0‘。

虽然没有任何答案能理解到这一点,但我要感谢每一个花时间尝试帮助我解决这个问题的人,我也很高兴你们的所有答案都帮助我理解了C作为一个整体,因为我有机会标记一个问题,因为我将标记“gmch”的答案,因为在我看来,他对一系列变量和指向上述变量的一系列指针之间的差异的解释是非常出色的。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-17 19:11:26

int* readings[3] = {0,0,0};是指向整数的指针数组.这可能就是为什么你(int)readings[1]停止编译器抱怨你。

我看不到一个getOutput(),所以不能看到它将对getOutput(readings)做什么,但是如果它想要一个指针数组到int,那么您将给它三个0指针--这可能很糟糕。

正如其他地方所指出的,char *temp[40]类似地是指向char的指针数组,而不是由40个字符组成的数组。

当涉及数组和指针时,C非常困惑,尤其是因为数组的名称是指向数组的第一个元素的隐式指针,而且(反过来)指针可以被当作数组使用。而“字符串”只会增加混乱。所以在..。

代码语言:javascript
复制
int readings[3] = { 11, 22, 33 } ;
int* p ;

我们有一个由三个整数组成的数组,名为readings,如图所示,以及指向整数‘p’的指针,没有值。现在:

代码语言:javascript
复制
readings[2] += 1 ;

将1添加到readings[2]中以生成23。我们可以:

代码语言:javascript
复制
p = readings ;

所以现在p指向readings[0] --因为数组的名称就像指向数组开始的指针一样自动工作。我们也可以写到:

代码语言:javascript
复制
p = &readings[0] ;

你可以说更清楚..。并符合:

代码语言:javascript
复制
p = &readings[1] ;

有趣的是,你可以写:

代码语言:javascript
复制
p[1] += 1 ;

('cos指针和数组基本上是可交换的),这将把readings[2]设置为‘33’。

实际上,以下所有内容都是指readings[2]

代码语言:javascript
复制
*(p+1) 
p[1]
readings[2]
*(readings+2)

越来越好了..。当您(显然)将数组传递给函数时,实际上是传递指向数组的第一个元素的指针。所以你的功能可以是:

代码语言:javascript
复制
static void foo(int* z) .....
static void foo(int a[]) .....

效果是一样的。你可以称之为:

代码语言:javascript
复制
foo(readings) ;
foo(p) ;

在函数本身中,a[2] *(a+2) z[2] *(z+2)几乎是可互换的。

作为一项规则,我想到一个定义:

char bar22;

创建一个名为char* (伪)的指针,名为bar,它隐式地指向22个字符数组的第一个元素。如果我还创建了:

代码语言:javascript
复制
char* pc = bar ; 

然后创建一个(实)指针,也被初始化为指向22个字符数组的第一个元素。barpc之间的差别很小:(1)不能分配给bar --实际上是const;(2) sizeof(bar)给出了数组的大小,而sizeof(pc)给出了指针E 238的大小。

票数 1
EN

Stack Overflow用户

发布于 2014-07-17 12:02:06

代码中有http://en.wikipedia.org/wiki/Undefined_behavior,这会导致奇怪的事情发生(最常见的是崩溃)。

问题在于您对变量temp的定义以及如何使用它。您可以在sprintf调用中使用它作为字符串,但它被定义为字符串数组。

票数 1
EN

Stack Overflow用户

发布于 2014-07-18 10:33:07

作为一般建议:将程序按部分拆分,将整个划分为2,或按函数(调用)排除函数。可能从简单的循环usngined long i = 0; while (1) { printf("%x ",i); i++; }开始,以确保应用了看门狗计时器pragma。那就把别人排除在外。否则,您只能分析代码和文档。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24802754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档