Проблема с динамической индикацией
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Проблема с динамической индикацией
Уважаемые нужна помощь)) Atmega8, WINAvr, Proteus 7.6 SP2
Нужно сделать с помощью 2-ух 4-х разрядных индикаторов, 2 дешифраторов и 3-х кнопок устройство ввода/вывода (на индикаторы) 8-ми разрядного числа. Т.е. при нажатии соответствующей кнопки меняется разряд/величина числа, записывается в массив, а из него все это хоз-во выводится на индикатор))
На пинах PD5, PD6, PD7 расположены кнопки, осуществляющие сдвиг разряда и увелечение/уменьшение числа на 1. 2 дешифратора - один на число, другой на позицию (УРА! динамическая индикация). Все записывается в массив step и выводится на порт C.
Проблема: с порта С ничего нет, подозревается таймер/счетчик.
Прилагается: проект в WinAvr и проект в Proteus (извините за корявость, все делалось за 5 минут)
Нужно сделать с помощью 2-ух 4-х разрядных индикаторов, 2 дешифраторов и 3-х кнопок устройство ввода/вывода (на индикаторы) 8-ми разрядного числа. Т.е. при нажатии соответствующей кнопки меняется разряд/величина числа, записывается в массив, а из него все это хоз-во выводится на индикатор))
На пинах PD5, PD6, PD7 расположены кнопки, осуществляющие сдвиг разряда и увелечение/уменьшение числа на 1. 2 дешифратора - один на число, другой на позицию (УРА! динамическая индикация). Все записывается в массив step и выводится на порт C.
Проблема: с порта С ничего нет, подозревается таймер/счетчик.
Прилагается: проект в WinAvr и проект в Proteus (извините за корявость, все делалось за 5 минут)
- Вложения
-
- приложение.rar
- В Proteus укажите путь к hex коду программы.
- (50.05 КБ) 180 скачиваний
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
Наверное я не правильно озвучил тему: проблема не с индикацией, а с записью данных в масиив цифр и вывод их на индикатор.
Вообщем хелп ми)
Вообщем хелп ми)
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
Выяснил, что за проблема
программа не хочет заполнять массив, только не понятно почему
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Проблема с динамической индикацией
Нет. Прерывание по таймеру не работает.
Исправь свою ошибку в строке TIMSK=(0<<TOIE0); на TIMSK=(1<<TOIE0);
Да и поменяй местами вывод на индикацию и опрос кнопок. Лучше выводить данные на индикатор по прерыванию таймера, а кнопки опрашивать в основной функции(main).
Вот тебе красивый пример вывода значений на индикатор в прерывании таймера:
Вот всё работает. Разбирайся.
Исправь свою ошибку в строке TIMSK=(0<<TOIE0); на TIMSK=(1<<TOIE0);
Да и поменяй местами вывод на индикацию и опрос кнопок. Лучше выводить данные на индикатор по прерыванию таймера, а кнопки опрашивать в основной функции(main).
Вот тебе красивый пример вывода значений на индикатор в прерывании таймера:
Код: Выделить всё
volatile unsigned int step[8];
unsigned int j=0;
ISR(TIMER0_OVF_vect)
{
PORTB = j;
PORTC = step[j];
j++;
if (j==8){j=0;}
TCNT0=0x00;
}
Вот всё работает. Разбирайся.
Код: Выделить всё
#define F_CPU 3686400UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//***************************************************************************
volatile unsigned int step[8];
unsigned int j=0;
//***************************************************************************
//Вывод на индикатор по прерыванию таймера (каждый разряд по очереди)
ISR(TIMER0_OVF_vect)
{
PORTB = j;
PORTC = step[j];
j++;
if (j==8){j=0;}
TCNT0=0x00;
}
//***************************************************************************
int main(void)
{
unsigned int i=0;
TIMSK=(1<<TOIE0);
TCCR0=(1<<CS00)|(0<<CS01)|(0<<CS02);
PORTD=0xE0;
DDRD=0x1B;
PORTB=0x18;
DDRB=0x07;
PORTC=0x70;
DDRC=0x0F;
sei();
//----------
//Тут опрос кнопок по while
while(1)
{
if(!(PIND & (1<<PIND5))){i++; if(i>7) {i=0;}}
_delay_ms(20);
if(!(PIND & (0<<PIND5))){_delay_ms(20);}
if(!(PIND & (1<<PIND6))){step[i]++;if(step[i]>9){step[i]=0;}}
_delay_ms(20);
if(!(PIND & (0<<PIND6))){_delay_ms(20);}
if(!(PIND & (1<<PIND7))){if(step[i]==0){step[i]=9;}else{ step[i]--;}}
_delay_ms(20);
if(!(PIND & (0<<PIND7))){_delay_ms(20);}
}
}
I am DX168B and this is my favourite forum on internet!
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
Уху)))
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Проблема с динамической индикацией
Но!! У этой программы есть два минуса:
1 - Обработка кнопок. Надо реализовать так, чтобы цифра менялась только тогда, когда кнопку отпускают. Или хотя бы задержки чуть по длиннее (1000мс)
2 - Засветка индикатора. Для её устранения необходимо сначала погасить индикатор, поменять значения и только потом зажечь. Вот пример переработанной программы.
Тут необходимо соединить вывод МК PD0 c выводом RBI (№5) дешифратора 7448.
1 - Обработка кнопок. Надо реализовать так, чтобы цифра менялась только тогда, когда кнопку отпускают. Или хотя бы задержки чуть по длиннее (1000мс)
2 - Засветка индикатора. Для её устранения необходимо сначала погасить индикатор, поменять значения и только потом зажечь. Вот пример переработанной программы.
Тут необходимо соединить вывод МК PD0 c выводом RBI (№5) дешифратора 7448.
Код: Выделить всё
#define F_CPU 3686400UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//***************************************************************************
volatile unsigned int step[8];
unsigned int j=0;
//***************************************************************************
ISR(TIMER0_OVF_vect)
{
asm("сbi 0x12, 0"); //Гасим весь индикатор.
PORTB = j;
PORTC = step[j];
j++;
if (j==8){j=0;}
TCNT0=0x00;
asm("sbi 0x12, 0"); //После всех переключений зажжём его.
}
//***************************************************************************
int main(void)
{
unsigned int i=0;
TIMSK=(1<<TOIE0);
TCCR0=(0<<CS00)|(1<<CS01)|(0<<CS02);
PORTB=0x00;
DDRB=(1<<PB0)|(1<<PB1)|(1<<PB2);
PORTC=0x00;
DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3);
PORTD=(1<<PD0)|(1<<PD5)|(1<<PD6)|(1<<PD7);
DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4);
sei();
//----------
while(1)
{
if(!(PIND & (1<<PIND5))){i++; if(i>7) {i=0;}}
_delay_ms(20);
if(!(PIND & (0<<PIND5))){_delay_ms(20);}
if(!(PIND & (1<<PIND6))){step[i]++;if(step[i]>9){step[i]=0;}}
_delay_ms(20);
if(!(PIND & (0<<PIND6))){_delay_ms(20);}
if(!(PIND & (1<<PIND7))){if(step[i]==0){step[i]=9;}else{step[i]--;}}
_delay_ms(20);
if(!(PIND & (0<<PIND7))){_delay_ms(20);}
}
}
I am DX168B and this is my favourite forum on internet!
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
как раз хотел написать про кнопки, уже ответили))
а что означает 0x12??
а что означает 0x12??
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Проблема с динамической индикацией
Это физический адрес порта D
Компилятор не понимает, что такое PORTD в ассемблерной вставке и по этому я написал его адрес.
Все адреса МК можно узнать в файле m8def.inc, который можно найти в папке avr assembler из AVR Studio.
Компилятор не понимает, что такое PORTD в ассемблерной вставке и по этому я написал его адрес.
Все адреса МК можно узнать в файле m8def.inc, который можно найти в папке avr assembler из AVR Studio.
I am DX168B and this is my favourite forum on internet!
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
И еще вопрос:
Вот так PORTC=step[j], зараза кушает весь порт, хотя реально нужно всего 4 линии порта (отображение числа в 2-ом коде), подскажите как записать это в 4 линии, чтобы остальные были свободны,пробывал писать не чистым присваиванием, а с помощью |=, не получилось((.
Так же не могли бы вы подсказать, вот так можно запомнить первые 4 разряда числа и использовать дальше, например передать в какую-нибудь функцию число:
while(1){
//опросили кнопки ролучили заполненный массив
abc=step[0]*1000+step[1]*100+step[2]*10+step[3];
}
void temp(unsigned int temp);
{
//выполняем функцию
}
P.S.:В последних версиях библиотеки avr-libc, входящей в состав компилятора AVR-GCC, использующегося в WinAVR, больше не поддерживаются функции inp, outp, sbi и cbi.
Вот так PORTC=step[j], зараза кушает весь порт, хотя реально нужно всего 4 линии порта (отображение числа в 2-ом коде), подскажите как записать это в 4 линии, чтобы остальные были свободны,пробывал писать не чистым присваиванием, а с помощью |=, не получилось((.
Так же не могли бы вы подсказать, вот так можно запомнить первые 4 разряда числа и использовать дальше, например передать в какую-нибудь функцию число:
while(1){
//опросили кнопки ролучили заполненный массив
abc=step[0]*1000+step[1]*100+step[2]*10+step[3];
}
void temp(unsigned int temp);
{
//выполняем функцию
}
P.S.:В последних версиях библиотеки avr-libc, входящей в состав компилятора AVR-GCC, использующегося в WinAVR, больше не поддерживаются функции inp, outp, sbi и cbi.
Re: Проблема с динамической индикацией
Чтобы частично задействовать линии порта можно использовать следующую запись, например:
линии PD0 и PD0 порта PORTD нужно установить в состояние "1": PORTD |= _BV(PD1)|_BV(PD0);
линии PD0 и PD0 порта PORTD нужно установить в состояние "0": PORTD &= ~(_BV(PD1)|_BV(PD0));
Удачи!
линии PD0 и PD0 порта PORTD нужно установить в состояние "1": PORTD |= _BV(PD1)|_BV(PD0);
линии PD0 и PD0 порта PORTD нужно установить в состояние "0": PORTD &= ~(_BV(PD1)|_BV(PD0));
Удачи!
Хорошее - враг лучшего
- shootnikS
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср янв 05, 2011 17:51:35
- Откуда: Пенза
Re: Проблема с динамической индикацией
Совсем обижаете, это естественно, просто когда присваиваешь порту переменную (линии порта установлены на выход), она кушает весь порт, и начихать, что перед этим я 4 линии инициализировал как выход, а 4 оставшиеся как вход, 4 как вход просто переходят в состояние z (неопределенное)
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Проблема с динамической индикацией
shootnikS писал(а):...она кушает весь порт, и начихать, что перед этим я 4 линии инициализировал как выход, а 4 оставшиеся как вход...
Вот...
а если зайти на страничку ARV и почитать про динамическую индикацию, то там как раз есть описание виртуального порта, в котором можно не только отдельными линиями управлять, а даже линии разных портов использовать как единый порт, почитай очень полезная штуковина.
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Проблема с динамической индикацией
зараза кушает весь порт
вот так: (компилятор IAR AVR)
Код: Выделить всё
unsigned char Prev,data;
Prev = PORTB;
Prev &= ~(0x0F); // это в случае, когда необходимо оставить неизменными старшие 4 бита порта
// очищаем биты которые нужно изменить, которые нужно оставить не трогаем
Prev |= ( data&(0x0F) ); //очищаем ненужные 4 старших бита
PORTB = Prev;Ставим плюсы: )
