Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Dot Matrix 5x7 (светодиодный точечный индикатор)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
uzzzer
Доброго всем дня !
Вот написал таки я программу для вывода символа на индикатор... Но ! Когда я перебираю строки матрицы, выставляя данные на столбцы, то все нормально, а когда наоборот... То получается такая ерунда: Когда выставлена минимальная задержка, то на индикаторе скажим так ничего не отображается, а когда большая, то отображается таже буква, только медленно соответственно. Как решить данную проблему ? Вразумите, чем эти переборы строк отличаются от перебора столбцов ?
Ниже текст программы, во вложенияи исходник и модель в Протеусе, а также проект целиком на 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); //При такой задержке более или менее адекватно выводится символ.
}
}
}
controller_m30
Нельзя ли выложить схему картинкой (если она конечно небольшая)?
Протеуса 8 нет, и ставить его я не умею blush.gif laughing.gif А по динамической индикации, в принципе, мог бы какую то мысль высказать, если бы видел схему.
uzzzer
Цитата(controller_m30 @ May 17 2015, 22:29) *
Нельзя ли выложить схему картинкой (если она конечно небольшая)?
Протеуса 8 нет, и ставить его я не умею blush.gif laughing.gif А по динамической индикации, в принципе, мог бы какую то мысль высказать, если бы видел схему.


Схемы так таковой нет, а вот скрин с модели протеуса.
controller_m30
Моё предложение такое.
В программу надо добавить ещё один массив чисел, из которого будут браться значения "бегущей единицы" для вывода в 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 должно быть нормально.
uzzzer
Цитата(controller_m30 @ May 18 2015, 12:03) *
Далее, в каждом цикле выполняем следующее:
1. PORTB=0 ; гасим все столбцы
2. PORTA=arr1[k]
3. PORTB=arr2[k] ; включаем очередной столбец
4. задержка 10ms
Задержку, понятно, подбираем - мне кажется что 10-15ms должно быть нормально.


Спасибо большее ! буду пробовать !
Я тут еще один очень интересный пример нашел Светодиодная матрица 8х8
Пытаюсь разобраться, как автор формирует бегущую строку, символы и т.д. Не посмотрите ? А то мне тяжело, опыта маловато...
Исходник этого проекта я прикрепил к сообщению.
controller_m30
Сначала надо разобраться с выводом неподвижного символа. и только потом переходить к бегущей строке wink.gif
uzzzer
Цитата(controller_m30 @ May 18 2015, 14:53) *
Сначала надо разобраться с выводом неподвижного символа. и только потом переходить к бегущей строке wink.gif


Ну вот разобрался с выводом символов, подключил сдвиговые регистры еще. А вот с бегущей строкой никак пока.
Прикрепил проект, в который находится еще и модель в Протеусе (папка 1\1\model) 5.DSN. А также схема в ПДФ.
iosifk
Цитата(uzzzer @ Jun 15 2015, 14:36) *
А вот с бегущей строкой никак пока.

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


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

Сделайте иерархию функций. Самая нижняя - динамическая индикация. Над ней- вывод символа. Над ней - вывод строки. Над выводом строки - вывод нескольких строк... И т.д.
uzzzer
Цитата(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];
}
}
}*/

}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.