реклама на сайте
подробности

 
 
> Опять двадцать пять, динамическая индикация
Василий_Безкатег...
сообщение Jun 19 2007, 12:34
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 15-09-06
Из: г. Смолевичи (Минская область)
Пользователь №: 20 403



Прошу не пинать сильно. Искал сабж по форуму, читал, но чегой-то недопонял. Есть Atmega16, компилятор IAR. К МК подключены 2 семисегментных индикатора (какие -то старенькие советские индикаторы). Схема подключения такая- на сегменты идёт сигнал с порта С (PC0-PC7)через резисторы 82 Ом, общие провода индикаторов подсоединены подсоединены к порту D (PD0 и PD2). Чтобы горели сразу два индикатора с неизменяющимся двухзначным числом написал такую программу.
---------------------------------------------------------------------------------------------------------


#include <ioavr.h>
#include <iom16.h>
#include <intrinsics.h>
int main( void )
{
int digit[10];

DDRC=0xFF; //настраиваем порт С на вывод
digit[0]=0x3F;
digit[1]=0x06;
digit[2]=0x5B;
digit[3]=0x4F; // цифры от 0 до 9
digit[4]=0x66;
digit[5]=0x6D;
digit[6]=0x7D;
digit[7]=0x07;
digit[8]=0x7F;
digit[9]=0x6F;
while(1) // бесконечный цикл
{
DDRD=0x04; // подаём единицу на PD2 -инициализируем один индикатор
PORTC =digit[1]; // подаём код цифры
__delay_cycles(2500); // задержка
DDRD=0x01; // подаём единицу на PD0-инициализируем второй индикатор
PORTC =digit[0]; // подаём код другой цифры
__delay_cycles(2500); // задержка
}
}
---------------------------------------------------------------------------------------------
А вот чтобы допустим 2 индикатора динамически отображали счёт до 99, например, не получается ;-(
Программа такая:
-------------------------------------------------------------------------
#include <ioavr.h>
#include <iom16.h>
#include <intrinsics.h>
int main( void )
{
int i;
int j;
int digit[10];
DDRC=0xFF;

digit[0]=0x3F;
digit[1]=0x06;
digit[2]=0x5B;
digit[3]=0x4F;
digit[4]=0x66;
digit[5]=0x6D;
digit[6]=0x7D;
digit[7]=0x07;
digit[8]=0x7F;
digit[9]=0x6F;
while(1)
{
for (j=0;j<10;j=j+1)
for (i=0;i<10;i=i+1)
{DDRD=0x04;
PORTC =digit[j];
__delay_cycles(90000);

DDRD=0x01;
PORTC =digit[i];
__delay_cycles(5000000);
}
}
}
=================================================
Пните пожалуйста, что и как писать чтобы считала до 99 в бесконечном цикле и при этом 2 индикатора горели постоянно. На Си это первые опыты для микроконтроллеров, с начала начал осваивать ассемблер.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Василий_Безкатег...
сообщение Jun 28 2007, 06:20
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 15-09-06
Из: г. Смолевичи (Минская область)
Пользователь №: 20 403



С Вашей огромной помощью, с помощью сайта pcports(точка)ru (сообственно смодифицировал код с этого прекрасного сайта)и radiokot(точка)ru скомпилировал программу счёта до 99 секунд на двух индикаторах. Сделана она пока не так как советовал -rezident-, т.е задержка вывода на индикацию и переключения катодов осуществляется задержками в цикле, а не, например, процедурой delay_ms. Приведу исходный код с объяснениями, может кому-нибудь понадобится. Может есть неточности или неграммотный код, не обессудьте.
// катоды индикаторов подключены к PD0 и PD2, сегменты к PC0..PC7
#include "iom16.h"
#include "inavr.h"

short unsigned int Number = 0;
unsigned char Dig[10];
// В этих переменных хранятся цифры, которые нужно отобразить
char Disp6, Disp7;

// Функция выделяет цифры из трехзначного числа Number (вычисляет целое количество десяток в числе и присваивают их переменной Num2, единицы в остатке присваиваются переменной Num3)
void Display (short unsigned int Number)
{
unsigned char Num1, Num2, Num3;
Num2=0;
while (Number >= 10)
{
Number -= 10;
Num2++;
}
Num3 = Number;
Disp6 = Dig[Num2];
Disp7 = Dig[Num3];
}

void i1_init() //Инициализация портов ввода/вывода
{
DDRC = 0xFF;
DDRD |= (1 << 0) |(1 << 2);
}

void timer0_init()
{ // в коде настройки прерывания на секунду
OCR1AH =0x98; //в регистре OCR1A записываем количество тактов, которое отсчитает счётчик за 1 с. OCR1AL =0x96;// рассч
TCCR1B |= (1 << 3);//включаем режим CTC (описан в даташите в mode of operations для таймера1)
TCCR1B |= (1 << 2);//прескалер настроен на деление частоты на 256
TIMSK = (1 << 4);// настройка работы таймера по сравнению TCNT1 и OCR1A
}

void Dig_init()
{
Dig[0] = 0x3F;//0
Dig[1] = 0x06;//1
Dig[2] = 0x5B;//2
Dig[3] = 0x4F;//3
Dig[4] = 0x66;//4
Dig[5] = 0x6D;//5
Dig[6] = 0x7D;//6
Dig[7] = 0x07;//7
Dig[8] = 0x7F;//8
Dig[9] = 0x6F;//9
}

void main()
{
unsigned char j, k = 0;
Dig_init();
Display(0);
i1_init();
timer0_init();
SREG |= (1 << 7);
while(1)
{
for (j = 0; j <= 50; j++){} // Задержка для отображения цифры
(k == 1) ? k = 0 : k++;
for (j = 0; j<=30; j++){} // Задержка для переключения катода
switch (k)
{
case 0: PORTD=0x04;//Единицы
PORTC = Disp7;
break;
case 1: PORTD=0x01; // Десятки
PORTC = Disp6;

}
}
}

#pragma vector = TIMER1_COMPA_vect // процедура обработки прерывания таймера 1
__interrupt void Indic_change()
{
if (Number < 99)
Number++;// Увеличение отображаемого числа.
else
Number = 0;
Display(Number);

}

Сообщение отредактировал Василий_Безкатегорийный - Jun 28 2007, 06:26
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 20:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016