|
|
  |
Dot Matrix 5x7 (светодиодный точечный индикатор), Нужна помощь,консультация |
|
|
|
May 17 2015, 10:33
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Доброго всем дня ! Вот написал таки я программу для вывода символа на индикатор... Но ! Когда я перебираю строки матрицы, выставляя данные на столбцы, то все нормально, а когда наоборот... То получается такая ерунда: Когда выставлена минимальная задержка, то на индикаторе скажим так ничего не отображается, а когда большая, то отображается таже буква, только медленно соответственно. Как решить данную проблему ? Вразумите, чем эти переборы строк отличаются от перебора столбцов ? Ниже текст программы, во вложенияи исходник и модель в Протеусе, а также проект целиком на ATMEL STUDIO 6.2. CODE #include <avr/io.h> #include <util/delay.h>
unsigned char k; //unsigned char arr[7]={0x07, 0x09, 0x11, 0x1F, 0x11, 0x11, 0x11}; //A перебераем строки, выставля данные на столбцы. //unsigned char arr[5]={0x60, 0x5F, 0x3F, 0x3F, 0x00};//A перебераем столбцы, выставля данные на строки. unsigned char arr[5]={0x60, 0x57, 0x37, 0x37, 0x00};//A перебераем столбцы, выставля данные на строки.
int main(void) {
PORTA=0xFF; DDRA=0xFF;
PORTB=0xFF; DDRB=0xFF;
while (1) { /*for(k=0;k<=6;k++) //Перебераем строки Данные выставляем на столбцы. { //PORTB=0x00; PORTA=arr[k]; //PORTB=0xFF; PORTB&=~(1<<k); _delay_ms(1); PORTB=0xFF; }*/ for(k=0;k<=4;k++) //Перебераем столбцы Данные выставляем на строки. { //PORTB=0x00; PORTB=0xFF; PORTA=arr[k]; PORTB&=~(1<<k); PORTB=~PORTB; //_delay_ms(100); //PORTB=0xFF; _delay_ms(1000); //При такой задержке более или менее адекватно выводится символ. } } }
Сообщение отредактировал IgorKossak - May 17 2015, 19:04
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Прикрепленные файлы
1.rar ( 17.1 килобайт )
Кол-во скачиваний: 9
matrix5x7.rar ( 83.85 килобайт )
Кол-во скачиваний: 11
|
|
|
|
|
May 18 2015, 00:39
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Цитата(controller_m30 @ May 17 2015, 22:29)  Нельзя ли выложить схему картинкой (если она конечно небольшая)? Протеуса 8 нет, и ставить его я не умею  А по динамической индикации, в принципе, мог бы какую то мысль высказать, если бы видел схему. Схемы так таковой нет, а вот скрин с модели протеуса.
Эскизы прикрепленных изображений
|
|
|
|
|
May 18 2015, 09:03
|
Местный
  
Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309

|
Моё предложение такое. В программу надо добавить ещё один массив чисел, из которого будут браться значения "бегущей единицы" для вывода в PORTB (то что выводится сейчас - неправильно).
Массив arr1 для PORTA: 0x60, 0x57, 0x37, 0x37, 0x00 (инвертированный символ "А"). Массив arr2 для PORTB: 0x01, 0x02, 0x04, 0x08, 0x10 ("бегущая единица").
Далее, в каждом цикле выполняем следующее: 1. PORTB=0 ; гасим все столбцы 2. PORTA=arr1[k] 3. PORTB=arr2[k] ; включаем очередной столбец 4. задержка 10ms
Задержку, понятно, подбираем - мне кажется что 10-15ms должно быть нормально.
|
|
|
|
|
May 18 2015, 11:02
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Цитата(controller_m30 @ May 18 2015, 12:03)  Далее, в каждом цикле выполняем следующее: 1. PORTB=0 ; гасим все столбцы 2. PORTA=arr1[k] 3. PORTB=arr2[k] ; включаем очередной столбец 4. задержка 10ms Задержку, понятно, подбираем - мне кажется что 10-15ms должно быть нормально. Спасибо большее ! буду пробовать ! Я тут еще один очень интересный пример нашел Светодиодная матрица 8х8Пытаюсь разобраться, как автор формирует бегущую строку, символы и т.д. Не посмотрите ? А то мне тяжело, опыта маловато... Исходник этого проекта я прикрепил к сообщению.
Сообщение отредактировал uzzzer - May 18 2015, 11:18
|
|
|
|
|
Jun 15 2015, 11:36
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Цитата(controller_m30 @ May 18 2015, 14:53)  Сначала надо разобраться с выводом неподвижного символа. и только потом переходить к бегущей строке  Ну вот разобрался с выводом символов, подключил сдвиговые регистры еще. А вот с бегущей строкой никак пока. Прикрепил проект, в который находится еще и модель в Протеусе (папка 1\1\model) 5.DSN. А также схема в ПДФ.
Прикрепленные файлы
5.PDF ( 248.09 килобайт )
Кол-во скачиваний: 98
1.7z ( 212.56 килобайт )
Кол-во скачиваний: 8
|
|
|
|
|
Jun 15 2015, 11:47
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(uzzzer @ Jun 15 2015, 14:36)  А вот с бегущей строкой никак пока. Когда выводите "неподвижную" строку, то всегда вывод начинается с одного и того же места - с начала строки. А для "бегущей", сделайте указатель на текущую позицию вывода "бегущей". И сделайте таймер, по которому этот указатель смещается на следующую позицию выводимого текста. Таймер, скажем на 1/4 или 1/2 или на 1 сек... А остальное, тоже как и в неподвижной. Сделайте вывод строки, как функцию, в которой передается начало строки и вся строка выводится, но не до конца строки, а до конца и потом до того места, откуда она начинается... Как бы круговой буфер... А над этой функцией надстройте ту, которая работает с таймером и меняет положение указателя начала...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Jun 15 2015, 12:17
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Цитата(iosifk @ Jun 15 2015, 14:47)  Когда выводите "неподвижную" строку, то всегда вывод начинается с одного и того же места - с начала строки. А для "бегущей", сделайте указатель на текущую позицию вывода "бегущей". И сделайте таймер, по которому этот указатель смещается на следующую позицию выводимого текста. Таймер, скажем на 1/4 или 1/2 или на 1 сек... А остальное, тоже как и в неподвижной. Сделайте вывод строки, как функцию, в которой передается начало строки и вся строка выводится, но не до конца строки, а до конца и потом до того места, откуда она начинается... Как бы круговой буфер... А над этой функцией надстройте ту, которая работает с таймером и меняет положение указателя начала... Я пытался реализовать нечто подобное, все упирается в реализацию того самого кругового буфера. Как его организовать ? Дело в том, что у меня схема немного специфичная, у меня происходит управление перебором столбцов, а данные пишутся через регистры в столбцы. Если все наоборот делать (таких примеров в сети туча !), то проблема решается просто побитывым сдвигом строк (ну типа вертикальной развертки), а у меня получается, что двигать нужно не битики, а элементы массива, вот тут я и спотыкаюсь.
Сообщение отредактировал uzzzer - Jun 15 2015, 12:18
|
|
|
|
|
Jun 15 2015, 13:06
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(uzzzer @ Jun 15 2015, 15:17)  Я пытался реализовать нечто подобное, все упирается в реализацию того самого кругового буфера. Как его организовать ? Дело в том, что у меня схема немного специфичная, у меня происходит управление перебором столбцов, а данные пишутся через регистры в столбцы. Если все наоборот делать (таких примеров в сети туча !), то проблема решается просто побитывым сдвигом строк (ну типа вертикальной развертки), а у меня получается, что двигать нужно не битики, а элементы массива, вот тут я и спотыкаюсь. Сделайте иерархию функций. Самая нижняя - динамическая индикация. Над ней- вывод символа. Над ней - вывод строки. Над выводом строки - вывод нескольких строк... И т.д.
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Jun 17 2015, 12:27
|

Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 7-10-10
Из: Москва
Пользователь №: 59 985

|
Цитата(iosifk @ Jun 15 2015, 16:06)  Сделайте иерархию функций. Самая нижняя - динамическая индикация. Над ней- вывод символа. Над ней - вывод строки. Над выводом строки - вывод нескольких строк... И т.д. Тут возникла проблема: Когда вызываю функцию void printstr(void); программа работает корректно, данные передаются в регистры и строка высвечивается полностью, а когда void printstr2(char *arr), то высвечивается только первый символ, как будто бы функция прочитывает только первый символ в строке. А так в принципе обе функции идентичны, за исключением параметров. CODE #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> //#include <avr/eeprom.h> #include "font5x7.h" #include "spi.h"
//#define pause 600 #define PORT_column PORTC #define DDR_column DDRC #define N1 23 #define N2 120 char line [N2]; //unsigned char Buffer [N2]; char string [] = "ATMEL ATMEGA HELLO WORLD"; void SPI_WriteRowbycollumn(int qi, char *data, int n); void printstr(void); void printstr2(char *arr);
void printstr(void) { int j,k; char qs[N2]; char array_qs[N2]; while(1)//for (;;)//бесконечный цикл для движения строки { for(k=0; k<=(sizeof(string)-2);k++) { qs[k] = string[k] -32; for(j=0;j<=4;j++) { array_qs[j+5*k]=pgm_read_byte(&simbols[j+5*(qs[k])]); line[j+5*k] =array_qs[j+5*k]; } } } }
void printstr2(char *arr) { int j,k; char qs[N2]; char array_qs[N2]; while(1)//for (;;)//бесконечный цикл для движения строки { for(k=0; k<=(sizeof(arr)-2);k++) { qs[k] = arr[k] -32; for(j=0;j<=4;j++) { array_qs[j+5*k]=pgm_read_byte(&simbols[j+5*(qs[k])]); line[j+5*k] =array_qs[j+5*k]; } } } }
void SPI_Init(void) { /*настройка портов ввода-вывода все выводы, кроме MISO выходы*/ SPI_DDRX = (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO); SPI_PORTX = (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO); /*разрешение spi,старший бит вперед,мастер, режим 0*/ SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0); SPSR = (0<<SPI2X); }
void SPI_WriteRowbycollumn(int qi, char *data, int n) { SPI_PORTX &= ~(1<<SPI_SS); for(int i=0;i<=n;i++) { SPDR = data[(qi-1)+5*i]; while(!(SPSR & (1<<SPIF))); } SPI_PORTX |= (1<<SPI_SS); }
ISR (TIMER1_COMPA_vect)//Подсветка разрядов индикатора в обработчике прерывания { static int q;//Внутренный счётчик отображаемого разряда q++; switch(q) //Перебор отображаемого сейчас разряда { case 1:PORT_column =0x00;//&= ~_BV(PC7);//Гасим предыдуший разряд SPI_WriteRowbycollumn(q, line,N1); PORT_column |= _BV(PC0);//Посвечиваем следующий разряд break; case 2:PORT_column =0x00;//&= ~_BV(PC0); SPI_WriteRowbycollumn(q, line,N1); PORT_column |= _BV(PC1); break; case 3:PORT_column =0x00;//&= ~_BV(PC1); SPI_WriteRowbycollumn(q, line,N1); PORT_column |= _BV(PC2); break; case 4:PORT_column =0x00;//&= ~_BV(PC2); SPI_WriteRowbycollumn(q, line,N1); PORT_column |= _BV(PC3); break; case 5:PORT_column =0x00;//&= ~_BV(PC3);//Гасим предыдуший разряд SPI_WriteRowbycollumn(q, line,N1); PORT_column |= _BV(PC4);//Посвечиваем следующий разряд break; case 6:PORT_column =0x00;//&= ~_BV(PC4); q=0; break; default: break; } }
int main (void) { SPI_Init(); //int i,j,l,a,k; int i,l; //char qs[N2]; DDR_column = 0xFF;//порт столбцов как выход TCCR1B |= 1<<WGM12 | 1<<CS11 | 1<<CS10; //Start timer1 in CTC mode with prescaler of 64 TIMSK |= 1<<OCIE1A; //Enable compare match interrupt OCR1A = 0x00BB; //Set compare value for 1 mSec //char array_qs[N2]; asm("sei");//sei ();//общее разрешение прерывания
for (i = 0, l = strlen(string); i < l / 2; i++) { char c = string[i]; string[i] = string[l - i - 1]; string[l - i - 1] = c; }
//printstr();
printstr2(string);
/*for (;;)//бесконечный цикл для движения строки { for(k=0; k<=(sizeof(string)-2);k++) { qs[k] = string[k] -32; for(j=0;j<=4;j++) { array_qs[j+5*k]=pgm_read_byte(&simbols[j+5*(qs[k])]); line[j+5*k] =array_qs[j+5*k]; } } }*/ }
Сообщение отредактировал uzzzer - Jun 17 2015, 12:28
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|