#Eugene 0 14 июня, 2010 Опубликовано 14 июня, 2010 (изменено) · Жалоба Здравствуйте! Потребовалось загрузить в последовательный сдвиговый регистр 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 Изменено 14 июня, 2010 пользователем #Eugene Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба А два хитровложенных цикла по битам-то зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
#Eugene 0 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба Эмм... А как иначе? первым берем следующий бит, вторым продвигаем его по регистру к концу... Или я что-то не понимаю? Код в первом посте обновил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба первым берем следующий бит, вторым продвигаем его по регистру к концу... Или я что-то не понимаю? Да, не понимаете работу сдвигового регистра: не нужно каждый бит специально куда-то сдвигать, он и так сдвинется и встанет в конце концов на место при загрузке следующих. Просто уберите из кода второй for. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
#Eugene 0 14 июня, 2010 Опубликовано 14 июня, 2010 (изменено) · Жалоба Понятно, исправил код в первом посте, правильно? Черт, не заметил временные диаграммы в даташите Изменено 14 июня, 2010 пользователем #Eugene Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба Хорошо, идем дальше: почему меняется длина загружаемых данных? Она должна быть всегда равна 15, т.е. загрузили 14 бит значения reference counter + '1' в CONTROL, дернули ENB, загрузили 14 бит значения ÷ N counter + '0' в CONTROL, дернули ENB еще раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
#Eugene 0 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба загрузили 14 бит значения ÷ N counter N counter 10-и битный же? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба Да, пардон - задвигать всегда по 15 бит не обязательно, если нет каскадирования. Хотя бывает удобнее. Лишнего защелка в любом случае не возьмет :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
#Eugene 0 14 июня, 2010 Опубликовано 14 июня, 2010 (изменено) · Жалоба Спасибо, разобрался. Загрузил только что в регистр 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); } Изменено 14 июня, 2010 пользователем #Eugene Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 14 июня, 2010 Опубликовано 14 июня, 2010 · Жалоба в регистр загрузилось не 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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 15 июня, 2010 Опубликовано 15 июня, 2010 · Жалоба Я бы написал как-нибудь так: Можно чуток короче: DATA = (data & 1); data >>= 1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
#Eugene 0 15 июня, 2010 Опубликовано 15 июня, 2010 · Жалоба Наконец то я разобрался. Чем больше R тем меньше ширина импульса и по этому при R = 2048 я их не замечал на экране осциллографа Так и должно быть? Странно как-то... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться