Помогите сократить запись (очень простой вопрос)

Гриша
Offline
Зарегистрирован: 27.04.2014

Товарищи, пожалуйста, помогите сократить запись!

Задача, отправить 4 байта в регистры, сейчас я отправляю таким образом:

  void Write_MBI5026(byte HD, byte HS, byte MD, byte MS)
    {
          unsigned char i;
          digitalWrite(MBI5026_pinLE,LOW);  // 
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,MS&0x80);  //
            MS = MS<<1;                            //   
            digitalWrite(MBI5026_pinCLK,HIGH);
          }
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,MD&0x80);  // 
            MD = MD<<1;                            //   
            digitalWrite(MBI5026_pinCLK,HIGH);
          }  
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,HS&0x80);  //
            HS = HS<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }
         for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,HD&0x80);  //
            HD = HD<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }  
       digitalWrite(MBI5026_pinLE,HIGH);  
       digitalWrite(MBI5026_pinLE,LOW);    
    } 

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


  
  byte digits[16]={63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113};
  unsigned char j, k=0; // не тот формат к, потом поменяю
  byte D1, D2, D3, D4;
  long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 200;           // interval at which to update (milliseconds)
  
  int MBI5026_pinOE  = 6;    // MBIpin21. When (active) low, the output drivers are enabled; when high, all output drivers are turned OFF (blanked).
  int MBI5026_pinCLK = A1;   // MBIpin3. Clock input terminal for data shift on rising edge
  int MBI5026_pinSDI = A2;   // MBIpin2. Serial-data input to the shift register 
  int MBI5026_pinLE  = A3;   // MBIpin4.  Data strobe. Serial data is transferred to the output latch when LE is high. The data is latched when LE goes low.
  
  
  
  void Write_MBI5026(byte HD, byte HS, byte MD, byte MS)
    {
          unsigned char i;
          digitalWrite(MBI5026_pinLE,LOW);  // 
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,MS&0x80);  //
            MS = MS<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,MD&0x80);  //
            MD = MD<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }  
          for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,HS&0x80);  //
            HS = HS<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }
         for(i=8;i>=1;i--)
          {    
            digitalWrite(MBI5026_pinCLK,LOW);
            digitalWrite(MBI5026_pinSDI,HD&0x80);  //
            HD = HD<<1;                            // 
            digitalWrite(MBI5026_pinCLK,HIGH);
          }  
       digitalWrite(MBI5026_pinLE,HIGH);  
       digitalWrite(MBI5026_pinLE,LOW);    
    } 
  
  void setup() 
  {
    pinMode(MBI5026_pinOE,  OUTPUT);
    pinMode(MBI5026_pinCLK, OUTPUT);
    pinMode(MBI5026_pinSDI, OUTPUT);
    pinMode(MBI5026_pinLE,  OUTPUT);  
  }
  
  void loop() 
  {

    unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) 
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
    k=k+1;
    
  }
    
    D1=k /1000%10;
    D2=k /100%10;
    D3=k /10%10;
    D4=k %10;
    
      Write_MBI5026(digits[D2], digits[D1], digits[D4], digits[D3]);

   analogWrite(MBI5026_pinOE,128); //динамически разрешаем работу разным регистрам, для уменьшения потребления  
  }

Он с ошибкой, необходимо поменять переменную, а то в текущую все время не влезает (только до 244 счет, а потом обнуление), но меня это сейчас не беспокоит… потом это будут часы с градусником …

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

Отдельная четырежды вызываемая функция, отправляющая 1 байт?

Logik
Offline
Зарегистрирован: 05.08.2014

4 байта в лонг. один цикл на 32 прохода выпихивает из лонга. А это вобще конкурс какойто? Призы будут?

Гриша
Offline
Зарегистрирован: 27.04.2014

andriano пишет:

Отдельная четырежды вызываемая функция, отправляющая 1 байт?

ну опыта и знаний пока не хватает, я не могу понять как из

Write_MBI5026(byte HD, byte HS, byte MD, byte MS)

взять байты по очереди, конечно, можно еще один for и 4 раза if и менять значение переменной, но что-то мне это не очень нравится, может есть способ изящнее?

кейс - тоже думаю не изяшнее будет

Гриша
Offline
Зарегистрирован: 27.04.2014

Logik пишет:

4 байта в лонг. один цикл на 32 прохода выпихивает из лонга. А это вобще конкурс какойто? Призы будут?

  void Write_MBI5026(unsigned long D1, unsigned long D2, unsigned long D3, unsigned long D4)
    {
      unsigned long DSentD=(digits[D4] << 24) + (digits[D3] << 16) + (digits[D2] << 8) + digits[D1];   // sent in 32-bit packets
      
      unsigned char i;
      digitalWrite(MBI5026_pinLE,LOW);  // 

      for(i=32;i>=1;i--)
      {    
        digitalWrite(MBI5026_pinCLK,LOW);
        digitalWrite(MBI5026_pinSDI,DSentD&0x00000001);  
        DSentD = DSentD>>1;                          
        digitalWrite(MBI5026_pinCLK,HIGH);
      }    
      digitalWrite(MBI5026_pinLE,HIGH);  
      digitalWrite(MBI5026_pinLE,LOW);    
    }

чего-то очень много места занимает это лонг...

не, не конкурс, просто спросил, нужно же делать все красиво... :)

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015
 void Write_MBI5026(byte D1, byte D2, byte D3, byte D4)
{
unsigned long DSentD=((long)digits[D4] << 24) | ((long)digits[D3] << 16) | ((long)digits[D2] << 8) | digits[D1];
...

Только я не понял, откуда взялся массив digits[].

Аналог того, что в первом посте:

 void Write_MBI5026(byte D1, byte D2, byte D3, byte D4)
{
unsigned long DSentD=((long)D4 << 24) | ((long)D3 << 16) | ((long)D2 << 8) | D1;
...
Гриша
Offline
Зарегистрирован: 27.04.2014

andriano пишет:

Только я не понял, откуда взялся массив digits[].

массив digits[] ето просто набор отображающий цифры - указатель на сегменты индикатора...

я немного эксперементировал с несколькими кодами и в итоге, поменял названия переменных, в первом посте вставка кода 2 строка 2