сдвиговый регистр

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

научите правильно работать со сдвиговым регистром , например 74нс595, желательно на си
нашёл вот такой пример

Код: Выделить всё

#include <avr/io.h>
 
#define DATA 0
#define SCL  1 
#define REC  2
 
void pause (unsigned int a)				
{ unsigned int i;
 
  for (i=a;i>0;i--)
   ;
}
 
void send_data (unsigned int data)
{ unsigned char i;
 
  for (i=0;i<16;i++)
   {
    if ((data&0x8000)==0x00) PORTD&=~_BV(DATA);	//Выставляем данные на PD0
	                    else PORTD|=_BV(DATA);
    asm("nop");
    PORTD|=_BV(SCL);	//Импульс на SCL
	asm("nop");
	PORTD&=~_BV(SCL);
    asm("nop");
	data=(data<<1);                         
   }
  PORTD|=_BV(REC);	//Импульс на Latch clock
  asm("nop");
  PORTD&=~_BV(REC);
}
 
int main(void)
{ unsigned int data=0;
 PORTD=0x00;		//Первоначально выключаем выхода
 DDRD=0x07;		//PD0-PD2 как выхода
 
 while (1) 
  {
    send_data(data);	//Отправить данные
    data=data+1;	
	pause(500);
  }
return 1;
}
как я понимаю asm("nop") это ассемблерная вставка, говорит о выполнении пустой операции, зачем это нужно?
что такое _BV() ??
нет ли какой нибудь функции которая бы принимала бинарный массив или число и сама бы говорила регистрам что им делать?
Последний раз редактировалось Gudd-Head Вт мар 25, 2014 14:51:27, всего редактировалось 1 раз.
Причина: Сюда перенёс
Реклама
Мудрый кот
Сообщения: 1842
Зарегистрирован: Пт май 29, 2009 10:58:47
Откуда: Саратов

Сообщение Fallk »

Я так понял вы SPI хотиете изобразить?
Спойлер;======
; Подпрограммы для передачи
; по интерфейсу SPI програмный
;======

SPI_MAN MOVWF SPI_REG
;======
; Колличество бит в передааемом байте
;======
MOVLW .8
MOVWF BYTE
;======
; Выставляю выход данных в нужное состояние
; в зависимости от текущего передаваемого
; бита
;======

Spi_L.1 BTFSS SPI_REG,7
BCF D_OUT
BTFSC SPI_REG,7
BSF D_OUT ;
RLF SPI_REG,1

;======
; Включаю синхроимпульс
;======
BSF SCLK ; Включение синхроимпульса (SCLK=1)
NOP

;======
; Выключаю синхроимпульс
;======
BCF SCLK ; Выключение синхроимпульса (SCLK=0)
BCF D_OUT

;======
; Счетчик 8 бит
;======
DECFSZ BYTE, 1 ; Отнять от ячейки 1 и записать ответ в нее же
GOTO Spi_L.1 ; Если равно нулю, уходим

return
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

Посмотрите проекты индикации на регистрах.
Например вот:
http://radioparty.ru/index.php/prog-avr ... on-74hc164
http://www.rlocman.ru/shem/schematics.html?di=65110
В общем дело происходит так:
Выставляю данные на вывод данных. Потом дергаю ногой тактового сигнала. Данные записываются в регистр и сдвигаются.
Таким макаром 8 бит вдвигаю в регистр и все!
Для 595го надо еще потом подать сигнал чтобы он данные отобразил на выходы.
В 164ом сразу отображаются на выходы.
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

с выводом разобрался, всё работает с двумя регистрами, но до тех пор пока зажигаю 15 светиков, при зажигании 16 загораеться всего 2

Код: Выделить всё

#include <avr/io.h>
#include <avr/delay.h>;
#define MR (1<<3) //ножка регистра mr
#define ST (1<<2) //ножка регистра защёлка
#define DS (1<<1) //ножка регистратора ds
#define SH (1<<0) //ножка sh

int main(void)
{
	unsigned int	shkala=16,
					sch;
	DDRB= 0b11111111;
	PORTB=0b00000000;
	PORTB|=MR;
	
	sh_reg(0b1111111111111111);
	
	while(1)
	{
		
	}
	return 1;	
}

void sh_reg(unsigned int ds)
{
	PORTB&=~MR;
	PORTB|=MR;
	unsigned int 
				ds_size=0,
				i_d=ds;
	while (i_d!=0)
	{
		i_d=(int)i_d/0b10;
		ds_size++;
	}
	
	PORTB&=~(ST);
	for (int i = ds_size; i >=0; i--)
	{
		if ((ds&(1<<i))!=0)
		{
			PORTB|=DS;	//ds
		} 
		else
		{
			PORTB&=~DS;	//ds
		}
		PORTB&=~SH;
		//asm("nop");
		PORTB|=SH;
	}
	PORTB|=ST;
}
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

Вы что то много плясок с бубном делаете.
Не проще ли сделать функцию для одного числа char и вместо стирания и выяснения сколько там бит (я правильно понял, что вы это делаете?) просто впихивать 8 штук и быть довольным?
Регистры соединены посделовательно, поэтому можно так впихнуть сколько надо.
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

так я и сделал функцию, в которую передаётся число, которое говорит какие светики жечь
я вроде там ничего не стирал и не выяснял, просто отрисовывал результат, до 15 же работает
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

А нафига размер выяснять когда он известен? У вас это 32.

Вот я же вам дал пример

Код: Выделить всё

// Функция вывода 1 разряда
12.void write_byte_1(char data)
13.{
14.for(char i = 0; i < 8 ; i++)
15.{
16.if((data & 0x80)!= 0) // Сравниваем 8-й бит с нулем
17.PORTB |= (1 << PB0); // DATA 1
18.else
19.PORTB &= ~(1 << PB0); // DATA 0
20.PORTB &= ~(1 << PB1); // CLK 0
21.PORTB |= (1 << PB1); // CLK 1
22.data = data << 1; // Сдвигаем биты
23.}
24.} 
Только надо аргумент скопировать в переменную. Так как тут из стека работать не будет.
Это вы правильно делаете.
Последний раз редактировалось Gisteresis Вт мар 18, 2014 09:42:27, всего редактировалось 1 раз.
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

я хочу в будущем иметь возможность добавить регистров
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

kelod писал(а):я хочу в будущем иметь возможность добавить регистров
Ну так тут весь смысл именно в этом!
Сколько регистров, столько раз надо вызвать эту функцию!

Можно конечно тогда массив битов делать, если вы так хотите.
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

а разве если передать в регистр сразу 16 бит они не должны передаваться последовательно?? вот смотрите, работает же
Вложения
1.rar
(17.4 КБ) 142 скачивания
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

я кажется понял в чём дело дело в том что char 8-битовый, а int-16 битный, значит нужно опять с бубном плясать...
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

а почему теперь больше чем 24 светика не горит?

Код: Выделить всё

#include <avr/io.h>
#include <avr/delay.h>;
#define MR (1<<3) //ножка регистра mr
#define ST (1<<2) //ножка регистра защёлка
#define DS (1<<1) //ножка регистратора ds
#define SH (1<<0) //ножка sh

int main(void)
{
	unsigned int	shkala=40,
					sch;
	DDRB= 0b11111111;
	PORTB=0b00000000;
	
	PORTB&=~MR;
	PORTB|=MR;

	PORTB&=~(ST);
	sh_reg(0b11111111);
	sh_reg(0b11111111);
	sh_reg(0b11111111);
	sh_reg(0b11111111);
	sh_reg(0b11111111);
	PORTB|=(ST);
	
	while(1)
	{
		
	}
	return 1;	
}

void sh_reg(unsigned char ds)
{
	/*PORTB&=~MR;
	PORTB|=MR;*/
	
	//PORTB&=~(ST);
	
	for (unsigned char i = 0; i <8; i++)
	{
		//_delay_ms(100);
		if ((ds&(1<<i))!=0)
		{
			PORTB|=DS;	//ds
		} 
		else
		{
			PORTB&=~DS;	//ds
		}
		PORTB&=~SH;
		PORTB|=SH;
	}
	//PORTB|=ST;
}
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

kelod писал(а):а разве если передать в регистр сразу 16 бит они не должны передаваться последовательно?? вот смотрите, работает же
Не ну конечно должны. Просто логично сделать функцию кратную количеству ног регистра.
kelod писал(а):я кажется понял в чём дело дело в том что char 8-битовый, а int-16 битный, значит нужно опять с бубном плясать...
Ну да. Вы будете следующий проект разрабатывать и что? Все заново переписывать под новые условия?
kelod писал(а):а почему теперь больше чем 24 светика не горит?
Может между 3им и 4ым регистрами нарушилась связь? Проверьте.
(24/8=3 андестенд?)

ПС: Почитайте на досуге п2.2 правил.
И кнопкой Spoiler тоже не мешало бы пользоваться.
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

Gisteresis писал(а): Может между 3им и 4ым регистрами нарушилась связь? Проверьте.
как она могла нарушиться?
и почему она на половине регистра нарушается?
вот схема
Вложения
1.rar
(17.19 КБ) 153 скачивания
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

kelod писал(а):вот схема
К сожалению далеко не все имеют установленный протеус! Сделайте скрин.
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

Косяк: тактовый вход (11) регистра U8 соединен с линией nMR.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Ответить

Вернуться в «Периферия»