Форум по микроконтроллерам: Программирование c нуля в AVRStudio 5 - Форум по микроконтроллерам

Перейти к содержимому

  • 13 Страниц +
  • « Первая
  • 11
  • 12
  • 13
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

Программирование c нуля в AVRStudio 5 основы и основные понятия

#241 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 10 Январь 2016 - 14:09

извините, больше не буду :) как я понял команда lpm по умолчанию загружает байт в регистр r0, а можно вместо r0 указать другой регистр? а то как то не понятно почему именно r0 :(
0

#242 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 10 Январь 2016 - 14:17

и еще если конечно не трудно, как без кнопок выводить эти значения из массива по очереди? скиньте ;) не обижайтесь на меня у меня просто позднее зажигание, пока не увижу не пойму
0

#243 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 12 Январь 2016 - 18:36

Просмотр сообщенияMUVAZIN (10 Январь 2016 - 14:09) писал:

как я понял команда lpm по умолчанию загружает байт в регистр r0, а можно вместо r0 указать другой регистр? а то как то не понятно почему именно r0 :(

Правильно. Так придумали разработчики и изменить мы не можем. Ну, а если Вам так хочется, то можно перенести с R0 в любой другой регистр и пользоваться как обычно, только смысла не вижу делать лишние движения...

Просмотр сообщенияMUVAZIN (10 Январь 2016 - 14:17) писал:

и еще если конечно не трудно, как без кнопок выводить эти значения из массива по очереди?

В плане автоматического пересчета, то инкриментируйте значение и выводите его на дисплей через некоторый промежуток времени, сделав задержку.
0

#244 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 14 Январь 2016 - 19:35

спасибо, я просто не понемал откуда взялся этот регистр он же не объявлялся в ночале и ему имя не присваивали поэтому я запутался и еще раз спасибо ;)
0

#245 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 12 Февраль 2016 - 12:21

ребята если не трудно выложите код для управления 8х8 матрицей
0

#246 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 14 Февраль 2016 - 19:20

Просмотр сообщенияMUVAZIN (12 Февраль 2016 - 12:21) писал:

ребята если не трудно выложите код для управления 8х8 матрицей

Сама матрица выглядит следующим образом:
Изображение
Для управления светодиодной матрицей в самом простом случае нужно подключить 2 порта, например порт В и порт С (микроконтроллер ATMega8), т.е. будет задействовано 16 выводов (что весьма нерационально).
Принцип: Один порт последовательно "перебирает" столбики с частотой не менее 200Гц т.е выполняет развертку, второй порт определяет "картинку". Один кадр записывается в виде программной матрицы. Что вы запишите в программную матрицу, то и будет выводиться. На практике, для управления светодиодной матрицей часто используются сдвиговые регистры, управляемые последовательным протоколом SPI, или специальные аппаратные драйвера со встроенной памятью. Для каждого случая нужно писать свою программу управления. "Студенческий" вариант управления я вам подсказал. Если вы освоили принципы динамической индикации с 7-сегментными индикаторами, то вам не составит большого труда дописать программу для светодиодной матрицы. Если у вас, что то не будет получаться, то мы вам поможем, но писать программу за вас не будем. Удачи!

P.S. Посмотрите ссылки:
http://microsin.net/...indication.html
http://www.doneathome.ru/archives/517

Сообщение отредактировал galrad: 14 Февраль 2016 - 20:01

0

#247 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 23 Февраль 2016 - 00:00

Немного "покопавшись" среди своих проектов, нашел одну из первых программ, для выведения информации на светодиодные матрицы. Использовал микроконтроллер ATmega8, подключение непосредственно к портам (в реальной схеме для ограничения тока светодиодов, нужно подключать микроконтроллер к матрице через резисторы в 220-300 Ом) Проект сделан в Протеусе, поэтому резистов нет (эмуляция работает и без них). Подключение простейшее.
Изображение
На матрицу последовательно выводится слово "ПРИВЕТ", программа написана на языке СИ, но при желании ее можно легко дезассемблировать в режиме отладки. Программа простейшая, поэтому мне кажется особых объяснений не требуется...
Программа на СИ
#define F_CPU 8000000UL         			// установка частоты микроконтроллера
#include <avr/io.h>             			// стандартная библиотека ввода-вывода
#include <util/delay.h>         			// библиотека задержки

 static unsigned char pic_res[][8]=			// Двухмерная программная матрица
{
{0x7E,0x7E,0x66,0x66,0x66,0x66,0x66,0x66},  //П
{0x3E,0x7E,0x66,0x66,0x7E,0x3E,0x06,0x06},  //Р
{0x66,0x66,0x76,0x7E,0x7E,0x6E,0x66,0x66},  //И
{0x3E,0x7E,0x66,0x3E,0x3E,0x46,0x7E,0x3E},  //В
{0x3E,0x3E,0x06,0x3E,0x3E,0x06,0x3E,0x3E},  //Е
{0x7E,0x7E,0x18,0x18,0x18,0x18,0x18,0x18}   //Т
}; 
 	
void indication (unsigned char a)   		// функция вывода
{
	unsigned char i, b;						// Определение локальных переменных							
		for(b=0; b<50; b++)					// Переменная в цикле, задающая яркость 
		{	
			for (i=0; i<8; i++)				// Переменная в цикле, формирующая развертку из 8 строк
			{
			PORTB =~(1<<i);					// Включение строки развертки
			PORTD=pic_res[a][i];			// Формирование изображения
			_delay_ms(1);					// Частота развертки 
			PORTB=255;						// Гашение
			PORTD=0;						// изображения	
			}	
		}
}

int main (void)
{
	unsigned char i;							//  Определение локальной переменной	
    	DDRD = 0XFF;							// PortD установить на вывод
    	PORTD = 0;								// обнулить все выводы PortD
    	DDRB = 0XFF;							// PortB установить на вывод
    	PORTB = 0;								// обнулить все выводы PortB

	while(1)									// Бесконечный цикл
	{
		for (i=0; i<6; i++)						// Перебор букв из матрицы
		{
				indication(i);					// Вывод изображения	
		}							
	}
}


Программу можно дописать, чтобы сделать бегущую стоку и добавить в программную матрицу все буквы русского и латинского алфавита. В этом случае можно выводить текст, набранный с клавиатуры компьютера или динамическое изображение...
Для комфортной работы со светодиодной матрицей рекомендую скачать программу по ссылке: Светодиодные индикаторы
Изображение
Программа универсальная, позволяет генерировать код в зависимости от того как подключены порты контроллера, и как реализована развертка. Кроме этого программа позволяет генерировать код 7-сегментного индикатора. Можно конвертировать числа разных разрядностей.

Сообщение отредактировал galrad: 23 Февраль 2016 - 00:36

0

#248 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 04 Март 2016 - 20:41

ну в общем я взял что-то из вашего добавил что свое и получилось вот это
?.include "m8def.inc"

.def temp = R16
.def temp1 = R17
.def temp2 = R18
.def temp3 = R19
.def rab = R20
.def loop1 = R21
.def loop2 = R22
.def loop3 = R23

.equ kdel = 200

.cseg
.org 0

ldi YH, high(RAMEND)
ldi YL, low(RAMEND)
out SPH, YH
out SPL, YL

ldi temp, 0b11111111
out DDRD, temp
out PORTD, temp
out DDRB,temp
out PORTB, temp


ldi temp, 0x05
out TCCR1B, temp

ldi temp, 0x80
out ACSR,temp

clr temp3
ldi rab, 0b10000000
led_start: rcall led ;вызов подпрограммы led
inc temp2 ;инкремент temp2
lsr rab ;сдвиг вправо
rcall delay2 ;к задержке2
cpi temp2, $30 ;сравнить temp2 с 48 (длина текста)
breq sdvig ;перейти если temp2 = 48
rjmp led_start

sdvig: inc temp3 ;инкремент temp3
rcall delay ;к задержке
cpi temp3, $30 ;сравнить temp3 с 48
breq sbros2 ;если равен то переход на sbros2
m1: clr temp2 ;очистить temp2
mov temp2, temp3 ;скопировать temp3 в temp2
ldi rab, 0b10000000 ;загрузка в rab 0b10000000
rjmp led_start

sbros2: clr temp3 ;сброс temp3
rjmp m1


led: rcall segment
out PORTB, r0 ;отрисовка строк
out PORTD, rab ;щтрисовка столбцов
ret

segment: ldi ZL, low(data*2)
ldi ZH, high(data*2)

ldi temp, 0
add ZL, temp2
adc ZH, temp
lpm
ret

delay: push temp
ldi temp, 0
out TCNT1H, temp
out TCNT1L, temp
wt1: in temp, TCNT1L
cpi temp, low(kdel)
brlo wt1
in temp, TCNT1H
cpi temp, high(kdel)
brlo wt1
pop temp
ret

delay2: push loop1
push loop2
push loop3

ldi loop3, 5
z1: dec loop3
breq z4
ldi loop2, 15
z2: dec loop2
breq z1
ldi loop1, 30
z3: dec loop1
brne z3
rjmp z2

z4: pop loop3
pop loop2
pop loop1
ret


data: .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;
.db 0x00, 0x00, 0x00, 0x08, 0x7E, 0x88, 0x40, 0x00 ;t
.db 0x00, 0x00, 0x70, 0xA8, 0xA8, 0xA8, 0x30, 0x00 ;e
.db 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00 ;x
.db 0x00, 0x00, 0x00, 0x08, 0x7E, 0x88, 0x40, 0x00 ;t
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;
0

#249 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 04 Март 2016 - 20:47

ну в общем это бегущая строка, я думаю у меня там с задержками что-то не то, слишком сильно текст моргает при движении, исправьте меня если не трудно :) и спасибо за помощь
0

#250 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 13 Март 2016 - 23:09

Продолжением 7-сегментных индикаторов можно считать светодиодные матрицы.
Матрицы занимают промежуточное положение между дисплеями различных приборов, гаджетов, сматрфонов. Матрицы могут быть монохромными или цветными (от 2 до 4 цветов, из цветных, чаще всего трехцветные, а для видеодисплеев добавляют отдельно белый).
Все жидкокристаллические экраны состоят из пикселей, аналогично светодиодам в матрицах. В последнее время с удешевлением светодиодов, широкое распространение получили рекламные бегущие огни, сделанные из светодиодных матриц.
Главное преимущество использования матриц в том, что можно выводить произвольную картинку и реализовать любую анимацию.
Светодиодные матрицы выпускаются в разных исполнениях:
Изображение
называются они точечными светодиодными матрицами.
Для понимания работы используем матрицу 8x8, так как оптимально подключается к двум портам микроконтроллера. Для удобства используем микроконтроллер ATmega 8, у которого есть полноценные порты B и D.
Схема подключения очень простая, но обратите внимание, что в матрице выводы не расположены последовательно, поэтому нужно обязательно смотреть даташит на данный вид матрицы,
кроме этого необходимо подключать один порт микроконтроллера к матрице через токоограничивающие резисторы по 200-300 Ом, иначе отдельные светодиоды матрицы выйдут из строя.
Любая светодиодная матрица выводит информацию по принципу динамической индикации.
Условно предположим, что матрица состоит из 8 строк, состоящих из 8 светодиодов. Тогда последовательно перебирая строки можно включать конкретные светодиоды.
Изображение
Включаются строки как “бегущие огни”, которые мы рассмотрели раньше. Светодиоды в строках подключены к портам куда выводится значение программной матрицы.
Таким образом, частота “бегущих огней” не меняется и равна примерно 200Гц. Для получения статической картинки достаточно чтобы номеру строки соответствовал порядковый номер данных матрицы, кратный 8.
Рассмотрим, как выводится значение цифры 3. Верхний ряд образует вертикальные строки от 0 до 7, которые включаются и выключаются последовательно, формируя развертку, а боковые строчки формируют изображение.
Полный проход от 0 до 7 т.е.8 строк называется кадром и соответствует программной матрице:
data:
.db 0x00, 0x00, 0x42, 0x81, 0x89, 0x76, 0x00, 0x00 ;
Кадр должен быть стабильным и не меняться в процессе работы программы, иначе "картинка" "рассыпатся".
Так как частота развертки практически не меняется, то удобно сделать развертку на основе прерываний аппаратных таймеров, а временем индикации управлять программно.
Чтобы вывести “бегущую строку” нужно сформировать последовательное смещение чтения данных из программной матрицы, в данном случае смещение равно одному байту.
Изображение
На рисунке видно, как смещается знакоместо - желтая граница постепенно переходит в белую замещая цифру 3 на цифру 1.
data:
.db 0x00, 0x00, 0x42, 0x81, 0x89, 0x76, 0x00, 0x00 ;
.db 0x00, 0x00, 0x00, 0x82, 0xFF, 0x80, 0x00, 0x00 ;

или

data:
.db 0x00, 0x00, 0x42, 0x81, 0x89, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xFF, 0x80, 0x00, 0x00 ;

Добиться этого можно простым инкрементированием адреса программной матрицы.
Очень часто, при создании конструкций на светодиодных матрицах, возникают проблемы с выведением информации. На самом деле, математика выведения информации на матричные дисплеи практически одинакова для всех устройств.
Главным является механизм выведения статической картинки, т.е. формирование кадра, где программы могут быть совершенно не стандартными, а вот сама динамика картинки как правило стандартная и может быть легко унифицирована а в дальнейшем модифицирована.
Далее составим алгоритм отображения информации и попробуем разобрать программу для управления светодиодной матрицей.

Сообщение отредактировал galrad: 14 Март 2016 - 10:32

0

#251 Пользователь офлайн   kocten 

  • Прибывший
  • Группа: Пользователи
  • Сообщений: 1
  • Регистрация: 17 Март 16

Отправлено 17 Март 2016 - 04:27

Здравствуйте! Хотелось бы посмотреть как это все реализуется)
0

#252 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 20 Март 2016 - 22:08

Развертка может быть как вертикальной, так и горизонтальной.
Для бегущих строк, конечно, оптимальным является вертикальная развертка, как было показано выше. Но, часто развертка может быть и горизонтальной, когда строка движется сверху вниз как в телевизорах с кинескопом.
В светодиодной матрице, при формировании изображения, программная матрица может быть написана по принципу: от старшего бита к младшему (как показано на рисунке)

Изображение
или по принципу: от младшего с старшему (как уже мы привыкли)
Изображение

Как видно, значения программной матрицы различаться, это зависит от пересчета бита: в первом случае – не стандартно от 7 до 0, во втором как обычно - от 0 до 7.
Как будет работать, казалось бы простая, “бегущая строка” в этих случаях, смотрим на следующих рисунках:
Изображение
Один кадр последовательно смещает каждый байт программной матрицы “вправо”. Хотя “картинка” движется “влево”.
При таком смещении “картинки” необходимо в течение какого-то времени циклически повторять процесс смещения, т.е. получается, что в течение некоторого времени этот процесс повторяется с начала – возвращаясь к первой картинке.
Глаз человека в этом случае будет видеть смещенную на одну строку “влево” цифру 3.
Если же не делать циклических повторений смещений, то мы не увидим никакой бегущей строки, нам будет казаться, что горят все светодиоды, только одни строчки ярче другие тусклее.
Кроме этого нужно группировать байты через каждые 64 бита, чтобы в первую строчку попал первый байт следующего знака.
На первый взгляд кажется, что этот механизм более сложный чем первый вариант, но на самом деле они равнозначны в программном отношении.
Просто первый вариант кажется более понятным. С другой стороны, мы можем организовать развертку программно, по вертикали или по горизонтали, в зависимости от поставленных задач.

На практике "одиночная" светодиодная матрица используется редко, как правило они объединяются группами, образуя светодиодное табло, но принципы формирования изображения подчиняются тем правилам, которые мы рассмотрели.

Теперь остается написать отдельные модули в виде подпрограмм и объединить их в одну программу.

Сообщение отредактировал galrad: 21 Март 2016 - 06:07

0

#253 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 17 Апрель 2016 - 21:36

Программ бегущей строки для светодиодной матрицы написано достаточно много, но оптимальных на самом деле единицы. На ассемблере программа получается достаточно громоздкой,
а потому начал было писать на СИ, но столкнулся с проблемой вывода строковых массивов. В результате моя программ получилась тоже не маленькой. Затем я вспомнил, что в программе
IAR AVR была библиотека pgmspace.h для работы со строковыми массивами. Нашел её по ссылке: http://avr-libc.naro...__pgmspace.html
А затем немного погуглив увидел программу написанную Черняковым Сергеем Станиславовичем: Прогамма бегущей строки
Мне она показалась достаточно оптимальной. Я немного изменил ее под микроконтроллер ATmega8. Схема выглядит достаточно просто, как и предыдущая. В Протеусе работает без проблем.
Выводит выражение "Hello, World on the site chipmk.ru", хотя можно вывести любое предложение не превышающее 255 символов.
Изображение

Программа написана на СИ

#define F_CPU 1000000UL                     			// установка частоты микроконтроллера
#include <avr/io.h>										// стандартная библиотека ввода-вывода
#include <avr/interrupt.h>								// библиотека прерываний
#include <util/delay.h>									// библиотека программных задержек
#include <avr/pgmspace.h>								// библиотека работы со стоками

#define PORT_column PORTB								// Порт D определяет вертикальные линии и
#define DDR_column  DDRB								// настроен на вывод
#define PORT_line   PORTD								// Порт B определяет горизонтальные линии и
#define DDR_line	DDRD								// настроен на вывод


const unsigned char simbols [] PROGMEM = {
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// пробел
	0x04,0x04,0x04,0x04,0x00,0x04,0x00,0x00,// !
	0x0A,0x0A,0x0A,0x00,0x00,0x00,0x00,0x00,// "
	0x0A,0x0A,0x1F,0x0A,0x1F,0x0A,0x0A,0x00,// #
	0x04,0x0F,0x14,0x0E,0x05,0x1E,0x04,0x00,// $
	0x18,0x19,0x02,0x04,0x08,0x13,0x03,0x00,// %
	0x0C,0x12,0x14,0x08,0x14,0x12,0x0D,0x00,// &
	0x0C,0x04,0x08,0x00,0x00,0x00,0x00,0x00,// '
	0x02,0x04,0x08,0x08,0x08,0x04,0x02,0x00,// (
	0x08,0x04,0x02,0x02,0x02,0x04,0x08,0x00,// )
	0x00,0x04,0x15,0x0E,0x15,0x04,0x00,0x00,// *
	0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00,// +
	0x00,0x00,0x00,0x00,0x0C,0x04,0x08,0x00,// ,
	0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,// -
	0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,// .
	0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00,// /

	0x0E,0x11,0x13,0x15,0x19,0x11,0x0E,0x00,// 0
	0x04,0x0C,0x04,0x04,0x04,0x04,0x0E,0x00,// 1
	0x0E,0x11,0x01,0x02,0x04,0x08,0x1F,0x00,// 2
	0x1F,0x02,0x04,0x02,0x01,0x11,0x0E,0x00,// 3
	0x02,0x06,0x0A,0x12,0x1F,0x02,0x02,0x00,// 4
	0x1F,0x10,0x1E,0x01,0x01,0x11,0x0E,0x00,// 5
	0x06,0x08,0x10,0x1E,0x11,0x11,0x0E,0x00,// 6
	0x1F,0x01,0x02,0x04,0x08,0x08,0x08,0x00,// 7
	0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,0x00,// 8
	0x0E,0x11,0x11,0x0F,0x01,0x02,0x0C,0x00,// 9
	0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00,// :
	0x00,0x0C,0x0C,0x00,0x0C,0x04,0x08,0x00,// ;
	0x02,0x04,0x08,0x10,0x08,0x04,0x02,0x00,// <
	0x00,0x00,0x1F,0x00,0x1F,0x00,0x00,0x00,// =
	0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00,// >
	0x0E,0x11,0x01,0x02,0x04,0x00,0x04,0x00,// ?

	0x0E,0x11,0x01,0x0D,0x15,0x15,0x0E,0x00,// @
	0x0E,0x11,0x11,0x11,0x1F,0x11,0x11,0x00,// A
	0x1E,0x11,0x11,0x1E,0x11,0x11,0x1E,0x00,// B
	0x0E,0x11,0x10,0x10,0x10,0x11,0x0E,0x00,// C
	0x1C,0x12,0x11,0x11,0x11,0x12,0x1C,0x00,// D
	0x1F,0x10,0x10,0x1E,0x10,0x10,0x1F,0x00,// E
	0x1F,0x10,0x10,0x1E,0x10,0x10,0x10,0x00,// F
	0x0E,0x11,0x10,0x17,0x11,0x11,0x0E,0x00,// G
	0x11,0x11,0x11,0x1F,0x11,0x11,0x11,0x00,// H
	0x0E,0x04,0x04,0x04,0x04,0x04,0x0E,0x00,// I
	0x07,0x02,0x02,0x02,0x02,0x12,0x0C,0x00,// J
	0x11,0x12,0x14,0x18,0x14,0x12,0x11,0x00,// K
	0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x00,// L
	0x11,0x1B,0x15,0x15,0x11,0x11,0x11,0x00,// M
	0x11,0x11,0x19,0x15,0x13,0x11,0x11,0x00,// N
	0x0E,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,// O

	0x1E,0x11,0x11,0x1E,0x10,0x10,0x10,0x00,// P
	0x0E,0x11,0x11,0x11,0x15,0x12,0x0D,0x00,// Q
	0x1E,0x11,0x11,0x1E,0x14,0x12,0x11,0x00,// R
	0x0F,0x10,0x10,0x0E,0x01,0x01,0x1E,0x00,// S
	0x1F,0x04,0x04,0x04,0x04,0x04,0x04,0x00,// T
	0x11,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,// U
	0x11,0x11,0x11,0x11,0x11,0x0A,0x04,0x00,// V
	0x11,0x11,0x11,0x11,0x15,0x15,0x0E,0x00,// W
	0x11,0x11,0x0A,0x04,0x0A,0x11,0x11,0x00,// X
	0x11,0x11,0x11,0x0A,0x04,0x04,0x04,0x00,// Y
	0x1F,0x01,0x02,0x04,0x08,0x10,0x1F,0x00,// Z
	0x0E,0x08,0x08,0x08,0x08,0x08,0x0E,0x00,// [
	0x11,0x0A,0x1F,0x04,0x1F,0x04,0x04,0x00,//
	0x0E,0x02,0x02,0x02,0x02,0x02,0x0E,0x00,// ]
	0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00,// ^
	0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,// _

	0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,// '
	0x00,0x00,0x0E,0x01,0x0F,0x11,0x0F,0x00,// a
	0x10,0x10,0x1E,0x11,0x11,0x11,0x1E,0x00,// b
	0x00,0x00,0x0E,0x10,0x10,0x11,0x0E,0x00,// c
	0x01,0x01,0x0D,0x13,0x11,0x11,0x0F,0x00,// d
	0x00,0x00,0x0E,0x11,0x1F,0x10,0x0E,0x00,// e
	0x06,0x09,0x08,0x1C,0x08,0x08,0x08,0x00,// f
	0x00,0x0F,0x11,0x11,0x0F,0x01,0x0E,0x00,// g
	0x10,0x10,0x16,0x19,0x11,0x11,0x11,0x00,// h
	0x04,0x00,0x0C,0x04,0x04,0x04,0x0E,0x00,// i
	0x02,0x00,0x06,0x02,0x02,0x12,0x0C,0x00,// j
	0x10,0x10,0x12,0x14,0x18,0x14,0x12,0x00,// k
	0x18,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,// l
	0x00,0x00,0x1A,0x15,0x15,0x11,0x11,0x00,// m
	0x00,0x00,0x16,0x19,0x11,0x11,0x11,0x00,// n
	0x00,0x00,0x0E,0x11,0x11,0x11,0x0E,0x00,// o

	0x00,0x00,0x1E,0x11,0x1E,0x10,0x10,0x00,// p
	0x00,0x00,0x0F,0x11,0x0F,0x01,0x01,0x00,// q
	0x00,0x00,0x16,0x19,0x10,0x10,0x10,0x00,// r
	0x00,0x00,0x0E,0x10,0x0E,0x01,0x1E,0x00,// s
	0x08,0x08,0x1C,0x08,0x08,0x09,0x06,0x00,// t
	0x00,0x00,0x11,0x11,0x11,0x13,0x0D,0x00,// u
	0x00,0x00,0x11,0x11,0x11,0x0A,0x04,0x00,// v
	0x00,0x00,0x11,0x11,0x11,0x15,0x0A,0x00,// w
	0x00,0x00,0x11,0x0A,0x04,0x0A,0x11,0x00,// x
	0x00,0x00,0x11,0x11,0x0F,0x01,0x0E,0x00,// y
	0x00,0x00,0x1F,0x02,0x04,0x08,0x1F,0x00,// z
	0x17,0x15,0x15,0x15,0x17,0x00,0x00,0x00,// 10
	0x17,0x11,0x17,0x14,0x17,0x00,0x00,0x00,// 12
	0x17,0x14,0x17,0x11,0x17,0x00,0x00,0x00,// 15
	0x01,0x05,0x09,0x1F,0x08,0x04,0x00,0x00,// стрелка
0x00,0x07,0x0E,0x1C,0x11,0x1E,0x00,0x00};// символ

unsigned char line [8];
unsigned char array_q_1 [8];
unsigned char array_q_2 [8];
unsigned char string [] = "Hello, World on the site chipmk.ru";

ISR (TIMER0_OVF_vect)		// Обработчик вектора прерывания таймера TIMER0
{
	static unsigned char q;	//Внутренный счётчик отображаемого разряда (сохраняет свое значение после выхода из функции)
	
	q++;
	switch(q) //Перебор отображаемого сейчас разряда
		{
			case 1:PORT_column |= _BV(PB7);		//Гасим предыдуший разряд
	           	PORT_line = line[0];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB0);	//Посвечиваем следующий разряд
			break;
			
			case 2:PORT_column |= _BV(PB0);		//Гасим предыдуший разряд
	           	PORT_line = line[1];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB1);	//Посвечиваем следующий разряд
			break;
			
			case 3:PORT_column |= _BV(PB1);		//Гасим предыдуший разряд
	           	PORT_line = line[2];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB2);	//Посвечиваем следующий разряд
			break;
			
			case 4:PORT_column |= _BV(PB2);		//Гасим предыдуший разряд
	           	PORT_line = line[3];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB3);	//Посвечиваем следующий разряд
			break;
			
			case 5:PORT_column |= _BV(PB3);		//Гасим предыдуший разряд
	           	PORT_line = line[4];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB4);	//Посвечиваем следующий разряд
			break;
			
			case 6:PORT_column |= _BV(PB4);		//Гасим предыдуший разряд
	           	PORT_line = line[5];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB5);	//Посвечиваем следующий разряд
			break;
			
			case 7:PORT_column |= _BV(PB5);		//Гасим предыдуший разряд
	           	PORT_line = line[6];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB6);	//Посвечиваем следующий разряд
			break;
			
			case 8:PORT_column |= _BV(PB6);		//Гасим предыдуший разряд
	           	PORT_line = line[7];			//Выводит соответствующую цифру
           		PORT_column &= ~_BV(PB7);	//Посвечиваем следующий разряд
		           q=0;							//Когда подсвечен последний 4-й разряд счётчик обнуляем
			break;
			
			default:
			break;   
		}
}

int main (void)
{
	unsigned char q_1,q_2,i,j,a=0;			// определение переменных
  
	DDR_column = 0xFF;						//порт колонок как выход
	DDR_line   = 0xFF;						//порт строк как выход
	
	TCCR0  = 0x02;							//запуск таймера для формирования динамической индикации
	TIMSK  = 0x01;							//разрешение прерывания таймера
	
	sei ();									//разрешение прерывания
	
	while(1)								//бесконечный цикл для движения строки справа налево
	{
		for(j=0; j<(sizeof(string)-2);j++)	//цикл c определением длины бегущей строки
		{
    		q_1 = string[j] -32;			//номер массива пикселей "левого" знака строки
			q_2 = string[j+1] - 32;			//номер массива пикселей "правого" знака строки
			for(i=0; i<8; i++) array_q_1[i] = pgm_read_byte(&simbols[i+q_1*8]);	//массив пикселей "левого" знака строки
			for(i=0; i<8; i++) array_q_2[i] = pgm_read_byte(&simbols[i+q_2*8]);	//массив пикселей "правого" знака строки
    		for(a=0; a<8; a++)
			{
				for(i=0; i<8; i++) line[i] = (array_q_1[i]<<a) | (array_q_2[i]>>(8-a)); //запись одного байта в массив line[]
				_delay_ms(100); 
			}
		}
	}
}

/*
	while(1)	//бесконечный цикл для движения строки слева направо
	{
		for(j=0; j<(sizeof(string)-2);j++)	//цикл c определением длины бегущей строки
		{
    		q_1 = string[(sizeof(string)-2)-j-1] -32;		//номер массива пикселей "левого" знака строки
			q_2 = string[(sizeof(string)-2)-j] - 32;		//номер массива пикселей "правого" знака строки
			for(i=0; i<8; i++) array_q_1[i] = pgm_read_byte(&simbols[i+q_1*8]);		//массив пикселей "левого" знака строки
			for(i=0; i<8; i++) array_q_2[i] = pgm_read_byte(&simbols[i+q_2*8]);		//массив пикселей "правого" знака строки
    		for(a=0; a<8; a++)
			{
				for(i=0; i<8; i++) line[i] = (array_q_1[i]<<(8-a)) | (array_q_2[i]>>a);_delay_ms(100); 
			}
		}
	}
*/


Индикация происходит по прерыванию 8 битного таймера Т0, в режиме normal, т.е. по его заполнению. С каждым прерыванием происходит включение одного из разрядов,а в итоге последовательный перебор всех 8 разрядов порта В.
Порт D выводит значения строкового массива, постепенно инкрементируя его и записывая его значение в массив line[ ]. При желании можно дезассемблировать программу и посмотреть в командах ассемблера. Сравните ради интереса, насколько усложняется в понимании программа...

Сообщение отредактировал galrad: 17 Апрель 2016 - 21:39

0

#254 Пользователь офлайн   MUVAZIN 

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 9
  • Регистрация: 04 Январь 16

Отправлено 08 Май 2016 - 13:23

вообщем у меня получилось бегущая строка на ассемблере, там код намного меньше чем на си если кому нужно в ютубе есть виде уроки романа звездопадова и в контакте группа, спасибо ему и вам вы мне очень помогаете, если можно помогите с косвенной адресацией на ассемблере че то у меня плохо получается записовать данные в озу
0

#255 Пользователь офлайн   galrad 

  • Завсегдатай
  • PipPipPip
  • Группа: Пользователи
  • Сообщений: 240
  • Регистрация: 26 Февраль 11

Отправлено 08 Май 2016 - 15:46

Просмотр сообщенияMUVAZIN (08 Май 2016 - 13:23) писал:

вообщем у меня получилось бегущая строка на ассемблере, там код намного меньше чем на си


Времени не хватает, чтобы сесть и написать программу. Так-то она не сложная, три вложенных цикла в виде подпрограмм. Рад, за Вас, что решили поставленную задачу, значит будет движение дальше. :D
0

#256 Пользователь офлайн   MUSIEFF 

  • Прибывший
  • Группа: Пользователи
  • Сообщений: 4
  • Регистрация: 15 Март 17

Отправлено 16 Март 2017 - 01:00

.include "m16def.inc"
.def temp = r16
.def srsave = r17
.def bitcnt = r18
.def rxbyte = r19
.def temp1 = r20
.def state = r21

.equ bitparity = 0
.equ bitrate = 9600
.equ BATD = 1000000/(16*bitrate)-1

.cseg
.org 0
jmp Reset
.org $0002
jmp EXT_INT0

Reset:
ldi temp, high(RAMEND)
out SPH, temp
ldi temp, low(RAMEND)
out SPL, temp

ldi temp, 0b01000000
out GICR, temp
out GIFR, temp
ldi temp, 0b01000010
out MCUCR, temp

ldi temp, high(BATD)
out UBRRH, temp
ldi temp, low(BATD)
out UBRRL, temp
ldi temp, 0b11011000
out UCSRB, temp
ldi temp, 0b10000110
out UCSRC, temp

ldi temp, 0b00000000
out DDRB, temp
ldi temp, 0b11111111
out PORTB, temp

ldi temp, 0b11111111
out DDRA, temp
out PORTA, temp

clr bitcnt
clr state

sei

Proga:
rjmp Proga

EXT_INT0:
cli
in srsave, SREG
push srsave
rcall RXKBD
pop srsave
out SREG, srsave
reti

RXKBD:
clt
sbic PINB, 0
set
cpi bitcnt, 0
breq FIRSTBIT
cpi bitcnt, 9
breq PARITYCHECK
cpi bitcnt, 10
breq RXFINISHED
lsr rxbyte
bld rxbyte, 7
clr temp1
bld temp1, bitparity
eor state, temp1

RXBITDONE:
inc bitcnt
ret

FIRSTBIT:
clr rxbyte
ldi temp, 0xFE
and state, temp
rjmp RXBITDONE

PARITYCHECK:
clr temp1
bld temp1, bitparity
eor state, temp1
rjmp RXBITDONE

RXFINISHED:
sbrs state, bitparity
rjmp DISCARDBYTE
clr bitcnt
rcall bytvix
ret

DISCARDBYTE:
clr bitcnt
clr rxbyte
ret

bytvix:

out PORTA, rxbyte
out UDR, rxbyte
ret
0

#257 Пользователь офлайн   MUSIEFF 

  • Прибывший
  • Группа: Пользователи
  • Сообщений: 4
  • Регистрация: 15 Март 17

Отправлено 16 Март 2017 - 01:03

написал это с клавиатуры считывает, ну если подключить вывод по USART, не работает, хотя че я вру и без UART нестабильно работает, знаю что неправильно что то сделал :( прошу помочь мне если не трудно
0

#258 Пользователь офлайн   MUSIEFF 

  • Прибывший
  • Группа: Пользователи
  • Сообщений: 4
  • Регистрация: 15 Март 17

Отправлено 16 Март 2017 - 21:05

может у кого нибудь ассемблерный код есть хотя бы для пс/2, поделитесь если не жалко
0

Поделиться темой:


  • 13 Страниц +
  • « Первая
  • 11
  • 12
  • 13
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей