简体   繁体   English

图片微控制器的初始化功能

[英]initialization function for pic microcontroller

I am trying to get a pic16 controller to run an initialization function that displays some text on an LCD only once and then goes on to display other things 我试图让pic16控制器运行初始化功能,该功能仅在LCD上显示一些文本,然后继续显示其他内容

The LCD output is working fine the problem is that the initialization function keeps executing. LCD输出工作正常,问题在于初始化功能一直在执行。 What am I doing wrong ? 我究竟做错了什么 ?

/*
 * 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);
}

The char number[] = ""; char number[] = ""; array is very small, yet you use it in itoa() , thus overwriting random memory. 数组很小,但是您可以在itoa()使用它,从而覆盖随机内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM