Страница 1 из 1
PIC24HJ128GP204 осваиваю SPI
Добавлено: Пн ноя 03, 2014 18:45:35
alexmlw
Приветствую!
Есть два МК PIC24HJ128GP204. Пытаюсь заставить их общаться по SPI
Код ведущего :
Код: Выделить всё
#include <p24hj128gp204.h>
#include <spi.h>
void main() {
unsigned int X = 3;
Init_conf();
PORTB = 0;
PORTCbits.RC4 = 0;
WriteSPI1 (0x0005);
PORTCbits.RC4 = 1;
X = ReadSPI1();
PORTB = X;
while (1);
}
void Init_conf () {
unsigned int SPICON1Value;
unsigned int SPICON2Value;
unsigned int SPISTATValue;
//PORTB
AD1PCFGL = 0xffff; //Analog module off
TRISB = 0x0000;
//PORTC
TRISC = 0x0000;
PORTCbits.RC4 = 1;
RPINR20 = 0x1F11; // SDI - RC1
RPOR9 = 0x0807; // SCK - RC3 SDO - RC2
//SPI
CloseSPI1(); // SPI off, for setting
SPICON1Value = ENABLE_SCK_PIN & ENABLE_SDO_PIN & SPI_MODE16_ON &
SPI_SMP_ON & SPI_CKE_OFF & SLAVE_ENABLE_OFF &
CLK_POL_ACTIVE_HIGH & MASTER_ENABLE_ON &
SEC_PRESCAL_1_1 & PRI_PRESCAL_1_1;
SPICON2Value = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT;
SPISTATValue = SPI_ENABLE;
OpenSPI1 (SPICON1Value, SPICON2Value, SPISTATValue);// setting end, SPI on
//Oscillator
}
Код ведомого:
Код: Выделить всё
#include <p24hj128gp204.h>
#include <spi.h>
void main() {
int X = 0;
Init_conf();
X = ReadSPI1();
if (X == 0x0005) {
WriteSPI1 (0xf1f1);
}
PORTB = X;
while (1);
}
void Init_conf () {
unsigned int SPICON1Value;
unsigned int SPICON2Value;
unsigned int SPISTATValue;
//PORTB
AD1PCFGL = 0xffff; //Analog module off
TRISB = 0x0000;
//PORTC
TRISC = 0x0000;
RPINR20 = 0x1311; // SCK -RC3 SDI - RC1
RPOR9 = 0x0007; // SDO - RC2
RPINR21 = 0x1F14; // SS - RC4
//SPI
CloseSPI1(); // SPI off, for setting
SPICON1Value = ENABLE_SCK_PIN & ENABLE_SDO_PIN & SPI_MODE16_ON &
SPI_SMP_ON & SPI_CKE_OFF & SLAVE_ENABLE_ON &
CLK_POL_ACTIVE_HIGH & MASTER_ENABLE_OFF &
SEC_PRESCAL_1_1 & PRI_PRESCAL_1_1;
SPICON2Value = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT;
SPISTATValue = SPI_ENABLE;
OpenSPI1 (SPICON1Value, SPICON2Value, SPISTATValue);// setting end, SPI on
//Oscillator
}
Принцип работы:
Ведущий передает 2 байта ведомому. Ведомый получает эти байты и сравнивает их, если они совпадает по условию он посылает ответ. В противном случае ответ не посылается. Полученные 2 байта записываются в порт В. Ведущий получает ответ и записывает в порт В.
Проблема заключается в том что они получая пакет при любых значениях записывают в потр 0xFFFF, если связь разорвать они также записывают в порт 0хFFFF.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Сб ноя 08, 2014 18:54:17
alexmlw
Сегодня переписал код.
Код: Выделить всё
#include <p24hj128gp204.h>
#include <spi.h>
int main() {
unsigned int X = 3;
Init_conf();
PORTB = 0;
PORTCbits.RC4 = 0;
WriteSPI1(0xF1F2);
while (SPI1STATbits.SPITBF == 1);
PORTCbits.RC4 = 1;
PORTB = X;
while (1);
return (0);
}
void Init_conf () {
//PORTB
AD1PCFGL = 0x1FFF; //Analog module off
TRISB = 0x0000;
//PORTC
TRISC = 0x0000;
PORTCbits.RC4 = 1;
RPINR20 = 0x1F11; // SDI - RC1 (RP17)
RPOR9 = 0x0807; // SCK - RC3 (RP19) SDO - RC2 (RP18)
//SPI
SPI1CON1 = 0x063F;
SPI1CON2 = 1;
SPI1STAT = 0x8000;
//Oscillator
}
https://yadi.sk/i/kh0oaKL-caQ72 ссылка на изображение
На изображении
0-й канал - sdi
1-й канал - sdo
2-й канал - sck
3-й канал - ss (RC4)
ss переходит на низкий уровень слишком рано, и еще не закончилась передача как он перешел на высокий уровень. Чем можно исправить это смещение?
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Вс ноя 09, 2014 00:19:51
Ser60
Почоже, что флаг SPITBF устанавливается как только последний байт для передачи записан в SPI1SR, что происходит до окончания его передачи. Попробуйте отслеживать конец передачи по флагу SPIRBF в цикле while. Зачем инструкция "SPI1CON2 = 1;" ? Бит 0 в регистре SPI1CON2 не задействован.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Вс ноя 09, 2014 13:26:47
alexmlw
Ser60 писал(а):Зачем инструкция "SPI1CON2 = 1;" ? Бит 0 в регистре SPI1CON2 не задействован.
Блин, ошибся. "SPI1CON2 = 0;"
Да отслеживание по SPIRBF помогло.
https://yadi.sk/i/j3HCjXTLcajEx SS должна быть такой широкой?
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Вс ноя 09, 2014 20:10:36
Ser60
Большая ширина SS функционированию не мешает. Однако, если хотите её уменьшить, то можно:
1. Тактировать МК на большей частоте по сравнению с тактированием модуля SPI
2. Заказать оптимизацию кода в компиляторе, надеясь, что он "inline" вызов функции WriteSPI1(0xF1F2). Или вместо вызова этой функции сами напишите просто SPI1BUF=0xF1F2;
3. Вместо while цикла использовать обработчик прерываний от SPI.
4. Программировать критичные по времени фрагменты кода на АСМе.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Пт авг 28, 2015 08:58:42
Roman Venom
Код: Выделить всё
#include "p24FJ256GB206.h"
#pragma config WPDIS = WPDIS // Segment Write Protection Disable->Segmented code protection is disabled
#pragma config WPFP = WPFP255 // Write Protection Flash Page Segment Boundary->Highest Page (same as page 170)
#pragma config WUTSEL = LEG // Voltage Regulator Wake-up Time Select->Default regulator start-up time is used
#pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select->Protected code segment upper boundary is at the last page of program memory; the lower boundary is the code page specified by WPFP
#pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select->Last page (at the top of program memory) and Flash Configuration Words are not write-protected
#pragma config SOSCSEL = SOSC // Secondary Oscillator Power Mode Select->Secondary oscillator is in Default (high drive strength) Oscillator mode
#pragma config ALTPMP = ALPMPDIS // Alternate PMP Pin Mapping->EPMP pins are in default location mode
// CONFIG2
#pragma config IESO = ON // Internal External Switchover->IESO mode (Two-Speed Start-up) is enabled
#pragma config IOL1WAY = ON // IOLOCK One-Way Set Enable->The IOLOCK bit (OSCCON<6>) can be set once, provided the unlock sequence has been completed. Once set, the Peripheral Pin Select registers cannot be written to a second time.
#pragma config FNOSC = FRCDIV // Initial Oscillator Select->Fast RC Oscillator with Postscaler (FRCDIV)
#pragma config PLL96MHZ = ON // 96MHz PLL Startup Select->96 MHz PLL is enabled automatically on start-up
#pragma config PLLDIV = DIV12 // 96 MHz PLL Prescaler Select->Oscillator input is divided by 12 (48 MHz input)
#pragma config POSCMOD = NONE // Primary Oscillator Select->Primary oscillator is disabled
#pragma config OSCIOFNC = OFF // OSCO Pin Configuration->OSCO/CLKO/RC15 functions as CLKO (FOSC/2)
#pragma config FCKSM = CSDCMD // Clock Switching and Fail-Safe Clock Monitor->Clock switching and Fail-Safe Clock Monitor are disabled
// CONFIG1
#pragma config WDTPS = PS32768 // Watchdog Timer Postscaler->1:32,768
#pragma config ICS = PGx1 // Emulator Pin Placement Select bits->Emulator functions are shared with PGEC1/PGED1
#pragma config FWPSA = PR128 // WDT Prescaler->Prescaler ratio of 1:128
#pragma config WINDIS = OFF // Windowed WDT->Standard Watchdog Timer enabled,(Windowed-mode is disabled)
#pragma config GWRP = OFF // General Segment Write Protect->Writes to program memory are allowed
#pragma config GCP = OFF // General Segment Code Protect->Code protection is disabled
#pragma config FWDTEN = ON // Watchdog Timer->Watchdog Timer is enabled
#pragma config JTAGEN = ON // JTAG Port Enable->JTAG port is enabled
void main(void)
{
SYSTEM_Initialize();
SPI1BUF=100;
Nop();
Nop();
while(_SPI1IF == 0);
}
/////инициализация
void SYSTEM_Initialize(void)
{
OSCILLATOR_Initialize();
PIN_MANAGER_Initialize();
SPI1_Initialize();
}
void OSCILLATOR_Initialize(void)
{
// DOZEN disabled; DOZE 1:8; CPDIV 1:1; RCDIV FRC/2; ROI disabled;
CLKDIV = 0x3100;
// Set the secondary oscillator
}
void PIN_MANAGER_Initialize(void)
{
/****************************************************************************
* Setting the GPIO of PORTB
***************************************************************************/
LATB = 0x00;
TRISB = 0xFFFF;
/****************************************************************************
* Setting the GPIO of PORTC
***************************************************************************/
LATC = 0x00;
TRISC = 0xF000;
/****************************************************************************
* Setting the GPIO of PORTD
***************************************************************************/
LATD = 0x00;
TRISD = 0x0FFF;
/****************************************************************************
* Setting the GPIO of PORTE
***************************************************************************/
LATE = 0x00;
TRISE = 0xFF;
/****************************************************************************
* Setting the GPIO of PORTF
***************************************************************************/
LATF = 0x00;
TRISF = 0x3B;
/****************************************************************************
* Setting the GPIO of PORTG
***************************************************************************/
LATG = 0x00;
TRISG = 0x034C;
/****************************************************************************
* Setting the Analog/Digital Configuration SFR
***************************************************************************/
ANSB = 0xFFFF;
ANSC = 0x6000;
ANSD = 0xC0;
ANSF = 0x01;
ANSG = 0x0200;
/****************************************************************************
* Set the PPS
***************************************************************************/
__builtin_write_OSCCONL(OSCCON & 0xbf); // unlock PPS
RPINR20bits.SDI1R = 0x15; // RG6->SPI1:SDI1
RPOR13bits.RP26R = 0x07; // RG7->SPI1:SDO1
RPOR9bits.RP19R = 0x08; // RG8->SPI1:SCK1OUT
__builtin_write_OSCCONL(OSCCON | 0x40); // lock PPS
}
void SPI1_Initialize (void)
{
// SPI Frequency = 500 000 Hz; SSEN disabled; PPRE 1:1; SMP Sample at Middle; MSTEN enabled; MODE16 disabled; DISSCK disabled; SPRE 8:1; CKE Idle to Active; DISSDO disabled; CKP Idle:Low, Active:High;
SPI1CON1 = 0x0023;
// SPIFSD disabled; SPIFPOL disabled; SPIBEN enabled; SPIFE disabled; FRMEN disabled;
SPI1CON2 = 0x0001;
// SISEL SPI_INT_SPIRBF; SPIEN enabled; SPISIDL disabled; SPIROV disabled;
SPI1STAT = 0x800C;
}
Чтобы не плодить новую тему... Решил побаловаться с PIC24, но вот что странно - не устанавливается флаг окончания SPI1IF по окончанию записи в
. С записью вообще непонятно: после
ничего не происходит, как было 0x00 так и осталось. Вроде всё настроено верно.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Пт авг 28, 2015 09:10:09
Albert_V
Рекомендую
всегда, кроме Data Sheet, читать ещё
Errata Data Sheet.
Там, как раз, есть информация по вашей теме.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 13:07:27
Roman Venom
Да, в errata не заглядывал. Теперь буду, спасибо за наводку.
Но, это не к моему МК.
К моему вот:
http://ww1.microchip.com/downloads/en/D ... 00504g.pdfИ таv проблемы с модулем SPI нет. Тем не менее, описанные советы попробовал.
В общем, некий прогресс есть. После того как установил
//enhanced buffer off
Флаг прерывания SPI1IF начал устанавливаться.
Но вылезла другая проблема - запись в SPI1BUF происходит с ошибками, раза 4 из 10 пишется не корректное число вместо необходимой константы. Добавлял задержки после записи и проверки флага SPI1IF - не помогает. Интересно, что флаг SPI1IF устанавливается в любом случае, даже если значение SPI1BUF не меняется после записи в него.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 13:15:42
Albert_V
По SPI - посмотрите
этот pdf.
У Microchip-а, как правило, мало информации в основном pdf-е. По периферии они выкладывают отдельные Reference Manual.
----
P.S.
Извините, "Си" не знаю, поэтому по вашей программе ничего подсказать не смогу.
Я пишу программы на ASM30.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 15:05:38
КРАМ
У него в исходнике собственно на Си ничего и не написано.
Потому понятно и без знаний этого языка.
Единственная особенность Си компилятора у 24/33-х - это структуры для обращения к битам или группам бит.
Выглядит как
<ИмяРегистра>bits.<имяБита/группыБит>
Объявление структур регистров специального назначения есть в хедере контроллера под Си (h-файл).
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 15:27:42
Albert_V
C SPI у PIC24FJ64GB004 (работа по SPI одна и та же), под которого я сейчас пишу программу, никаких проблем нет.
Работаю с OLED с контроллером SSD1306 (общение по SPI).
С низшим приоритетом, подпрограмма (когда ей выделяется время) "сливает" VideoRam в OLED "по кругу". Никаких ошибок нет.
Фото моей платы:
Спойлер


и схема без номиналов (в прикреплённом файле).
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 15:56:29
Roman Venom
Ну а в общем, почему может происходить запись в буфер с ошибкой? Питание проверил, с частотами SPI игрался...странно всё.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Ср сен 02, 2015 16:02:21
Albert_V
Случайно, нет ситуации, при которой вы "закидываете" данные в буфер до окончания передачи?
У себя я делаю проверку (ожидание) так:
Спойлер
Код: Выделить всё
WAITSPIIF:
btss IFS0,#SPI1IF
goto WAITSPIIF
bclr IFS0,#SPI1IF
mov SPI1BUF,W3
RETURN
Чтение SPI1BUF по флагу SPI1IF Master-у нужно делать обязательно (!)
(даже, если это не требуется по алгоритму работы программы)!
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 09:19:32
Roman Venom
Короче, всё работало изначально. Это особенность (глюк?) PIC24+PICKIT3. В железе всё работает, в протеусе тоже.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 09:27:15
Albert_V
Можете более конкретно объяснить в чём был глюк?
Я работаю, в основном, с PIC24F и PIC24H в MPLAB+ICD3 и не замечал никаких проблем (учитывая информацию из Errata).
/Протезом не пользуюсь/.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 11:46:35
Roman Venom
При записи данных в SPIxBUF при отладке PICKIT3 в самом регистре SPIxBUF ничего не появляется (0х00), как будто бы запись не прошла. Однако реально всё отправляется корректно. В случае приёма данных в SPIxBUF всё отображается корректно.
MK PIC24FJ256GB206
Так что вот такой глюк. Похоже на глюк отладчика.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 12:07:29
Albert_V
Roman Venom писал(а):При записи данных в SPIxBUF при отладке PICKIT3 в самом регистре SPIxBUF ничего не появляется (0х00), как будто бы запись не прошла.....
Правильно, значение регистра SPIxBUF он вам и не должен сразу показать, поскольку вы имеете право считать его значение
только по окончании передачи/приёма байта. Во время передачи не надо пытаться считывать его значение.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 12:11:07
КРАМ
Roman Venom писал(а):При записи данных в SPIxBUF при отладке PICKIT3 в самом регистре SPIxBUF ничего не появляется (0х00), как будто бы запись не прошла.
А там и на самом деле ничего не появляется. Точнее появляется и тут же сбрасывается в регистр сдвига SPIxSR, программного доступа к которому нет.
Вы ищите черную кошку в темной комнате...
По сути на передаче как такового буферного регистра нет.
Re: PIC24HJ128GP204 осваиваю SPI
Добавлено: Чт сен 17, 2015 13:19:25
Roman Venom
Угу. Протеус ввёл в заблуждение. Вопрос разрешился, самое главное.