如何避免PIC16f877A项目中有浮点到字符串转换的堆栈溢出?

时间:2016-03-27 17:55:06

标签: c stack-overflow microcontroller compiler-warnings mplab

我目前正在研究一种交通监控系统,该系统需要通过GSM / GPRS模块将地质坐标(浮动)作为文本消息发送。我使用以下代码将这些浮点值转换为字符串,但在编译中“警告:(1393)检测到可能的硬件堆栈溢出;估计堆栈深度:10”恰好弹出。 我正在使用PIC 16f877A,除了更换MCU之外,我还能做些什么来避免这种情况?

void reverse(char *str, int len)
{
int i=0, j=len-1, temp;
    while (i<j)
    {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++; j--;
    }
}

int intToStr(int x, char str[], int d)
{
    int i = 0;
    while (x)
    {
        str[i++] = (x%10) + '0';
        x = x/10;
    }
    while (i < d)
        str[i++] = '0';

    reverse(str, i);
    str[i] = '\0';
    return i;
}

void ftoa(float n, char *res, int afterpoint)
{
    int ipart = (int)n;
    float fpart = n - (float)ipart;
    int i = intToStr(ipart, res, 0);
    if (afterpoint != 0)
    {
        res[i] = '.';
        fpart = fpart * pow(10, afterpoint);
        intToStr((int)fpart, res + i + 1, afterpoint);
    }
}

2 个答案:

答案 0 :(得分:1)

你可以使用内置的“sprintf”功能,这样的话(用pic16f1705编译好,你的照片也一样):

char array[64];
float myvalue=2.0f;
sprintf(array, "%f", myvalue);

查看XC8编译器的帮助文件,help-&gt; XC8 Toolchain-&gt; MPLAB XC8 Compiler-&gt;库函数 - &gt; sprintf

您也可以使用printf直接打印到USART1:

printf("my message to GSM transitter %f", myvalue); 

答案 1 :(得分:0)

这里是我在PICF16F877A中用于打印ADC值的代码的宁静

// CONFIG
#pragma config FOSC  = HS      // Oscillator Selection bits (HS oscillator)
#pragma config WDTE  = OFF     // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF    // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON    // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP   = OFF      // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD   = OFF      // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT   = OFF      // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP    = OFF       // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>
#include <pic16f877a.h>
#include <stdio.h>
#include <string.h>

#define _XTAL_FREQ 20000000

/////////////////////////Code to print debug print//////////////////////////////
//#define FREQ 8000000
#define FREQ _XTAL_FREQ
#define baud 9600
#define spbrg_value (((FREQ/64)/baud)-1)    //312500 spbrg=32
unsigned char data1;
char *str1;
void serial_init()
{
    SPBRG=spbrg_value;
    //SPBRG=31;
    //  TXSTAbits.TXEN = 1;
    //CSRC: Clock Source Select bit            0
    //TX9 : 9-bit Transmit Enable bit          0
    //TXEN: Transmit Enable                    0  
    //SYNC: EUSART Mode Select bit             0
    //SENDB: Send Break Character bit          0
    //BRGH: High Baud Rate Select bit          0
    //TRMT: Transmit Shift Register Status bit 1
    //TX9D: Ninth bit of Transmit Data         0
    TXSTA=0x20;

    //  RCSTAbits.SPEN = 1;
    //  RCSTAbits.CREN = 1;

    //bit 7 SPEN: Serial Port Enable bit        1
    //bit 6 RX9: 9-bit Receive Enable bit       0
    //bit 5 SREN: Single Receive Enable bit     0
    //bit 4 CREN: Continuous Receive Enable bit 1
    //bit 3 ADDEN: Address Detect Enable bit    0
    //bit 2 FERR: Framing Error bit             0
    //bit 1 OERR: Overrun Error bit             0
    //bit 0 RX9D: 9th bit of Received Data      0
    RCSTA=0x90;
    //Setting 
    TRISCbits.TRISC6=0;
    TRISCbits.TRISC7=1;
}
void tx(unsigned char temp)
{
    TXREG=temp;
    while(PIR1bits.TXIF == 0);
    while(TXSTAbits.TRMT == 0);

}

void tx_str(char *senpoint)
{
    str1=senpoint;
    while(*str1 != '\0')
    {
        tx(*str1);
        str1++;

    }
}

//In main function, you can write,

unsigned char ADCBuf[40]; 
void main()
{
  serial_init();
//  unsigned int a;
  TRISA = 0xFF;                 //Analog pins as Input
//  TRISB = 0x00;                 //Port B as Output
//  TRISC = 0x00;                 //Port C as Output
  ADC_Init();                   //Initialize ADC
  unsigned int a;
  float V;
  a = 10;
  unsigned char str_1[]="P";
   tx_str("ADC TEST \n\r");
  while(1)
  {

    a = ADC_Read(0);            //Read Analog Channel 
//    a = a + 1;            //Read Analog Channel 0
    sprintf(ADCBuf,"Adc Val = %d \n\r",a);
    tx_str(ADCBuf);
    __delay_ms(1000);            //Delay
    V = a*(5000.0/1023.0);
    sprintf(ADCBuf,"Voltage = %f \n\r",V);
    tx_str(ADCBuf);
    __delay_ms(1000);


  }                    
}