EEPROM

barada
Offline
Зарегистрирован: 25.11.2013

приветствую. вот уже несколько дней подряд парюсь над одним проэктом, суть которого - управление синтезатором 9850. Это радиолюбительский проэкт, кто в теме - тот поймет для чего синтезатор. Проблема возникла тогда, когда решил запрограммировать "Памяти", тобишь выставляешь частоту, нажимаешь на кнопку, к примеру "D", потом выбераешь нужную ячейку на цифровой клавиатуре, оно записывает текущее число в ЕЕПРОМ и дальше по алгоритму. Для моих целей потребовалось сохранение еще одного действующего значения частоты, для того, чтоб потом использовать это значение в расчете частоты с учетом сдвига по частоте, для получения необходимой промежуточной частоты, вобщем не так важно, как то, что эта функция исправно работает, а вот функция простого запоминания с тем же алгоритмом работать не хочет. 

Значит память ЕЕПРОМ организована таким образом, что стандартная библиотека позволяет читать/писать ее побайтно. исходя из этого я организовал такую схему работы: для промежуточной частоты у меня используются первые 8 байтов: 0,1,2,3.....7. Код для записи у меня таков: 

///////////////////////////
void eeprom_write()
{
  //String eeprom_data;
  eeprom_data = (String)b;
    for(int i=start_addres; i<=start_addres+eeprom_data.length(); i++){
    EEPROM.write(i, eeprom_data[i]);
    //Serial.println(i);
    delay(100);
    Serial.println(eeprom_data.charAt(i));
  }
  start_addres=0;
}

eeprom_data и остальные переменные определены слудющим образом:

int start_addres;
int stop_addres;
String eeprom_data;

Функция записи вызывается:

if (key== 0x43){        ////////если нажата кнопка "С", тогда.....
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Set shift freq?");
      lcd.setCursor(0,1);
      lcd.print("  No-* / Yes-#");
lab5: 
      char key = kpd.get_key();
      if(key != '\0') {    
        tone(16, 5000, 5);
        if(key == 0x2A){       /////////если нажал кнопку "звездочка", тогда ничего                                                                   ///// не происходит
          lcd.clear();
          vfo();
        }
        if(key ==0x23) {          ///////если нажал кнопку "решетка", то тогда....
          start_addres = 0;    /
          stop_addres = 7;
          eeprom_clear();      //запись нулей в ячейки EEPROM с адресами от 0 до 7 
          eeprom_write();      //запись побайтно из переменной b в ячейки от 0 до 7
          lcd.clear();
          lcd.write("EEPROM alredy set");
          lcd.setCursor(0,1);
          lcd.print(eeprom_data);
          delay(1000);
          lcd.clear();
          LCD();
          goto lab2;
        }
      }
      goto lab5;           ////////////////go to the begin of Y/N EEPROM SET
    }

Напомню - этот участок кода рабтает четко и без нареканий. Проблема возникает тогда, когда я меняю значения 

start_addres = 0;
stop_addres = 7;

на 

start_addres = 8;
stop_addres = 15;

оно почему-то просто не хочет записывать то же самое значение переменной "b"  в ячейки памяти с адресами от 8 до 15. 

получается, что я хочу записывать первую память в промежуток 8-15, вторую в 16-23 и так далее. Код записи как для промежуточной частоты так и для памятей одинаковый, разные лишь значения 

start_addres
stop_addres

к слову в записи данных учавствует лишь стартовый адрес, в качестве стопового сумма значения стартового и длины строки. стоповый адрес участвует только в пердварительном стирании, ато мало ли.

кто что подскажет?

barada
Offline
Зарегистрирован: 25.11.2013

вот полный код

#include <AD9850.h>
//#include <string.h>
//#include <floattostring.h>
#include <EEPROM.h>
#include <rotary.h>
#include <stdlib.h>
#include <stdio.h>
#include <Wire.h>
#include <i2ckeypad.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(15, 14, 13, 12, 11, 10); 
#define ROWS 4
#define COLS 4
#define PCF8574_ADDR 0x38   // With A0, A1 and A2 of PCF8574A to ground I2C address is 0x38
i2ckeypad kpd = i2ckeypad(PCF8574_ADDR, ROWS, COLS);
int start_addres;
int stop_addres;
int dr = 200;         ////////zaderjka na drebezg
long stp=1000;
String eeprom_data;
AD9850 ad(5, 6, 7); // w_clk, fq_ud, d7
Rotary r = Rotary(2,3);
long RIT;
long b;
int TIMER = 0;
byte stat = 0; 
void setup()
{
  pinMode(4, INPUT_PULLUP);
  Serial.begin(57600);
  lcd.begin(16, 2);

  //ad.setfreq(fr);
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
  Serial.println("Ok");
  lcd.print("Ok");
  delay(500);
  lcd.clear();
  Wire.begin();
  kpd.init();
  tone(16, 3000);
  delay(50);
  noTone(16);
  delay(50);
  tone(16, 4000);
  delay(50);
  noTone(16);
}

void loop()
{
  menu();

}

/////////////////////MENU////////////////
void menu(){
  lcd.clear();
  lcd.setCursor(3,0);
  lcd.print("Main menu");
  lcd.setCursor(0,1);
  lcd.print("1-VFO+IF  2-VFO");
lab1:
  char key = kpd.get_key();
  char eepromdata[8]; 
  if(key != '\0') {    
    tone(16, 5000, 5);

    if(key == 0x31){          ////////if key = "1"
      for(int i=0; i<=7; i++){

        eepromdata[i] = EEPROM.read(i);
        delay(100);
      }
      RIT = atof(eepromdata);     ///////8862760
      vfo();
    }
    if(key == 0x32){          ////////if key = "2"
      RIT = 0;
      vfo();
    }

  }
  goto lab1;
}
///////////////VFO///////////////
void vfo(){
  ///stp = 100;
  lcd.clear();
  stat = 1;
  //lcd.clear();
  lcd.setCursor(2,0);
  lcd.print("<<--VFO-->>");
  delay(500);
  lcd.clear();
  LCD();
  delay(10);
lab2:                ///////////////////////////start loop vfo
  stat = 1;
  if (digitalRead(4) == LOW) {
    stp=stp*10;
    if (stp == 1000000){   
      stp = 10;
    }
    Serial.print("Step=");
    Serial.println(stp);
    lcd.clear();
    LCD();  
    tone(16, 5000, 20);
    TIMER = 0;
    delay(10);
label:               ////////////////////start loop step whilepressed
    while (digitalRead(4) == LOW){
      delay(20);
      TIMER++;
      if (TIMER == 50){
        TIMER = 0;
        menu();
      }

      goto label;
    }
  }

  char key = kpd.get_key();
  if(key != '\0') { 
    stat = 3;  
    tone(16, 5000, 5);

    if(key == 0x42){        ////////INPUT FREQ/////////BBBBBBBBBBBBB/////
      input_freq();
    }

    if (key== 0x43){        ////////SET SHIFT FREQ///////CCCCCCCCCCC///////
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Set shift freq?");
      lcd.setCursor(0,1);
      lcd.print("  No-* / Yes-#");
lab5: 
      char key = kpd.get_key();
      if(key != '\0') {    
        tone(16, 5000, 5);
        if(key == 0x2A){       //////////*******////////
          lcd.clear();
          vfo();
        }
        if(key ==0x23) {          //////////#######////////
          start_addres = 0;
          stop_addres = 7;
          eeprom_clear();      // write a 0 to  7 bytes of the EEPROM
          eeprom_write();
          lcd.clear();
          lcd.write("EEPROM alredy set");
          lcd.setCursor(0,1);
          lcd.print(eeprom_data);
          delay(1000);
          lcd.clear();
          LCD();
          goto lab2;
        }
      }
      goto lab5;           ////////////////go to the begin of Y/N EEPROM SET
    }

    if(key == 0x41){              ////////////EXIT VFO////////AAAAAAAAAAAAAAA
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("   Exit VFO?");
      lcd.setCursor(0,1);
      lcd.print("  No-* / Yes-#");
lab3:                 //////////////loop y/n menu    
      char key = kpd.get_key();
      if(key != '\0') {    
        tone(16, 5000, 5);
        if(key == 0x23){        ////////#########
          menu();
        }
        if(key ==0x2A) {        ///////**********
          lcd.clear();
          vfo();           ////////////////go to the begin of vfo()
        } 
      }
      goto lab3;           ///////////goto loop y/n menu
    }

    if(key == 0x44){      ///////////DDDDDDDDDDDD////////////
      lcd.clear();                                       ////
      lcd.setCursor(0,0);                                ////
      lcd.print("Set memory 0-9");                       ////
lab6:                                                    ////
      char key = kpd.get_key();                          ////
      if(key != '\0') {                                  ////
        tone(16, 5000, 5);                               ////
        if(key == 0x31){        ////////111111111////////////
          start_addres = 8;
          stop_addres = 15;
          eeprom_clear();      // write a 0 to  7 bytes of the EEPROM
          eeprom_write();
          lcd.clear();
          lcd.write("Memory 1 saved");
          lcd.setCursor(0,1);
          lcd.print(eeprom_data);
          delay(2000);
          lcd.clear();
          LCD();
          goto lab2;
        }                                                 ////
      }
      goto lab6;                                        ////

    }

  }
  goto lab2;

}///////end VFO///////



///////////////LCD////////////
void LCD(){
  //lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Step");
  lcd.setCursor(7,0);
  if(stp<1000){
    lcd.print(stp);
    lcd.print("Hz");  
  }
  if(stp>=1000){
    lcd.print(stp/1000);
    lcd.print("kHz");
  }
  //lcd.setCursor(13,0);

  lcd.setCursor(0,1);

  lcd.print("VFO");
  lcd.setCursor(5,1);

  if(b<=999){
    lcd.print(b);
    lcd.print("Hz      ");
  }
  else{
    if(b>=1000){
      lcd.print(float(b)/1000);
      lcd.print("kHz     ");
    }
  }


  //return;
}
//////////////////////////////
//////////////////////////////VALCODER INTERRUPT////////////////////

ISR(PCINT2_vect) {
  unsigned char result = r.process();
  if (result) {
    if (stat == 1){
      result == DIR_CW ?  b=b+stp : b=b-stp;
      float a = b + RIT;
      ad.setfreq(a );
      /* Serial.print("Freq: " );
       Serial.println(result == DIR_CW ?  b : b );
       Serial.print("a=");
       Serial.println(a);
       Serial.print("RIT");
       Serial.println(RIT);
       Serial.print("b=");
       Serial.println(b);*/
      //tone(16, result == DIR_CW ?  3000 : 2000, 20);      ///slow process
      LCD();
    }
    if (stat == 2){
      result == DIR_CW ?  RIT=RIT+stp : RIT=RIT-stp ;
      lcd.setCursor(0,2);
      lcd.print("RIT = ");
      lcd.print(RIT);

    }


  }
} 
////////////////////////////////////input freq///////////////
void input_freq(){

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Input new freq");
  lcd.setCursor(14,1);
  lcd.print("Hz");
  int i=0;
  char string[8] = {
    0, 0, 0, 0, 0, 0, 0, 0                };
  //double b;
  //b = atof(string);
lab4:                                 /////////////////looop freq input/////
  char key = kpd.get_key();
  if(key != '\0') {    
    tone(16, 1000, 5);



    /*if(i==8){
     lcd.clear();
     lcd.setCursor(0,1);
     lcd.print(string);
     
     b = atof(string); 
     long a = b + RIT;     
     ad.setfreq(a);
     
     vfo();
     }*/
    if(key == 0x31){
      string[i] = '1';
      //lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x32){
      string[i] = '2';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++; 
      delay(dr);
    }
    if(key == 0x33){
      string[i] = '3';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x34){
      string[i] = '4';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }

    if(key == 0x35){
      string[i] = '5';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x36){
      string[i] = '6';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x37){
      string[i] = '7';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x38){
      string[i] = '8';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x39){
      string[i] = '9';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    if(key == 0x30){
      string[i] = '0';
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print(string);
      lcd.setCursor(8,1);
      lcd.print("HZ      ");
      i++;
      delay(dr);
    }
    /*if(key == 0x2A){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("*");
     }
     if(key == 0x23){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("#"); 
     }*/
    if(key == 0x41){
      /*lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("A");*/
      delay(dr);
      vfo();
    }
    if(key == 0x42){

      b = atof(string); 
      long a = b + RIT;   
      ad.setfreq(a);
      vfo();
      delay(dr);
    }
    /*if(key == 0x43){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("C");
     }
     if(key == 0x44){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("D"); 
     }*/
  }
  goto lab4;                /////////////////goto loop freq input
}


///////////////////////////
void eeprom_clear()
{
  // write a 0 to  7 bytes of the EEPROM
  for (int i = start_addres; i <=stop_addres; i++){
    EEPROM.write(i, 0); 
    delay(100);
    //Serial.println(i);
  }
}
///////////////////////////
void eeprom_write()
{
  //String eeprom_data;
  eeprom_data = (String)b;
    for(int i=start_addres; i<=start_addres+eeprom_data.length(); i++){
    EEPROM.write(i, eeprom_data[i]);
    //Serial.println(i);
    delay(100);
    Serial.println(eeprom_data.charAt(i));
  }
  start_addres=0;
}




 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Из функции menu нет выхода. В ней вызывается vfo, из которой вызывается menu.
Море ненужных goto, особенно 114- строки.
С такой навороченной логикой контроллеру работать сложно .
В прерывания вывод в Serial.
Тут нужно все переписывать, потому что ошибки могут быть какими угодно.

barada
Offline
Зарегистрирован: 25.11.2013

было еще хуже, я дилетант и освоил мегу для того, чтоб сделать именно этот проект. оно все намучено, но работает и никаких тормозо, зависаний нет.

мою проблему с ЕЕПРОМ я хотел решить на стандартном примере, изменив правила перебора адресов - тоже не работает. где-то попадались записи о том, что работа с памятью немного кривая, черт его знает. если не заработает - буду разбираться с i2c eeprom. прибор получился хороший, хотелось бы хоть какой-то сервис. а на 114 строке была реализация входа в меню до того, как пришил i2c клавиатуру. ото полежит пару недель, потом сам сижу и разбираюсь - что я тут напрограммировал.