I2C и отключение прерываний noInterrupts()

Нет ответов
retroman
Offline
Зарегистрирован: 25.01.2015
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
#define FASTADC 1

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

//для пищалки
//#define R3_PIN       A0
#define SPEAKER_PIN  11
#define T2_WGM   0b010
#define T2_COMA  0b01
#define T2_CS    0b111

// параметры подстройки
int pMID=0;
int pMAX=0;
int pMIN=0;
int Sensv = 0; //(0 - макс чувствительность, минимум - около сотни наверное.)
int LastData[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int SetupData[200];
void delayms(int ms) {
  for (int i=0;i<ms;i++) delayMicroseconds(1000);
}
void setup() {
  //set port/pin  mode
  //DDRD = 0xFF;//all outputs
  //DDRC = 0x0F;//all inputs
  //DDRD = 0xFF;//all outputs
  //DDRC = B11111110;
  //TIMER INTERRUPT SETUP
  
  DDRD = DDRD | B00001110;
  PORTD = B00001110;

  //PORTD = 0;
  
lcd.init();
  lcd.backlight();
  lcd.print("START  ");
  
  #if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif

  //для динамика
 
  TCCR2A = (T2_COMA << 6) | (T2_WGM & 0b011);
  TCCR2B = ((T2_WGM & 0b100) << 1) | T2_CS;
  OCR2A = 18;
  // pinMode(R3_PIN, INPUT);
 // pinMode(SPEAKER_PIN, INPUT);  
 // pinMode(SPEAKER_PIN, OUTPUT);
  noInterrupts();
  beep(100);
  delayms(100);
  beep(100);
  delayms(100);
  beep(100);
  delayms(1000); 
  //посылаем пару тыщ импульсов в холостую просто так 
  //
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SETUP...  ");
  //while (1) 
  for (int i=0;i<200;i++) {  
  int t = SendPulse();  
  delayMicroseconds(6500); 
  }
  //посылаем 200 импульсов для настройки
  for (int i=0;i<200;i++) {
  int t = SendPulse();
  SetupData[i]=t;
  delayMicroseconds(6500);   
  }
  int tmin=1024;
  int tmax=0;
  unsigned long tnak=0;
  for (int i=0;i<200;i++) {
    tnak=tnak+SetupData[i];
    if (SetupData[i]>tmax) tmax = SetupData[i];
    if (SetupData[i]<tmin) tmin = SetupData[i];
  }  
 pMID = tnak/200;
 pMIN = tmin;
 pMAX = tmax;
 lcd.clear();
 lcd.setCursor(0,1);
 lcd.print(pMIN);
 lcd.setCursor(5,1);
 lcd.print(pMID);
 lcd.setCursor(10,1);
 lcd.print(pMAX);
 /* //for test
 for (int i=0;i<200;i++){
 lcd.setCursor(0,0);
 lcd.print(SetupData[i]);
 delayms(1000);
 lcd.setCursor(0,0);
 lcd.print("           ");
 }*/
 beep(500);
}
//Функция опроса кнопок модуля дисплея 1602 с кнопками.
//кнопки подключены к аналоговому порту (0) ардуино, если их подключаете как то иначе - функцию необходимо переделать
int getKey() {
  int value = analogRead(0);
  if (value>1000) return 0; //ничего не нажато
  if (value>580) return 1; //SELECT //Автонастройка.
  if (value>380) return 2; //ЛЕВО
  if (value>200) return 3; //ВНИЗ //Уменьшить порог (увеличивается чувствительность)
  if (value>80) return 4; //ВВЕРХ //Увеличить порог (снижается чувствительность)
  if (value<50) return 5; //ВПРАВО
}


void beepOn() {
  pinMode(SPEAKER_PIN, OUTPUT);
}
void beepOff() {
  pinMode(SPEAKER_PIN, INPUT); 
}

void beep(int msec) {
 beepOn();
 delayms(msec);
 beepOff(); 
}

int lmax = 10;
int mmax = 80;
int mmaxDefault = 80;
int lmaxDefault = 10;
int LL=lmax; //Длина звук. сигнала, циклов
int MM=mmax; //Длина тишины, циклов.

     int vo = 0;
     int vi = 0;
     int vod = 0;
     int vid = 0;
     unsigned long v1 = 0;
int SendPulse() {
    //--------------------------
    //Начало импульса
    //Мощный ключ открыт, усилитель выключен.
    PORTD = B00000010; 
    //-------------------------
    //Ожидаем 100мкс: 
    delayMicroseconds(100);
    //Закрываем ключ:
    PORTD = B00001010;
    //Открываем Q1:
    delayMicroseconds(12); //Защитный интервал
    PORTD = B00001110;
    delayMicroseconds(7);
    PORTD = B00001100;
    delayMicroseconds(100);
    PORTD = B00001110;
    int r = analogRead(1);
    return r;
}
int tControl = 0; //может изменяться от 0 до 15
int maxControl = 10; //кол-во измерений для расчета - чем больше количество измерений, тем меньше влияние шума.
                    //При тестировании в доме я выставлял 12-15 измерений для получения стабильной работы.
                    //В поле достаточно двух

int getMidControl() {
  int gm = 0;
  for (int i=0;i<maxControl;i++) {
    gm = gm+LastData[i];
  }
  int res = gm/maxControl;
  return res;
}

char Str2[11] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'\0'};
int V;
void(* resetFunc) (void) = 0; //сброс
int setupcount = 150;
void loop() {
  int k =0;
  //tone(SPEAKER_PIN,400);
  noInterrupts();
  //lcd.setCursor(0,0);
  //lcd.print(t);
  
  //Бит 3 = 1, J3
  //Бит 2 = 1  J4
  //Бит 1 = 1, J9
  PORTD = B00001110;
  delayms(2000);
  int ssl=0; 
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("      ");
    lcd.setCursor(12,1);
    lcd.print("    ");
    lcd.setCursor(12,1);
    lcd.print(Sensv);
    int a = 0;
    int val;
    LL=9;
    while (1) {
      k = getKey();
     if(tControl>=maxControl) tControl=0;
    int t = SendPulse();
    LastData[tControl] = t;
    int s = getMidControl();
    tControl++;
    //для тестирования
    //pMID = 781;
    //s = 520;
    //==================
    //==================================
    // ОЗВУЧКА ЦЕЛИ          V
    //==================================
    if (LL<lmax && LL>0) LL--;
    if (LL==0 && MM>0) MM--;
    if (MM==0) {
      LL = lmax;
      MM = mmax;
    } 
    if (setupcount>0) {
      if (s<=pMID) pMID = pMID-1;
      setupcount--;
    }
    int signal=(pMID-Sensv)-s; //для средних значений
    //int signal=(pMIN-Sensv)-s; //для минимальных
    if (signal>0 && LL==lmax) {
      beepOn();
      //if (signal<50) slevel = 2-
      int slevel = 200-signal; //цифра влияет на чувствительность пищалки. 400- редко пикает, затем часто до писка. 50 - быстро, затем писк.
      if (slevel<5) slevel = 5;
      mmax = slevel/5;
      MM = mmax;
      LL--;
    }
    if (signal<0 && LL==lmax) {
      mmax = mmaxDefault;
      MM = mmax;
    }
    int ssk = signal;
    signal = signal/5;
    if (signal<0) signal = 0;
    for (int i=0;i<10;i++) {
    if (i<signal) Str2[i] = 0xff;
    else Str2[i] = ' ';
    }
    if (LL==0) beepOff();
    //==================================
    //==================================
    //if (a==0) val = s;
    lcd.setCursor(0,1);
    lcd.print(Str2);
    a++;
    if (k==4) {
      Sensv++;
      lcd.setCursor(12,1);
      lcd.print("   ");
      lcd.setCursor(12,1);
      lcd.print(Sensv);
      beep(100);
      delayms(100);
    }  
    if (k==3) {
      Sensv--; 
      lcd.setCursor(12,1);
      lcd.print("   ");
      lcd.setCursor(12,1);
      lcd.print(Sensv);
      beep(100);
      delayms(100);
    }
    if (k==1) {
      
      pMID = t;
      Sensv = 0;
      setupcount = 150;
      lcd.setCursor(12,1);
      lcd.print("   ");
      lcd.setCursor(12,1);
      lcd.print(Sensv);
      beep(200);
      delayms(500);
      
      //resetFunc();
    };
    delayMicroseconds(1000); 

    lcd.setCursor(0,0);
    lcd.print(vi);
    lcd.print('.');
    lcd.print(vid);
    lcd.print("V  ");
    lcd.print(ssl);
    lcd.print(' ');
        if (a>200) {
      a = 0;
     //1 раз за 200 циклов измеряем напряжение аккумулятора и выводим на экран
     V = analogRead(4);
     //V = V-73; //калибровка во вольтметру
     unsigned long vt = V*125l;
     vt = vt/64l-140;
     vi = vt/100;
     vid = vt/10%10;
     ssl = ssk/10;
     //vi = v1*4;
    }
    //lcd.print(vid);    

    //lcd.print(vi);       
  }
}