0

我正在尝试让 pic16 控制器运行初始化函数,该函数仅在 LCD 上显示一些文本,然后继续显示其他内容

LCD 输出工作正常,问题是初始化函数一直在执行。我究竟做错了什么 ?

/*
 * File:   main.c
 *
 * Created on Sep 1, 2013, 12:09 PM
 */


#include <pic.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "delay.h"

__CONFIG(WDTE_ON & PWRTE_ON & MCLRE_ON & BOREN_ON & FOSC_INTRCIO );

static int exec_counter = 0;

#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))      // bit mask macros
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define flip_bit(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define test_bit(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define E  RC4         //  Define the LCD Control Pins
#define RS RC5
int i;                 //  Use Global Variables for Debug

LCDWrite(int LCDData, int RSValue)
{

    PORTC = (LCDData >> 4) & 0x0F;  //  Get High 4 Bits for Output
    RS = RSValue;
    E = 1;  E = 0;                   //  Toggle the High 4 Bits Out

    PORTC = LCDData & 0x0F;          //  Get Low 4 Bits for Output
    RS = RSValue;
    E = 1;  E = 0;                   //  Toggle the Low 4 Bits Out

    if ((0 == (LCDData & 0xFC)) && (0 == RSValue))
        DelayMs(5);
    else
        DelayUs(200);

}  //

void writeLines(char top[],char bottom[]){
    for (i = 0; top[i] != 0; i++)   //  Write Line 1
        LCDWrite(top[i], 1);

    LCDWrite(0b11000000, 0);        //  Move Cursor to the Second Line

    for (i = 0; bottom[i] != 0; i++)//  Write Line 2
        LCDWrite(bottom[i], 1);

}

int countelems(char arr[]){
    for (i = 0; arr[i] != 0; i++){}
    return i;
}
void pad_number(char number[],char numberout[],char unit[]){
    int size_n = countelems(number);        // get length of number array by reference
    int size_u = countelems(unit);          // get length of unit array by reference
    int size = size_u + size_n + 1;         // calculate total size of text with 1 space between number and unit
    int L_space = floor((16-size)/2)-1;     // calculate space required on left side of display to center text
    for (i = 0; i <= 15; i++)
        numberout[i] = 0b10100000;          // fill output char array with spaces
    for (i = 0; i <= (size_n); i++){
        numberout[i+(L_space+1)] = number[i];       // fill output char array with number
    }
    numberout[L_space+size_n+1] = 0b10100000;       // put space in output char array between number and unit
    for (i = 0; i <= size_u; i++){
        numberout[i+(L_space+size_n+2)] = unit[i];  // fill output char array with unit
    }
}
void pad_text(char text[],char textout[]){
    int size = countelems(text);            // get length of char array by reference
    int L_space = floor((16-size)/2);       // calculate space required on left side of display to center text
    for (i = 0; i <= 15; i++)
        textout[i] = 0b10100000;            // fill output char array with spaces
    for (i = 0; i <= 15; i++){
        if( i >= L_space && i <= (L_space+size)){
            textout[i] = text[i-L_space];   // fill middle of output char array with text
        }
    }
}
void getAnalog(int channel,char parameter[], char unit[]){
    char output_parameter[16];
    char output_number[16];
    char number[16];
    ADCON0 = channel << 2;                  // select channel
    //set_bit(ADCON0,7);                    // set ADFM flag so LSB is bit 0 of ADRESL
    set_bit(ADCON0,0);                      // switch ADC on = set ADON flag 0b00000001
    sampleTime();                           // wait required aquisition time
    set_bit(ADCON0,1);                      // start conversion = set GO/DONE bit
    while(test_bit(ADCON0,1)){/* wait for ADC to complete conversion */;}
    int ADCresult = (ADRESL+ADRESH)/10;     // get result from ADC
    itoa(number,ADCresult,10);              // convert ADC result to charstring
    LCDWrite(0b00000001, 0);                //  Clear LCD
    pad_text(parameter,output_parameter);
    pad_number(number,output_number,unit);
    writeLines(output_parameter, output_number);
}
void init(){
    DelayMs(20);                //  Wait for LCD to Power Up

    PORTC = 3;                  //  Start Initialization Process
    E = 1;  E = 0;              //  Send Reset Command
    DelayMs(5);

    E = 1;  E = 0;              //  Repeat Reset Command
    DelayUs(200);

    E = 1;  E = 0;              //  Repeat Reset Command Third Time
    DelayUs(200);
    PORTC = 2;                  //  Initialize LCD 4 Bit Mode
    E = 1;  E = 0;
    DelayUs(200);

    LCDWrite(0b00101000, 0);    //  LCD is 4 Bit I/F, 2 Line

    LCDWrite(0b00000001, 0);    //  Clear LCD

    LCDWrite(0b00000110, 0);    //  Move Cursor After Each Character

    LCDWrite(0b00001110, 0);    //  Turn On LCD and Enable Cursor
    //          "0123456789012345"
    writeLines( "  INITIALIZE    ",
                "     TEXT       ");

}
void main(void) {
    OPTION_REG |= 0x7;  // set prescaler to 1:128 or 2.3 Seconds
    OPTION_REG |= 0x8;  // assign prescaler to WDT
    TRISA = 0b00000101; // configure PORTA set RA0 and RA2 to analog input;
    ANSEL = 0b00000101; // disable input buffers if I/O pins RA0 and RA2
    TRISC = 0;          // configure PORTC as output
    ADCON1 = 0;         // select FOSC2
    if (exec_counter == 0){
        exec_counter++;
        init();
        DelayS(4);
    }
    PORTC = 0;

    while (1) {
        getAnalog(0,"VELOCITY","KM/H");
        DelayS(4);
        getAnalog(2,"ACCELERATION","M/S^2");
        DelayS(4);
    }
    return;
}

/*
 * File:   delay.c
 *
 * Created on Sep 3, 2013, 12:09 PM
 */

#include "delay.h"
#include <pic.h>
#define _XTAL_FREQ 4000000

void DelayMs(unsigned char cnt)
{
#if XTAL_FREQ <= 2MHZ
        do {
                DelayUs(996);
        } while(--cnt);
#endif

#if    XTAL_FREQ > 2MHZ
        unsigned char   i;
        do {
                i = 4;
                do {
                        DelayUs(250);
                } while(--i);
        } while(--cnt);
#endif
}

void DelayS(unsigned int count){
    for (int i=0; i<=count;i++){
        NOP();
        CLRWDT();
        DelayMs(1000);
    }
}

void sampleTime(){
    // TC = – 10pF ( 1k Ω + 7k Ω + 1k Ω ) ln(0.0004885)
    //    = 0.686 μS
    // TACQ = 5μS + 0.686μS + [ ( 50°C- 25°C ) ( 0.05μ S /°C ) ]
    //      = 6.936 μS /
    // 1 instruction cycle = 4μS @ 1 mHz
    // 1 instruction cycle = 1μS @ 4 mHz
    // 1 instruction cycle = 500nS @ 8 mHz
    // 1 instruction cycle = 200nS @ 20 mHz
    // TACQ @  1 mHz is 6.936 μS / 4 μS   or ~  2  instruction cycles
    // TACQ @  4 mHz is 6.936 μS / 1 μS   or ~  7  instruction cycles
    // TACQ @  8 mHz is 6.936 μS / 0.5 μS or ~  14 instruction cycles
    // TACQ @ 20 mHz is 6.936 μS / 0.2 μS or ~  35 instruction cycles
    DelayUs(8);
}
4

1 回答 1

0

char number[] = "";数组非常小,但您在 中使用它itoa(),从而覆盖了随机内存。

于 2013-09-04T09:45:01.963 回答