Автор Тема: 10bit-ов брояч?  (Прочетена 19780 пъти)

kalos

  • Робо-Новак
  • *****
  • Публикации: 14
    • Профил
10bit-ов брояч?
« -: Юни 19, 2011, 01:48:26 pm »
Здравейте,
имам нужда от помощ.
Какъв е най-добрия начин за десетичен 10-битов брояч т.е. имам 10 светодиода на дигиталните изходи (4-13), брояча да започне от 0 и да добавя през 1 сек. по една еденица. Като моментното чсило да се "изписва" чрез светодиодите.
Подобно на това http://www.youtube.com/watch?v=t3Ol3Dxxl0s
но без но без 74HC595

Малко съм разсеян в момента, дано да стане ясно какъв им е въпроса.
Поздрави :)

tommyboy

  • Направо Робот! :)
  • *****
  • Публикации: 416
    • Профил
10bit-ов брояч?
« Отговор #1 -: Юни 19, 2011, 05:01:32 pm »
а защо без 74HC595

zen

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 121
    • Профил
10bit-ов брояч?
« Отговор #2 -: Юни 19, 2011, 05:22:27 pm »
Ето ти кода. Имай предвид, че не съм го тествал. По късно ще го тествам и евентуално коригирам.


 long decimal;  
 char binary[80];
 
 
void setup() {                
   Serial.begin(9600);
   decimal = 0;
   
   for(int br = 4;br<14;br++)
   {
    pinMode(br, OUTPUT);  
   
   }
 
}

void loop() {
decimal++;
if(decimal==1024)
{  
decimal = 0;
}

   
dec2bin(decimal,binary);

for(int br = 4;br<14;br++)
{
  if(binary[br-4] == 1)
  {
    digitalWrite(br, HIGH);    
  }
  else
  {
     digitalWrite(br, LOW);    
  }
   
}


Serial.print("Dec:");Serial.println(decimal);
Serial.print("Bin:");Serial.println(binary);
Serial.println(" ");

delay(1000);
 
}


void dec2bin(long decimal, char *binary)
{  
int  k = 0, n = 0;  
 
int  remain;  
char temp[80];  

do  
{
remain    = decimal % 2;    
decimal   = decimal / 2;  
temp[k++] = remain + '0';  
}
while (decimal > 0);  

while (k >= 0)
    binary[n++] = temp[--k];
   binary[n-1] = 0;        
}

kalos

  • Робо-Новак
  • *****
  • Публикации: 14
    • Профил
10bit-ов брояч?
« Отговор #3 -: Юни 19, 2011, 06:26:26 pm »
Тествах това което си написал, брояча работи и подава данните към сериния порт, но не се отразява на светодиодите.
tommyboy - в момента нямам налични, а програмата ми е да тествам една схема.
По-точно имам една охранителна ролетка с дистанционно (ето интегралната схема на дистацнионното http://www.honsitak-taiwan.com/list.files/list_pdf/hk526e-2.pdf) със постоянен код.
Идеята ми е да закача ардуиното към наличното ми дистанционно за да определя времето необходимо за отваряне на ролетката.
Към момента в дистанционното има 10битов "избирач" опеделящ ключа за защита.

kalos

  • Робо-Новак
  • *****
  • Публикации: 14
    • Профил
10bit-ов брояч?
« Отговор #4 -: Юни 19, 2011, 06:30:17 pm »
Преди малко тествах ето този код:
/*
  Binary counter
  Counts up and prints result to LEDs, for practicing binary counting.

  This code is in the public domain.
*/

int startPin = 2;
int everyNthPin = 1;
int totalPins = 12;
int delayInms = 500;


void setup() {              
  for (int i = startPin; ( i / everyNthPin ) - startPin < totalPins;  i += everyNthPin) {
    pinMode(i, OUTPUT);  
  }
}

int expo( int base , int power) {
  int total = base;
  for( int times = power; times > 1; times--) {
    total *= base;
  }
  return total;
}

int i = 0;

void loop() {
  int carry = i;
  int currentbit = 0;
 
  int j = startPin;
  for (; ( j / everyNthPin ) - startPin < totalPins;  j += everyNthPin)  {
    currentbit = carry % 2;
    carry = carry / 2;
   
    if (currentbit > 0)  {
      digitalWrite(j, HIGH);
    } else {
      digitalWrite(j, LOW);
    }
  }

  i++;
  if (i >= expo(2 , totalPins) ) i = 0;
  delay(delayInms);
}

Работи, но нещо не ми е ясно как :)
дали ще може някой да ми разясни?
Благодаря предварително.

zen

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 121
    • Профил
10bit-ов брояч?
« Отговор #5 -: Юни 19, 2011, 07:17:15 pm »
Оправих кода и го тествах. Сега е ОК. Ако искаш мога да ти напиша и коментари:

long decimal;  
 char binary[10];
 
 
void setup() {                
   Serial.begin(9600);
   decimal = 0;
   
   for(int br = 4;br<14;br++)
   {
      pinMode(br, OUTPUT);    
   }  
}

void loop()
{
  decimal++;
  if(decimal==1024)
  {  
    decimal = 0;
    for(int br = 0; br < 10; br++)
      binary[br] = '0';
  }

   
dec2bin(decimal,binary);


for(int br = 4;br<14;br++)
{
  if(binary[br-4] == '1')
  {
    digitalWrite(br, HIGH);      
  }
  else
  {
     digitalWrite(br, LOW);      
  }
   
}

Serial.println(binary);
 
}


void dec2bin(long decimal, char *binary)
{  
  int  k = 0;  
 
  int  remain;  
  char temp[10];    

  do    
  {
    remain    = decimal % 2;    
    decimal   = decimal / 2;  
    temp[k++] = remain + '0';  
  }
  while (decimal > 0);    

  for(int br = 0;br < k;br++)
    binary[br] = temp[br];  
}
 

kalos

  • Робо-Новак
  • *****
  • Публикации: 14
    • Профил
10bit-ов брояч?
« Отговор #6 -: Юни 19, 2011, 08:39:33 pm »
Ще съм ти благодарен, ако ми го разясниш.

zen

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 121
    • Профил
10bit-ов брояч?
« Отговор #7 -: Юни 19, 2011, 08:51:00 pm »
Ето. Ако пак не е ясно кажи. За да конвертирам десетично в двуично използвам алгоритъма с делене на 2 и проверка на остатъка:


 long decimal; // променлива за десетично представяне
 char binary[10]; //10 мерен масив, в който пазя двуичните стойности
 
 
void setup() {                
   Serial.begin(9600);   // инициализиране на серийният порт
   decimal = 0;          
   
   for(int br = 4;br<14;br++) // дефиниране на всички  пинове от 4 до 13 като изходи
   {
      pinMode(br, OUTPUT);    
   }  
}

void loop()
{
  decimal++; // добавяне на 1 на променливата
  if(decimal==1024) //ако decimal e 1024 превъртам брояча и почвам пак от 0 (1023 е 10 единици в двучен код 1111111111)
  {  
    decimal = 0;
    for(int br = 0; br < 10; br++) //инициализирам и масива наново
      binary[br] = '0';
  }

   
dec2bin(decimal,binary);  // конвертирам decimal в binary


for(int br = 4;br<14;br++) // обхождане на пиновете
{
  if(binary[br-4] == '1') // проверка на съответният елемент от масива дали е 1. Първият елемент е на 4 пинм, така че всеки път вадя 4
  {
    digitalWrite(br, HIGH);      // ако е 1 свети
  }
  else
  {
     digitalWrite(br, LOW);      // ако не е 1, т.е. 0, не свети
  }
   
}

Serial.println(binary);  // пращам двуичното число на серийния само за проверка
 
}


void dec2bin(long decimal, char *binary)
{  
  int  k = 0;  
 
  int  remain;  
  char temp[10];    

  do    
  {
    remain    = decimal % 2;    // проверявам остатъка при делене на 2
    decimal   = decimal / 2;    // деля на 2 за следващият ход на цикъла
    temp[k++] = remain + '0';   // добавям остатъка на следващата позиция в масива
  }
  while (decimal > 0);    

  for(int br = 0;br < k;br++) // копирам временният масив в binary
    binary[br] = temp[br];  
}

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
10bit-ов брояч?
« Отговор #8 -: Юни 20, 2011, 10:43:12 am »
Няма смисъл да конвертираш в двочина бройна система. Ако пиновете са ти на един порт може просто да записвате десетичното число в регистъра на порта и това директно ще изкара двоичната му стойност на пиновете.
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

zen

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 121
    • Профил
10bit-ов брояч?
« Отговор #9 -: Юни 20, 2011, 10:58:09 am »
Не знам дали ще стане така, защото тук говорим за 10 бита

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
10bit-ов брояч?
« Отговор #10 -: Юни 20, 2011, 01:52:34 pm »
Не е споменато за какъв контролер говорим, но виждам някакъв код за Ардуино, така че предполагам, че контролерът е 8 битов. На езика на ардуино не знам дали ще стане, но под С нещата изглеждат така. Да речем че 8 от пиновете са ти на PORTB и другите 2 са ти на PORTA_PIN0 и PORTA_PIN1. Числото, което искаш да запишеш, нека е num. Тогава правиш така:

PORTB = num;
PORTA &= 0xFC;
PORTA |= (num >> 8);

Разбира се това работи за конкретен случай, когато ледовете са наредени последователно по пиновете. Ако дадеш схема на свързване, кой лед на кой пин е, мога да ти дам точен код. Ако светодиодите не са последователно по порта, тогава може да се използва union структура с 10 битови полета и една променлива, в която да се пише, но това за да стане трябва да се знае и схемата и езика и компилатора, на който се прави.
Иначе теоритично правилно си го конвертирал в двоична бройна система, само че тук става въпрос за микроконтролер (тоест имаш достъп до много ниско ниво, а там всичко е двоично), което прави задачата доста по-проста. Това е ключовата разлика между ембедед програмирането и програмирането от високо ниво, трябва да използваш всеки възможен ресурс най-оптимално.
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

zen

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 121
    • Профил
10bit-ов брояч?
« Отговор #11 -: Юни 20, 2011, 05:56:40 pm »
Прав си. Така ще стане. Имай предвид все пак, че съм си програмист от по-горно ниво и все още ми е малко трудно да си пречупя мисленето  :lol:

kalos

  • Робо-Новак
  • *****
  • Публикации: 14
    • Профил
10bit-ов брояч?
« Отговор #12 -: Юни 21, 2011, 10:40:21 am »
До колкото съм запознат с портовете на ардуиното в момента използвам всички пинове от PORTB и няколко от PORTC (за да не закачам сериината връзка).

zen благодаря ти за разяснението!