Перейти к содержанию
    

Вопрос про последовательный сдвиговый регистр

Здравствуйте!

Потребовалось загрузить в последовательный сдвиговый регистр PLL синтезатора MC145158 некоторые данные, загружать решил при помощи микроконтроллера attiny2313, написал для этого в CodeVision AVR следующую программу:

#include<tiny2313.h>
#include<delay.h>   
#define CLK PORTB.0 
#define DATA PORTB.1  
#define ENB PORTB.2
#define led PORTD.5 
#define wait delay_us(500);

void send(unsigned int data,unsigned int length)
{  
int i,j;
for(i=length;i!=0;i--)
   {  
   if((data & (1<<i))!=0)
   {
   DATA=1;  
   }      
   else 
   {
   DATA=0;
   }    
   CLK=1; 
   wait
   CLK=0;    
   wait
  } }
void main(void)
{ 
  DDRB=0b00000111;
  DDRD.5=1;
  send(0b10001110110110,14);
  send(0b0001000000,10);   
  send(0b00100000,8);
  wait 
  ENB=1; //включаем защелку, передаем данные в счетчики
  delay_ms(10); 
  ENB=0;
  led=1; 
  while(1);
}

Вроде бы все правильно, код работает, но загружает в регистр что-то не то, на ножке fR PLL синтезатора должен появиться сигнал с частотой 1.5625 кГц, но его нет :laughing:

В чем может быть проблема?

MC145158_2.pdf

Изменено пользователем #Eugene

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эмм... А как иначе?

первым берем следующий бит, вторым продвигаем его по регистру к концу... Или я что-то не понимаю?

Код в первом посте обновил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

первым берем следующий бит, вторым продвигаем его по регистру к концу... Или я что-то не понимаю?

Да, не понимаете работу сдвигового регистра: не нужно каждый бит специально куда-то сдвигать, он и так сдвинется и встанет в конце концов на место при загрузке следующих. Просто уберите из кода второй for.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понятно, исправил код в первом посте, правильно?

Черт, не заметил временные диаграммы в даташите

Изменено пользователем #Eugene

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо, идем дальше: почему меняется длина загружаемых данных? Она должна быть всегда равна 15, т.е. загрузили 14 бит значения reference counter + '1' в CONTROL, дернули ENB, загрузили 14 бит значения ÷ N counter + '0' в CONTROL, дернули ENB еще раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, пардон - задвигать всегда по 15 бит не обязательно, если нет каскадирования. Хотя бывает удобнее. Лишнего защелка в любом случае не возьмет :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, разобрался. Загрузил только что в регистр R 100100000000000 (2048), кварц стоит на 3200 кГц, на выходе fR появился сигнал частотой 800 кГц, значит в регистр загрузилось не 2048, а 4, но почему?

Загружаю вот так:

void send(unsigned int data,unsigned int length)
{  
int i;
for(i=0;i!=length;i++)
   {  
   wait 
   if((data & (1<<i))!=0)
   {
   DATA=1;  
   }      
   else 
   {
   DATA=0;
   } 
   wait
   CLK=1;    
   wait
   CLK=0;    
   wait
  } } 
void main(void)
{ 
  send(0b100100000000000,15); 

  delay_us(500);
  ENB=1;
  delay_us(500);
  ENB=0; 
  while(1);
}

Изменено пользователем #Eugene

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в регистр загрузилось не 2048, а 4, но почему?

Данные должны загружаться старшим битом вперед, а в вашей программе они загружаются в противоположном направлении.

 

Я бы написал как-нибудь так:

#define wait() delay_us(500)

void send(unsigned int data)
{  
    int i = 15;

    do
    {
        if(data & 1) DATA = 1;
        else DATA = 0;
        data >>= 1;
        wait();
        CLK = 1;
        wait();
        CLK = 0;
        wait();
    } while(--i);
}

void main(void)
{ 
    send(0b001000000000001); 
    delay_us(500);
    ENB = 1;
    delay_us(500);
    ENB = 0; 
    while(1);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы написал как-нибудь так:

Можно чуток короче:

        DATA = (data & 1);
        data >>= 1;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наконец то я разобрался.

Чем больше R тем меньше ширина импульса и по этому при R = 2048 я их не замечал на экране осциллографа :blush:

Так и должно быть? Странно как-то...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...