09.03.2021, Вторник, 00:56
09.03.2021 в 00:56
Секундомер на 999.9 сек. на семисегментном идикаторе
Схема:



Листинг в CodeVisionAVR:

Код

#include <io.h>
#include <delay.h>

static flash unsigned char digit[] =  
{
  (0b11000000), //0
  (0b11111001), //1
  (0b10100100), //2
  (0b10110000), //3
  (0b10011001), //4
  (0b10010010), //5
  (0b10000010), //6
  (0b11111000), //7
  (0b10000000), //8
  (0b10010000) //9  
};
  // с точкой
static flash unsigned char digitP[] =  
{
  (0b01000000), //0
  (0b01111001), //1
  (0b00100100), //2
  (0b00110000), //3
  (0b00011001), //4
  (0b00010010), //5
  (0b00000010), //6
  (0b01111000), //7
  (0b00000000), //8
  (0b00010000) //9  
};
   
static flash unsigned char razryad[] =  
{
  (1), //0
  (2), //1
  (4), //2
  (8), //3
};
   

void main(void)
{
  int i,j,k,n;
  PORTD=0x00;  
  DDRD=0b11111111;
  PORTC=0xFF;  
  DDRC=0b11111111;
   
while (1)
  {  
  for(n=0;n<10;n++)
  {  
  for(i=0;i<10;i++)
  {
  for(k=0;k<10;k++)
  {
  for(j=0;j<50;j++)
  {
  PORTD=digit[n];  
  PORTC=razryad[0];
  delay_ms(5);
  PORTD=digit[i];  
  PORTC=razryad[1];
  delay_ms(5);  
  PORTD=digitP[k]; // с точкой  
  PORTC=razryad[2];  
  delay_ms(5);
  PORTD=digit[j/5]; // десятые доли  
  PORTC=razryad[3];  
  delay_ms(5);  
  }  
  }
  }
  }
  }
}


Просмотров: 2853. Комментариев: 1
1 herozero   (30.09.2013 15:26) [Материал]
Почитал вот тут в pdf-e на стр. 41 такую вещь:

Цитата
необходимо  получить  гашение  на  короткий период  индикатора  при  смене  разрядов,  а  произойти  оно  может  при  подаче  уровней  логических нулей  на  сегменты  индикатора,  т.е.  во  все  разряды  порта  PortB,  к  которым  они  подключены.
Сделать это можно двумя командами:
Код
movlw b'00000000' ; записать все нули в регистр аккумулятор
movwf   PortB      ; записать содержимое аккумулятора в  PortB

Я  не  стал  особо  мудрствовать  и  добавил  эти  команды  в  начале  цикла  индикации  7-step  cycle  of digits.

Переводя на наши условия, получаем, что  PORTD надо "объединичивать" перед каждым включением каждого разряда, например так (далее привожу код самого внутреннего цикла):
Код
PORTD=0xff;
      PORTD=digit[n];      
      PORTC=razryad[0];    
      delay_ms(5);
      PORTD=0xff;    
      PORTD=digit[i];      
      PORTC=razryad[1];    
      delay_ms(5);
      PORTD=0xff;      
      PORTD=digitP[k]; // с точкой      
      PORTC=razryad[2];      
      delay_ms(5);
      PORTD=0xff;    
      PORTD=digit[j/5]; // десятые доли      
      PORTC=razryad[3];      
      delay_ms(5);

Тогда и в Протеусе всё работает правильно!
Остаётся только сделать, чтобы при нажатии кнопки (сперва, конечно, добавить саму кнопку) таймер не просто ресетился, а сохранял текущее состояние секунд (и тогда его уже точно можно будет назвать секундомером). Итог оформлю новостью)
PS: вот оно
Имя *:
Email:
Подписка:1
Код *: