Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.61/443: Рейтинг темы: голосов - 443, средняя оценка - 4.61
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 37

PIC, SPI и сдвиговый регистр.

03.09.2012, 18:29. Показов 86807. Ответов 115
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте уважаемые гуру!
Настал для меня период слезть с ардуино и перейти на следующий уровень общений с МК. К тому же понадобилось перепрошить одну девайсину на PIC16F877.
Как нельзя лучше, пришлась среда разработки для PIC под разные платформы, в частности под Mac я запустил все без проблем.
Hello world в виде морганий светодиода и считываний кнопки вроде проблем не вызвали, однако этап освоения SPI поставил в тупик, в связи с чем прошу у вас помощи.

Написал небольшой код, который по нажатию кнопки должен отправить данные по SPI в сдвиговый регистр 74HC595:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <pic16f877.h>
#include <stdyo.h>
#include <stdlib.h>
#include <htc.h>
 
int main() {
 
ADCON1 = 0x06; //Порт А будет работать как цифровой вход-выход
 
SSPEN = 1; //Бит включения SPI
SMP = 1; //Фаза выборки бита, опрос входа в конце выборки данных
CKP = 1; //Полярность тактового сигнала
CKE = 1; //Определение фронта, по которому будут передаваться данные
 
SSPM3 = 0; //0000 тактовый сигнал SPI будет работать от 1/4 скорости процессора
SSPM2 = 0;
SSPM1 = 0;
SSPM0 = 0;
 
TRISC0 = 1; //C0 как вход, для тактовой кнопки
TRISC3 = 0; //C3  SCK ведущий режим
TRISC5 = 0; //C5  SDO
TRISA5 = 0; //A5 SS линия
 
TRISD = 0x00; //Порт D как выход
PORTD = 0x00; //Низкий уровень на весь порт D
 
//Цикл программы
while (1) {
 
if (PORTCbits.RC0 == 1) { //Если нажата кнопка, выполняем блок
PORTDbits.RD4 = 1; //Высокий уровень для записи в сдвиговый регистр
SSPBUF = 0b00001111; //Передает байт в регистр
PORTDbits.RD4 = 0; //Низкий уровень для записи в сдвиговый регистр
}
 
}
 
}
Программу я решил постестить в виртуальной машине, в программе Proteus (Штука мне показалась весьма глючная, постоянно виснет при симуляциях, хотя может руки у меня кривые), в связи с чем создал схему и залил туда свой HEX.
Первоночальный запуск происходит как надо, кнопка отрабатывает как и задумано, в первых 4х регистрах высокий уровень, в остальных низкий.

<Изображение удалено>
Однако нажимая кнопку несколько раз, наблюдается смещение регистров, хотя каждый раз посылается по 8 бит...

<Изображение удалено>
В связи с этим вопрос, что в данной программе не так? Возможно по окончанию передачи нужно записывать еще какой то служебный бит что мы закончили?
И должен ли на выходе SCK высокий уровень, если мы ничего не передаем, в случае работы с 595?
Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.09.2012, 18:29
Ответы с готовыми решениями:

Сдвиговый регистр без микроконтроллера
Добрый день, на работе грузчики притащили два огромных сегментных индикатора с азс, попросили как нибудь им его приспособить типа лампочки,...

Программный SPI для PIC
объясните пожалуйста реализацию SPI-интерфейса(передача 16 бит) для простейшего pic(12 серия), в котором нет аппаратного SPI. На языке C.

[VHDL] ПЛИС длинный сдвиговый регистр с параллельной загрузкой
Подтолкните в нужную сторону, никак не могу сообразить. С одной стороны поступают байты по 8-разрядной шине. Динные выдает контроллер...

115
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
03.09.2012, 19:33
Как вы думаете , если с такой скоростью, как вы долбите SPI и без проверки окончания передачи , долбить по голове - быстро ли дойдет ????
Далее - видите серый уровень на пине куда кнопка подключена? Что означает серый цвет ?
В аурдино так же кнопки подключаются ?
Зато диагноз вынесен - Proteus глючит...
0
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 37
03.09.2012, 21:11
Про серый уровень осознал, приделал подтягивающий резистор с земли.
Про протеуст я же написал, что руки скорее всего кривые, я первый раз использую его, не знаю примудростей симуляции и почему он может вылетать.
Про проверку окончания передачи я же написал еще в первом сообщении, в этом собственно и вопрос, кто из них отвечает за окончание передачи? В даташите есть бит BF и SSPOV, вроде бы оба подходят, какой из них нужно использовать для проверки?

Спасибо за комментарии!
0
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
03.09.2012, 22:10
Цитата Сообщение от JikoKiy
В даташите есть бит BF и SSPOV, вроде бы оба подходят, какой из них нужно использовать для проверки?
Code
1
while(!BF);
И изучите , что из себя представляет механизм SPI, лишним не будет.
Тяжело конечно после облегчалок аурдуньи ...
Кстати Hi Tech какой версии? Они не все хороши, последняя неглючная 9.63 STD .
0
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 37
04.09.2012, 00:21
Hi tech это компилятор? У меня его нет, с сайта микрочипа для мака доступен только XC8. В них есть принципиальная разница?
0
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
04.09.2012, 09:21
Цитата Сообщение от JikoKiy
Hi tech это компилятор? У меня его нет, с сайта микрочипа для мака доступен только XC8. В них есть принципиальная разница?
Ну ясно. ХС8 это продолжение Hi Tech. Геморрой будет только при переносе старых проектов.
У вас получилось ?
0
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 37
04.09.2012, 13:13
Цитата Сообщение от dosykus
У вас получилось ?
Да, все получилось, спасибо! Я добавил проверку после пересылки, и все встало хорошо =)
Code
1
2
3
4
5
6
7
8
9
10
11
12
 while (1) {
 
if (PORTCbits.RC0 == 1) { //Если нажата кнопка, выполняем блок
 
PORTDbits.RD4 = 1; //Высокий уровень для записи в сдвиговый регистр
SSPBUF = regZ; //Передает байт в регистр
PORTDbits.RD4 = 0; //Низкий уровень для записи в сдвиговый регистр
 
while (!BF);
}
 
}
Попутно вопрос еще, никак не найду фукции delay, в разных примерах используют ее, однако подключая delays.h у меня все функции оттуда светятся серым, предполагается теперь что каждый сам будет писать данные функции, или еще что то требуется подключить для их работы?
0
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
04.09.2012, 13:36
Цитата Сообщение от JikoKiy
Написал небольшой код, который по нажатию кнопки должен отправить данные по SPI в сдвиговый регистр 74HC595:
у этого регистра есть SPI-вход?
http://avrdivices.ru/sdvygovy-registr-74hc595/
0
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 37
04.09.2012, 13:58
По сути его принцип работы и есть SPI, по тактам проталкивает биты, затем закрывает защелку для изменения состояния ног разом.
http://robocraft.ru/btog/arduino/519.html
0
SWK
04.09.2012, 15:34
Цитата Сообщение от JikoKiy
По сути его принцип работы и есть SPI, по тактам проталкивает биты, затем закрывает защелку для изменения состояния ног разом.
А я так обычно берегу SPI для чего-нибудь более серьезного - например, работы с микросхемами, которые имеют встроенный SPI, (внешней памятью, EEPROM, SD-Card)...
А для записи в регистры проще сделать программмно, там скорость особой роли не играет.
Например, в контроллере башни своего робота -
- я для расширения ввода - вывода использую запись в 3 регистра 74HC595, и ввод с 8 линий через 74HC165. Запись в регистры делаю через запараллеленные входы данных и сдвига, а потом защелкиваю данные в буфере выбранного регистра. Процедура (на МикроПаскале для PIC) предельно проста, и много времени не отнимает:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure WR_REG_U368(N_r : byte); // Запись байта в регистры.
var i, Bi : byte;
begin
case N_r of
3: Bi := Buf_U3;  // байт регистра шаговиков.
6: Bi := Buf_U6;  // байт регистра ключей IRF9540.
8: Bi := Buf_U8;  // байт регистра TST230R.
end;
for i := 7 downto 0 do
begin
if Bi.i = 0 then PORTD.4 := 0 else PORTD.4 := 1;
PORTD.6 := 1; // Сдвиг регистра!
PORTD.6 := 0;
end;
case N_r of
3: begin PORTA.2 := 1; PORTA.2 := 0; end; // Запись байта в регистр шаговиков.
6: begin PORTD.7 := 1; PORTD.7 := 0; end; // Запись байта в регистр ключей IRF9540.
8: begin PORTD.5 := 1; PORTD.5 := 0; end; // Запись байта в регистр TST230R.
end;
end;
Компилируется в 100 байт. Замена Case на IF дает экономию в 6 байт (94 байта), по времени - тоже почти одинаково.
Использование отдельных процедур для каждого регистра - тем более более громоздко и не так универсально. Тут легко расширить количество регистров хоть до десятка.
И удобно, когда запись в регистры делается через команды извне.
Работает надежно (второй год уже гоняю).

Вызов тоже прост. Кладем байт в соответствующий буфер (буфера нужны, чтобы можно было потом в любое время считать содержимое этих регистров, или изменить отдельные биты, не трогая остальных), и вызываем процедуру с указанием номера нужного регистра:
Code
1
2
    Buf_U6 := s3;   // Байт для записи в регистр
WR_REG_U368(6); // Запись байта в регистр ключей IRF9540.
Дополнительный плюс такого варианта - использую любые незанятые ноги любых портов, которые удобно использовать для разводки платы.
В данном случае - PORTA.2, PORTD.4, PORTD.5, PORTD.6, PORTD.7.
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
04.09.2012, 15:53
Цитата Сообщение от SWK
Запись в регистры делаю через запараллеленные входы данных и сдвига, а потом защелкиваю данные в буфере выбранного регистра.
Итого 2 лишних вывода.
Цитата Сообщение от SWK
PORTD.6 := 1; // Сдвиг регистра!
PORTD.6 := 0;
На ЧМЗ не разу не нарывались ?
Цитата Сообщение от SWK
Компилируется в 100 байт.
Это оооооочень много ...
0
SWK
04.09.2012, 16:44
Цитата Сообщение от dosykus
Цитата Сообщение от SWK
Запись в регистры делаю через запараллеленные входы данных и сдвига, а потом защелкиваю данные в буфере выбранного регистра.
Итого 2 лишних вывода.
Считайте: на 3 регистра у меня 1 - данные, 1 - тактовый, по 1 - стробы защелки на каждый регистр.
Итого - 2 общих + 3 индивидуальных = 5 ног.
На SPI будем иметь: SS, SDI, SDO, SCK, + 3 линии сторобов защелки. Итого = 7 штук! У иеня - 5. Ну, SS можно не использовать. SDI - можно не подключать, но все равно он занят!
В любом случае, у меня - меньше. С чего вы взяли 2 лишних? Покажите меньше. В любом случае для 3х регистров 595 нужны данные, такт и стробы записи. (Если не городить всякие там RC цепочки, формирующие строб записи после пачки тактовых, что для 3х регистров все равно не проканает).

Цитата Сообщение от SWK
PORTD.6 := 1; // Сдвиг регистра!
PORTD.6 := 0;
На ЧМЗ не разу не нарывались ?
А "ЧМЗ" - что это? Челябинский Моторный Завод?

SWK"] Компилируется в 100 байт.
Это оооооочень много ...[/QUOTE]
Это - универсальная процедура для записи в любой из 3 (можно и более) регистров 74HC595. С буферизацией записываемых в каждый регистр данных.

Для 1 регистра, с передачей данных напрямую в процедуру, получится порядка 20-30 байт(лень проверять).
Не думаю, что у JikoKiy аналогичная запись через SPI на С скомпилируется намного меньше.
Не говоря уже о записи в несколько регистров. Плюс - использование любых свободных ног, и остается аппаратный SPI для более серьезных вещей.
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
04.09.2012, 16:57
Я собственно не о хардварном SPI .
74HC595 соединяются последовательно .
Выход сдвигового регистра первой с входом второй и т.д.
Тактовые и защелки параллелятся . И того получаем 3 вывода. Динные, Тактовые и Защелки.
Получаем возможность наращивать количество 74HC595, не увеличивая количества выводов.
Собственно это же классика , удивительно что вы этого не знаете.

Далее софт .
Создается буфер равный(в байтах) количеству 74HC595.
В функции вывода выводим сразу весь буфер .
После вывода строб защелки.
Плюсы: Динный вывод можно автоматизировать :
повесить его на прерывание.
То есть мы только изменяем то что нужно в буфере , а все остальное сделается автоматом.
Вся эта байда не может весить 100 байт . Конкретно покажу вечером .

На счет Челябинского моторного ,
вы меня удивляете - это распространенные грабли новичков.
Хотя ваш пасксраль мог и задержек нафигачить ...
0
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 49
04.09.2012, 17:24
Интересно... а ресетом регистров... чё, никто никогда не рулит??? )))))
0
SWK
04.09.2012, 17:27
Цитата Сообщение от dosykus
Я собственно не о хардварном SPI.
74HC595 соединяются последовательно .
Выход сдвигового регистра первой с входом второй и т.д.
Тактовые и защелки параллелятся . И того получаем 3 вывода. Динные, Тактовые и Защелки.
Получаем возможность наращивать количество 74HC595, не увеличивая количества выводов. Далее софт .
Создается буфер равный(в байтах) количеству 74HC595.
В функции вывода выводим сразу весь буфер .
После вывода строб защелки.
Плюсы: Динный вывод можно автоматизировать :
повесить его на прерывание.
То есть мы только изменяем то что нужно в буфере , а все остальное сделается автоматом.
И гонять каждый раз все 3 байта, при изменении битов в одном из них?
Для однозадачного режима на макетке, может и устроит. У меня же - режим мультизадачный, несколько задач (в том числе и УЗ дальномер, и измерение освещенности с TST230R, и куча менее критичных) крутятся параллельно, и мне нет смысла терять время на монопольные действия, типа вывода в регистры, которые выполняются одним куском. Утроение времени работы процедуры вывода - мне не надо. Тем более - ради экономии пары выводов. Когда только использование 3х 595 и одного 165 регистров дало мне их сразу 24 выхода и 8 входов. Когда у контроллера - 33, а потребность платы была 53. Получилось же 60. То есть с запасом. Незадействованные ноги контроллера вывел на разьемы, для возможности будущих расширений. Например, подключение серв, или еще чего. Там среди свободных есть и ШИМ, и АЦП.

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

Вся эта байда не может весить 100 байт . Конкретно покажу вечером .
Попробуйте. Сравним, с учетом вышесказанного.

На счет Челябинского моторного ,
вы меня удивляете - это распространенные грабли новичков.
Хотя ваш пасксраль мог и задержек нафигачить ...
Ну, я то - давно уже не новичок. И все у меня, как правило, всегда работает.
А задержки я привых в наносекундах считать еще со времен жесткой логики, в 70х годах.
В данном случае (при тактовой 16 МГц) я имею четкий строб длиной 250нс, что для моей платы вполне достаточно. И более чем на порядок превосходит минимально допустимый для 74HC595. (Паспортная частота клока до 100 МГц).

Ваше же нелюбовь к Паскалю - всего лишь от его незнания. Меня он устраивает. Не будет устраивать - буду использовать что другое. Не проблема. Я - не фанат, как некоторые. Много чего пробовал. Использую же то, что мне удобно.
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 49
04.09.2012, 17:28
Цитата Сообщение от dosykus
Собственно это же классика , удивительно что вы этого не знаете.
Точно... классика АОНизма и "бегающих" строк... ))))
0
SWK
04.09.2012, 17:30
Цитата Сообщение от kuvotdo
Интересно... а ресетом регистров... чё, никто никогда не рулит??? )))))
У меня там RC - цепочка 12к 1 мкф, надежно обнуляющая их при подаче питания. При этом повешенные на регистры ключи ULN2803 остаются закрытыми, без ложных выбросов при включении.
1 / 1 / 0
Регистрация: 22.09.2010
Сообщений: 393
04.09.2012, 17:38
Цитата Сообщение от SWK
Попробуйте. Сравним, с учетом вышесказанного.
Сначала выложите свой асм листинг .

Кстати не порите чушь , вывод 3х байт займет не так много времени сколько вы расписываете .
0
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 49
04.09.2012, 17:47
А в условиях нехватки времени и ресурсов SPI вполне становится палочкой-выручалочкой... ))))
Чем ногами дрыгать... ))))
0
SWK
04.09.2012, 18:15
Цитата Сообщение от dosykus
Сначала выложите свой асм листинг ..
Нет проблем. указанная процедура находится по адресам 0x164-0x1C7.
[35.65 Кб]

Кстати не порите чушь , вывод 3х байт займет не так много времени сколько вы расписываете.
Это вы порете чушь.
Я же использую в программах своего робота то, что считаю нужным, и удобным. И просто так, ни за что что ни про что, увеличивать время записи в регистр втрое, не получая какого - либо для себя преимущества (при наличии кучи свободных ног), - не вижу смысла.
Как и нет пока необходимости использовать для этого аппаратный SPI.
А в условиях нехватки времени и ресурсов SPI вполне становится палочкой-выручалочкой... ))))
Чем ногами дрыгать... ))))
У меня нет проблем со временем и ресурсами в моих модулях робота. Главный цикл крутится за доли миллисекунды в контроллерах с PIC (ходовой, поворотной платформы, бамперов, аудиоконтроллера), в ЦК пока - так и вовсе 12-14 мкс, на Меге 128, 16 МГц.

Контролирую при отладке времена главного цикла, и отводимого задачам на монопольные куски, постоянно, (вставляя в нужных местах изменения состояния какой - либо из ног для контроля), мне хватает.

Многозадачные режимы на флаговом автомате в реальном времени в контроллерах использую давно, с 80х годов. Опыт есть.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.09.2012, 18:15
Помогаю со студенческими работами здесь

Что такое регистр F в PIC-овском Assembler?
Здорово, всем. Что такое регистр F в PIC-овском Assembler? Т.е. это просто свободная ячейка ОЗУ?

Сдвиговый регистр 595N и SPI
Хотел бы запустить сабж с SPI для управления семисегментниками, да ещё с реализацией возможности подключать последовательно несколько таких...

STM32F1038 74hc595d*2 сдвиговый регистр по spi
Имеется ARM-PLC контроллер на stm32f103c8 https://plus.google.com/photos/10591585 ... 1263983601 У него есть 8 релейных выходов,...

ШД, Сдвиговый регистр и МК
Идея состоит в чём?! Есть Tiny13A, есть 155ир13, есть mosfit ы(либо транзисторы) допустим irf540n, униполярный ШД. Хотел намутить мини...

Сдвиговый регистр
http://iosyitistromyss.ru/sdvygovyj-registr.html http://iosyitistromyss.ru/img/storters/rikystir.GIF прочитал эту статью, и у...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru