Announcement

Collapse
No announcement yet.

Announcement

Collapse
No announcement yet.

Tracker-PI 2 Source code and Coil's Есho calc. for public improvements in Geoscan Pulse Technology

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Tracker-PI 2 Source code and Coil's Есho calc. for public improvements in Geoscan Pulse Technology

    //main.c программа импульсного металлоискателя tracker-pi2 V1.0 за публичные усовершенствования технологии Geoscan Pulse//
    //C / C++ компилятор IAR Embedded Workbench IDE AVR 7.30.4//

    #include "iotiny2313a.h"
    #include <ioavr.h>
    #include <intrinsics.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "ina90.h"
    #include "lcd.h"
    #include "timeout.h"
    #include "hardware.h"
    #include "global_var.h"
    #define START_DELAY 500 //милисекунд для установления режимов усилителя по постоянному току
    #define ENABLE_LCD // если включено - светодиоды не используются
    #define ENABLE_SOUND
    #define ENABLE_USART
    #define OLD_AVERAGE_FILTER // усредняющий и помехоподавляющий фильтр
    #define USE_MANUAL_TIME_TX // задать время накачки вручную - для особых датчиков
    #define ManualTimeTX 0x75
    #define BoardV3 // на плате 3 версии находятся ускоряющие конденсаторы 470пФ и открывающий вспомогательный транзистор в драйвере полевика

    #ifdef BoardV3
    #define CAP_BOOST_TIME 5 // -5us
    #define TIME_GUARD 0x0c // 12us
    #define START_TIME_TX 64 // 100us
    #else
    #define CAP_BOOST_TIME 0 // 0
    #define TIME_GUARD 0x0a // 10 us
    #define START_TIME_TX 0x41 // 65 us
    #endif

    #define UTC_DELAY_1 6
    #define UTC_DELAY_2 6
    #define baudrate 38400 // 57600; 115200; 128000

    void LowBatIndicationLoop (void);

    void __watchdog_init (void)
    {
    //запускаю сторожевой таймер на 2 секунды
    __watchdog_reset ();
    WDTCR |= ((1<<WDCE)|(1<<WDE));
    WDTCR = (1<<WDE)|(7<<WDP0);
    __watchdog_reset ();
    }

    void InitTimers (void)
    {
    TCCR1A = 0x00;
    TCCR1B |= ((1<<CS10) | (1<<WGM12));
    OCR1A = 58500; //50000+6; //0xc350; //0xc350;

    TCCR0B |= (4<<CS00);

    TIMSK |= ((1<<TOIE0) | (1<<OCIE1A));

    ACSR |= (1<<ACIC);
    }

    void InitPorts (void)
    {
    PortPot |= (1<<Pot);
    PortPotDir |= (1<<Pot);
    PortKeys |= ((1<<Q2) | (1<<Q0) | (1<<Q1));
    PortKeysDir |= ((1<<Q2) | (1<<Q0) | (1<<Q1));
    PortSpeakerDir |= (1<<Speaker);
    PortSys |= ((1<<Pot) | (1<<Q2) | (1<<Q0) | (1<<Q1) | (1<<BatMeter));
    PortSysDir |= ((1<<Pot) | (1<<Q2) | (1<<Q0) | (1<<Q1) | (1<<Speaker));
    }

    void InitUsart (unsigned int baud)
    {
    UBRRH = (unsigned char)(baud>>;
    UBRRL = (unsigned char)baud;

    UCSRB |= (1<<TXEN);
    }

    void USARTSendChar (unsigned char data)
    {
    #ifdef ENABLE_USART
    while (!( UCSRA & (1<<UDRE))); // ждем, пока отправится предыдущий байт
    UDR = data;
    #endif //ENABLE_USART
    }

    void InitMode (void)
    {
    IntegratorCycleEnd = 0x00; // переменная глобальная, поэтому равна 0 после RESET
    //устанавливаем начальные временные интервалы
    TimeTX = START_TIME_TX-CAP_BOOST_TIME;
    TimeGuardAfterTXOFF = 0; // переменная глобальная, поэтому равна 0 после RESET
    TimeGuardAfterRXON = 0;// + CAP_BOOST_TIME;// + UTC_DELAY_1; // переменная глобальная, поэтому равна 0 после RESET
    TimeIntegration = 0x10;
    __enable_interrupt();
    }

    void GetPotPosition (void)
    {
    unsigned int counter = 0;
    __disable_interrupt();
    PortPotDir &= ~(1<<Pot); //переключаем выход на вход
    PortPot &= ~(1<<Pot);
    while (PinPot & (1<<Pot)) { counter += PositionAddStep; } //ждем, пока напряжение упадет до порогового
    UDR = (unsigned char)counter;
    PortPot |= (1<<Pot); //переключаем вход на выход
    PortPotDir |= (1<<Pot);
    counter -= PositionSub;
    if ((counter > PositionMax) || (counter == 0)) counter = 1; // проверяем, не вылезло ли за пределы
    Sensitivity = counter;
    UDR = (unsigned char)Sensitivity;
    }

    __flash signed int segmentsDec[5]={10000,1000,100,10,1};
    unsigned char String[5];

    void CharToStringDec(signed int inp)
    {
    unsigned char i;
    String[0]=String[1]=String[2]=String[3]=String[4]=0;
    // перевод
    for(i=0;i<5
    {
    if((inp-segmentsDec[i])>=0)
    {
    inp-=segmentsDec[i];
    String[i]++;
    }
    else i++;
    }
    }

    #ifdef ENABLE_LCD
    static __flash char str01 [] = " -<>+ "; //+000
    static __flash char str02 [] = "Wait"; //+000

    void LCDBarUpdate (signed int level)
    {
    unsigned char col, pos;
    signed int t;
    if (level < 0) t = 0;
    if (level < 256) t = (signed int)level;
    else t = 255;

    if (level >= threshold5) { ToneNumber = 5; }
    else if (level >= threshold4) { ToneNumber = 4; }
    else if (level >= threshold3) { ToneNumber = 3; }
    else if (level >= threshold2) { ToneNumber = 2; }
    else if (level >= threshold1) { ToneNumber = 1; }
    else { ToneNumber = 0; }

    if (++LCDPrescaler > 2)
    {
    LCDPrescaler = 0;

    lcd_gotoxy(0,0);//здесь показать уровень
    lcd_puts_p(str01);
    if (level < 0) { lcd_putc('-'); }
    else { lcd_putc(' '); }
    CharToStringDec(level); // конвертация
    for (unsigned char v=1; v<5; v++) lcd_putc(String[v]+0x30);
    lcd_gotoxy(0,1);
    col = (t+4 / 16;//рассчитываем номер знакоместа для рисования палки
    if (col>0) for (unsigned char z=0; z<col; z++) lcd_putc(0x05);//рисуем несколько полностью закрашенных знакомест
    //рассчитываем номер символа для отображения в знакоместе //5 вариантов
    pos = (t+4 - (col*16); // остаток
    pos = (pos)/3;
    lcd_putc(pos); //0x00+
    for (unsigned char t=0; t<16; t++) lcd_putc(' '); //не чистим экран, а заполняем пробелами
    }
    }

    #endif //ENABLE_LCD

    void DelayUnits (unsigned long time)
    {
    while (time--) {}
    }
    #pragma vector = TIMER1_COMPA_vect //вызывается раз в 5мс
    __interrupt void KeyDrive (void)
    {
    unsigned int ICRData = ICR1; //получаем данные о времени срабатывания компаратора
    PortKeys &= ~(1<<Q1); //выключаем первый усилитель
    DelayUnits (10);
    PortKeys &= ~(1<<Q0); //включаем накачку катушки
    DelayUnits (TimeTX);
    PortKeys |= (1<<Q0); //выключаем накачку катушки
    DelayUnits (TimeGuardAfterTXOFF);
    PortKeys |= (1<<Q1); //включаем первый усилитель
    DelayUnits (TimeGuardAfterRXON);
    PortKeys &= ~(1<<Q2); //включаем интегратор
    DelayUnits (TimeIntegration);
    PortKeys |= (1<<Q2); //выключаем интегратор
    IntegratorCycleCount++;
    Integrator += ICRData;
    __enable_interrupt(); //разрешить прерывания

    if (IntegratorCycleCount > 7)
    {
    IntegratorCycleCount = 0;
    Integrator = (Integrator >> 3); // деление на 8
    ReceivedSignal = (unsigned int)Integrator;
    UDR = ReceivedSignal>>8;
    IntegratorCycleEnd = 0xFF;
    Integrator = 0;
    }

    GetPotPosition ();
    __watchdog_reset ();
    }

    unsigned char SoundCycleCount;
    #pragma vector=TIMER0_OVF_vect
    __interrupt void Sound (void)
    {
    TCNT0 = 0xFE; // перезагрузить таймер
    if ((ToneNumber != 0) && (SoundCycleCount == 0))
    {
    SoundCycleCount = 16 - ToneNumber;
    #ifdef ENABLE_SOUND
    if (PortSpeaker & (1<<Speaker)) PortSpeaker &= ~(1<<Speaker); // speaker toggle
    else PortSpeaker |= (1<<Speaker);
    #endif //ENABLE_SOUND
    }
    if (SoundCycleCount) SoundCycleCount--;

    #ifdef ENABLE_SOUND
    if (ToneNumber == 0) PortSpeaker &= ~(1<<Speaker); // не потребляем динамиком лишний ток
    #endif //ENABLE_SOUND
    }
    void LowBatIndicationLoop (void) // отсюда никогда не выходим
    {
    TimeTX = 0; //Полная накачка уже ни к чему
    PortSysDir &= ~(1<<Q0); //Выключаем ключ совсем - Полная накачка уже ни к чему
    while (1)// батарея разряжена
    {
    __delay_cycles((CtrlClockRate/1000)*500);
    if (ToneNumber == 1) ToneNumber =0;
    else ToneNumber = 1;
    }

    }
    int main (void)
    {
    signed int Ka=0, Kb=0, Kc=0, Kd=0, temp=0, tempdebug=0;
    InitPorts ();

    #ifdef ENABLE_LCD
    lcd_init(LCD_DISP_ON);
    lcd_clrscr();
    lcd_gotoxy(6,0);
    lcd_puts_p(str02);
    #endif //ENABLE_LCD

    #ifdef ENABLE_USART
    InitUsart (((CtrlClockRate/16)/baudrate)-1);
    #endif //ENABLE_USART
    InitTimers ();
    InitMode ();
    __delay_cycles((CtrlClockRate/1000)*START_DELAY); // стартовая задержка
    __watchdog_init ();

    unsigned int tem;

    for (unsigned char i=0; i<8; i++)
    {
    while (IntegratorCycleEnd == 0) {} // ждем пока пройдет интегрирование
    EchoSumm = EchoSumm + ReceivedSignal;
    tem = ReceivedSignal >> 8;
    USARTSendChar ((unsigned char)tem);
    USARTSendChar ((unsigned char)ReceivedSignal);
    IntegratorCycleEnd = 0;
    }

    USARTSendChar ((unsigned char)EchoSumm);

    EchoSumm = EchoSumm >> 8; // деление на 256
    Echo = (unsigned char)(EchoSumm);
    USARTSendChar (Echo);
    Echo -= 0x32;
    USARTSendChar (Echo); // эхо, полученное при калибровке

    if (Echo >= 0x19) // катушка в порядке, эхо достаточной величины
    {
    if (Echo <= 0x37) {Ka = 0x19; Kb = 0x37; Kc = 0xA0; Kd = 0x8C; }
    else if (Echo <= 0x4B) {Ka = 0x37; Kb = 0x4B; Kc = 0x8C; Kd = 0x67; }
    else if (Echo <= 0x52) {Ka = 0x4B; Kb = 0x52; Kc = 0x67; Kd = 0x52; }
    else if (Echo <= 0x5F) {Ka = 0x52; Kb = 0x5F; Kc = 0x52; Kd = 0x41; }

    temp = Echo - Ka;
    temp = temp * (Kd - Kc);
    temp = Kc + (temp / (Kb - Ka));

    #ifndef USE_MANUAL_TIME_TX
    TimeTX = temp - CAP_BOOST_TIME; //устанавливаем рабочие тайминги
    if (Echo >= 0x60) TimeTX = 0x41 - CAP_BOOST_TIME;
    #endif

    #ifdef USE_MANUAL_TIME_TX
    TimeTX = ManualTimeTX;
    #endif //USE_MANUAL_TIME_TX

    TimeGuardAfterTXOFF = TIME_GUARD;
    TimeGuardAfterRXON = 0x00;// + CAP_BOOST_TIME;// + UTC_DELAY_1 + UTC_DELAY_2;
    TimeIntegration = 0x32;

    USARTSendChar (TimeTX); // вычисленное время накачки

    for (unsigned char i=0; i<10; i++) // пропускаем 10 циклов для устаканивания
    {
    while (IntegratorCycleEnd == 0) {} // пропускаем 1 цикл
    IntegratorCycleEnd = 0;
    }

    while (IntegratorCycleEnd == 0) {} // пропускаем 1 цикл, этого достаточно
    IntegratorCycleEnd = 0;

    unsigned int tem;
    EchoSumm = 0;
    for (unsigned char i=0; i<32; i++)
    {
    while (IntegratorCycleEnd == 0) {} // ждем пока пройдет интегрирование
    tem = ReceivedSignal >> 8;
    USARTSendChar ((unsigned char)tem);
    USARTSendChar ((unsigned char)ReceivedSignal);
    EchoSumm += ReceivedSignal;
    IntegratorCycleEnd = 0;
    }
    EchoSumm = EchoSumm >> 5; // деление на 32
    BaseValue = (unsigned int)EchoSumm; // получили базовое значение при отсутствии металла
    tem = BaseValue >> 8;
    USARTSendChar ((unsigned char)tem);
    USARTSendChar ((unsigned char)BaseValue);
    USARTSendChar (BaseValue>>; //базовое значение

    while (1) // основной цикл обнаружения металла
    {
    while (IntegratorCycleEnd == 0) {} // ждем пока пройдет интегрирование
    IntegratorCycleEnd = 0;

    #ifdef OLD_AVERAGE_FILTER //усреднитель сигнала
    EchoSumm = 0;
    for (unsigned char z=0; z<(ArrayLength-1); z++) { ArrayReceivedSignal [z] = ArrayReceivedSignal [z+1]; } // сдвинули массив к 0 ячейке
    ArrayReceivedSignal [ArrayLength-1] = ReceivedSignal; // в последнюю ячейку вносим свежее значение
    for (unsigned char z=0; z<ArrayLength; z++) EchoSumm += ArrayReceivedSignal [z]; // суммируем последние показания
    ReceivedSignal = (unsigned int)(EchoSumm / ArrayLength);
    #endif //OLD_AVERAGE_FILTER

    UDR = ReceivedSignal;
    tem = ReceivedSignal >> 8;
    USARTSendChar ((unsigned char)ReceivedSignal);
    USARTSendChar ((unsigned char)tem);
    temp = ReceivedSignal - BaseValue; // сравнение с опорным значением
    tempdebug = temp + 127;
    if (tempdebug > 255) tempdebug = 255;
    if (tempdebug < 0) tempdebug = 0;
    UDR = tempdebug;
    temp += temp; // разницу удваиваем со знаком
    temp += temp; // разницу удваиваем со знаком
    temp = 250;
    temp = temp / ((signed int)Sensitivity);
    USARTSendChar ((unsigned char)Sensitivity);

    #ifdef ENABLE_LCD // тут своя процедура вывода полосы
    if (temp < -4 temp = -48; // следим за рамками
    if (temp > 999 temp = 9999;
    if (++LCDPrescaler > 2)
    LCDPrescaler = 0;
    LCDBarUpdate (temp);
    #endif //ENABLE_LCD
    }
    }
    else LowBatIndicationLoop ();
    }

    ----------------------
    /*оптимизировано для меньшего размера кода, для случая если 4 бита, RS и E находятся в пределах 1 порта*/


    #include <ioavr.h>
    //#include <avr/pgmspace.h>
    #include "timeout.h"
    #include <intrinsics.h>
    #include "lcd_hw.h"
    #include "lcd.h"


    __flash char SymbolCGRAM[48] = {
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    0x00, /* ........ */
    // символ №0
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    0x10, /* ...$.... */
    // символ №1
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    0x18, /* ...$$... */
    // символ №2
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    0x1C, /* ...$$$.. */
    // символ №3
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    0x1E, /* ...$$$$. */
    // символ №4
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    0x1F, /* ...$$$$$ */
    // символ №5
    };

    /* compatibilty macros for old style */
    /*
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif

    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif
    */
    /*
    ** constants/macros
    */

    void lcd_e_high(void)
    {
    LCD_DATA_PORT |= (1<<LCD_E_PIN);
    }

    void lcd_e_low(void)
    {
    LCD_DATA_PORT &= ~(1<<LCD_E_PIN);
    }

    void lcd_cmd_mode(void)
    {
    LCD_DATA_PORT &= ~(1<<LCD_RS_PIN); // RS=0 command mode
    }

    void lcd_data_mode(void)
    {
    LCD_DATA_PORT |= (1<<LCD_RS_PIN); // RS=1 data mode
    }

    void lcd_data_port_out(void)
    { /* defines all data pins as output */
    LCD_DDR_PORT |= (1<<LCD_DATA_PIN_D7) | (1<<LCD_DATA_PIN_D6) | (1<<LCD_DATA_PIN_D5) | (1<<LCD_DATA_PIN_D4) | (1<<LCD_RS_PIN) | (1<<LCD_E_PIN);
    //LCD_DDR_PORT |= (1<<LCD_RS_PIN) | (1<<LCD_E_PIN);
    /*
    LCD_DDR_PORT |= (1<<LCD_DATA_PIN_D7);
    LCD_DDR_PORT |= (1<<LCD_DATA_PIN_D6);
    LCD_DDR_PORT |= (1<<LCD_DATA_PIN_D5);
    LCD_DDR_PORT |= (1<<LCD_DATA_PIN_D4);
    */
    }

    #if LCD_LINES==1
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE
    #else
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES
    #endif

    /*
    ** function prototypes
    */
    static void lcd_e_toggle(void);
    static void lcd_out_high(u08 d);
    //static void lcd_out_low(u08 d);

    /*
    ** local functions
    */

    /*
    static void lcd_out_low(u08 d)
    { // output low nibble
    if (d&0x0 LCD_DATA_PORT_D7 |= (1<<LCD_DATA_PIN_D7);
    else LCD_DATA_PORT_D7 &= ~(1<<LCD_DATA_PIN_D7);
    if (d&0x04) LCD_DATA_PORT_D6 |= (1<<LCD_DATA_PIN_D6);
    else LCD_DATA_PORT_D6 &= ~(1<<LCD_DATA_PIN_D6);
    if (d&0x02) LCD_DATA_PORT_D5 |= (1<<LCD_DATA_PIN_D5);
    else LCD_DATA_PORT_D5 &= ~(1<<LCD_DATA_PIN_D5);
    if (d&0x01) LCD_DATA_PORT_D4 |= (1<<LCD_DATA_PIN_D4);
    else LCD_DATA_PORT_D4 &= ~(1<<LCD_DATA_PIN_D4);
    }
    */
    static void lcd_out_high(u08 d) // output high nibble
    {
    unsigned char temp;

    LCD_DATA_PORT &= ~((1<<LCD_DATA_PIN_D7) | (1<<LCD_DATA_PIN_D6) | (1<<LCD_DATA_PIN_D5) | (1<<LCD_DATA_PIN_D4));//сбросили DATA

    temp = 0xF0 & d; // маскируем младшие биты на всякий случай

    LCD_DATA_PORT |= temp;
    /*
    if (d&0x80) LCD_DATA_PORT |= (1<<LCD_DATA_PIN_D7);
    else LCD_DATA_PORT &= ~(1<<LCD_DATA_PIN_D7);
    if (d&0x40) LCD_DATA_PORT |= (1<<LCD_DATA_PIN_D6);
    else LCD_DATA_PORT &= ~(1<<LCD_DATA_PIN_D6);
    if (d&0x20) LCD_DATA_PORT |= (1<<LCD_DATA_PIN_D5);
    else LCD_DATA_PORT &= ~(1<<LCD_DATA_PIN_D5);
    if (d&0x10) LCD_DATA_PORT |= (1<<LCD_DATA_PIN_D4);
    else LCD_DATA_PORT &= ~(1<<LCD_DATA_PIN_D4);
    */
    }

    static void lcd_e_toggle(void)
    /* toggle Enable Pin */
    {
    lcd_e_high();
    __delay_cycles((CtrlClockRate/1000000)*5);
    lcd_e_low();
    __delay_cycles((CtrlClockRate/1000000)*1);
    }


    static void lcd_write(u08 data, u08 rs)
    {
    __delay_cycles((CtrlClockRate/1000000)*;

    for (unsigned char cycle=0; cycle<2; cycle++)
    {
    if (cycle == 0) lcd_out_high(data);
    else lcd_out_high(data << 4);

    __delay_cycles((CtrlClockRate/1000000)*;

    if (rs)
    lcd_data_mode();
    else
    lcd_cmd_mode();
    lcd_e_toggle();
    }

    /*
    lcd_out_high(data);
    __delay_cycles((CtrlClockRate/1000000)*;

    if (rs)
    lcd_data_mode();
    else
    lcd_cmd_mode();
    lcd_e_toggle();

    lcd_out_high(data << 4);
    __delay_cycles((CtrlClockRate/1000000)*;

    if (rs)
    lcd_data_mode();
    else
    lcd_cmd_mode();

    lcd_e_toggle();
    */
    }
    static unsigned char lcd_waitcmd(unsigned char cmdwait)
    {
    __delay_cycles((CtrlClockRate/1000000)*9);
    /* the display needs much longer to process a command */
    if (cmdwait){
    __delay_cycles((CtrlClockRate/1000)*2);
    }
    return (0);
    }

    /*
    ** PUBLIC FUNCTIONS
    */
    void lcd_command(u08 cmd)
    /* send commando <cmd> to LCD */
    {
    lcd_waitcmd(0);
    lcd_write(cmd, 0);
    lcd_waitcmd(1);
    }

    void lcd_gotoxy(u08 x, u08 y)
    /* goto position (x,y) */
    {
    #if LCD_LINES==1
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
    #endif
    #if LCD_LINES==2
    if (y == 0)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
    else
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);
    #endif
    #if LCD_LINES==3
    if (y == 0)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
    else if (y == 1)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);
    else if (y == 2)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x);
    #endif
    #if LCD_LINES==4
    if (y == 0)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE1 + x);
    else if (y == 1)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE2 + x);
    else if (y == 2)
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE3 + x);
    else /* y==3 */
    lcd_command((1 << LCD_DDRAM) + LCD_START_LINE4 + x);
    #endif

    } /* lcd_gotoxy */

    void lcd_putc(char c)
    /* print character at current cursor position */
    {
    lcd_waitcmd(0);
    lcd_write((unsigned char)c, 1);
    lcd_waitcmd(0);
    }

    void lcd_puts(const char *s)
    /* print string on lcd */
    {
    while (*s) {
    lcd_putc(*s);
    s++;
    }

    }

    void lcd_puts_p(const char __flash *progmem_s)
    /* print string from program memory on lcd */
    {
    register char c;

    while (c = (*(unsigned char __flash *)(progmem_s++))) {
    lcd_putc(c);
    }

    }

    void InitCGram(void) // инициализация области CGRAM
    {
    unsigned char i;
    lcd_write(0x40, 0); // установка видео-адреса в области CGRAM
    __delay_cycles((CtrlClockRate/1000000)*100); // попробовать еще это убрать
    for(i=0;i<sizeof(SymbolCGRAM);i++)
    {
    lcd_write(SymbolCGRAM[i],1); // загрузка символов в CGRAM
    __delay_cycles((CtrlClockRate/1000000)*100);
    }
    }

    void lcd_init(u08 dispAttr)
    /* initialize display and select type of cursor */
    /* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */
    {
    /*------ Initialize lcd to 4 bit i/o mode -------*/

    lcd_data_port_out(); /* all data port bits as output */

    //сделано в процедуре выше
    //LCD_DDR_PORT |= (1<<LCD_RS_PIN) | (1<<LCD_E_PIN);
    //LCD_RS_DDR |= (1<<LCD_RS_PIN); /* RS pin as output */
    //LCD_E_DDR |= (1<<LCD_E_PIN); /* E pin as output */


    //sbi(LCD_RS_PORT, LCD_RS_PIN); /* RS pin as 1 */
    //sbi(LCD_E_PORT, LCD_E_PIN); /* E pin as 1 */

    __delay_cycles((CtrlClockRate/1000)*15); /* wait 12ms or more after power-on */


    for (unsigned char init_c=0; init_c<4; init_c++)
    {
    if (init_c < 3) lcd_out_high(LCD_FUNCTION_8BIT_1LINE);
    else lcd_out_high(LCD_FUNCTION_4BIT_1LINE);
    lcd_e_toggle();
    __delay_cycles((CtrlClockRate/1000)*2);
    }
    /*
    lcd_out_high(LCD_FUNCTION_8BIT_1LINE);
    lcd_e_toggle();
    __delay_cycles((CtrlClockRate/1000)*2);

    lcd_out_high(LCD_FUNCTION_8BIT_1LINE);
    lcd_e_toggle();
    __delay_cycles((CtrlClockRate/1000)*2);

    lcd_out_high(LCD_FUNCTION_8BIT_1LINE);
    lcd_e_toggle();
    __delay_cycles((CtrlClockRate/1000)*2);

    lcd_out_high(LCD_FUNCTION_4BIT_1LINE);
    lcd_e_toggle();
    */
    /* set IO mode to 4bit */
    // main init for 4-bit interface
    //unsigned char i = 0;
    //for (i = 0; i < sizeof(byte_init); i++) lcd_write(byte_init[i], 0);


    /* from now the lcd only accepts 4 bit I/O, we can use lcd_command() */
    lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */
    lcd_command(LCD_DISP_OFF); /* display off */
    lcd_clrscr(); /* display clear */
    lcd_command(LCD_MODE_DEFAULT); /* set entry mode */
    lcd_command(dispAttr); /* display/cursor control */
    lcd_waitcmd(1);
    InitCGram();
    }


    Click image for larger version  Name:	Трекер Пи схема электрическая.jpg Views:	0 Size:	680.8 KB ID:	449703 Click image for larger version  Name:	fuse tracker.png Views:	0 Size:	38.9 KB ID:	449704 8042_sensor.rar echo_calc.rar tracker 2 main.rar

  • #2
    if you use the CODE tags ("#" icon) your code will be more readable:

    Code:
    void CharToStringDec(signed int inp)
    {
      unsigned char i;
      String[0]=String[1]=String[2]=String[3]=String[4]=0;
      // перевод
      for(i=0;i<;5;)
      {
        if((inp-segmentsDec[i])>=0)
        {
          inp-=segmentsDec[i];
          String[i]++;
        }
        else i++;
      }
    }​

    Comment

    Working...
    X