реклама на сайте
подробности

 
 
> Не работает прерывание SPI1 dsPIC33FJ256GP710, Не работает прерывание SPI1 в режиме SPI slave Framed slave
MasterM12
сообщение Aug 6 2013, 05:14
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 18-08-07
Из: Омск
Пользователь №: 29 871



Доброго времени суток! Столкнулся со следующей проблемой: при инициализации модуля SPI1 в режим SPI slave Framed slave контроллер не входит в прерывание по импульсам на ноге SS1. В других режимах работы модуля прерывание отрабатывает. Обмен происходит с АЦП, которая и генерирует клоки и импульсы кадровой синхронизации. Возможно в этом режиме прерывание и не должно срабатывать, но в дата- и эррата-шитах этого не нашел. Разработка ведется в среде MikroC for dsPIC/PIC24 ver.6.0. АЦП ADS1601, тактируется от LTC6903.
Привожу кусок кода программы:
Код
void Start_ADC(void)                 //инициализация SPI1, прерывания от SPI1, и в конце - разрешение тактирования АЦП
{
sampling_flag = 1;


TRISF6_bit = 1; //SCK1
TRISF7_bit = 1; //SDO1
TRISF8_bit = 1; //SDI1
TRISB2_bit = 1; //SS1

SPI1STATbits.SPIEN = 0;

SPI1CON2bits.FRMDLY = 1;
SPI1CON2bits.FRMPOL = 1;
SPI1CON2bits.SPIFSD = 1;
SPI1CON2bits.FRMEN = 1;

SPI1CON1bits.PPRE = 4;
SPI1CON1bits.SPRE = 3;
SPI1CON1bits.MSTEN = 0;
SPI1CON1bits.CKP = 0;
SPI1CON1bits.SSEN = 0;
SPI1CON1bits.CKE = 1;
SPI1CON1bits.SMP = 0;
SPI1CON1bits.MODE16 = 1;
SPI1CON1bits.DISSDO = 1;
SPI1CON1bits.DISSCK = 0;

  SPI1STATbits.SPISIDL = 1;


IFS0bits.SPI1EIF = 0;
IFS0bits.SPI1IF = 0;
IEC0bits.SPI1IE = 1;
IPC2bits.SPI1IP = 4;

SPI1STATbits.SPIEN = 1;

oe_6903 = 1;        //start of SPI master
}



void SPI1Interrupt() iv IVT_ADDR_SPI1INTERRUPT ics ICS_AUTO             //Обработчик прерывания, сюда не входит
{
unsigned int aSample, tmp;
aSample = SPI1BUF;
IFS0bits.SPI1IF = 0;         //Clear Interrupt status of SPI1
SPI1STATbits.SPIROV = 0;
IEC0bits.SPI1IE =1;
}


void main() {

  Start_ADC();

  while (1) {
      //////////////////////// ничего больше не делаем

  }

}


Ниже приведены осциллограммы на SS1, SCLK1 и SDI1 соответственно (все ноги сконфигурированы на вход)
Прикрепленное изображение

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MasterM12
сообщение Aug 7 2013, 10:20
Сообщение #2





Группа: Новичок
Сообщений: 6
Регистрация: 18-08-07
Из: Омск
Пользователь №: 29 871



Неправильно выразился, в инициализации сначала делаю фиктивное чтение, а потом обнуляю SPIROV (для надежности sm.gif), а прерывание так и молчит. Сделал сейчас просто SPI Slave - все срабатывает, берутся семплы от АЦП, но пока не разобрался с фазой клоков, т.к. АЦП CS поднимает по 15 клоку, и 16-й клок проходит уже при поднятом CS. По идее старший бит должен теряться(в сдвиговый регистр вдвигается 15 бит вместо 16). Наверное вследствие этого в результатах проскакивает и старший и младший биты одновременно при КЗ входа АЦП, хотя по осциллограмме шумит 4 младших бита, остальные - в нулях.
Вобщем пошел разбираться с полярностью и фазой клоков, и в АЦП есть прямые и инверсные клоки, может что получится.
На рисунке осциллограмма данных с АЦП при подаче на вход 100 мВ.
Прикрепленное изображение

P.S. Все же интересно, кто-то из форумчан заводил SPI в framed slave mode c прерываниями? У меня уже ощущение что это в принципе невозможно (баг камня).

Инициализация SPI теперь выглядит так:
Код
void Start_ADC(void)
{
int tmp;
sampling_flag = 1;
//SPI1_Init_Advanced(_SPI_SLAVE, _SPI_16_BIT, _SPI_PRESCALE_SEC_4, _SPI_PRESCALE_PRI_4, _SPI_SS_ENABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE);

TRISF6_bit = 1; //SCK1
TRISF7_bit = 1; //SDO1
TRISF8_bit = 1; //SDI1
TRISB2_bit = 1; //SS1

SPI1STATbits.SPIEN = 0;

SPI1CON2bits.FRMDLY = 0;
SPI1CON2bits.FRMPOL = 0;
SPI1CON2bits.SPIFSD = 0;
SPI1CON2bits.FRMEN = 0;

SPI1CON1bits.PPRE = 4;
SPI1CON1bits.SPRE = 3;
SPI1CON1bits.MSTEN = 0;
SPI1CON1bits.CKP = 1;
SPI1CON1bits.SSEN = 1;
SPI1CON1bits.CKE = 1;
SPI1CON1bits.SMP = 0;
SPI1CON1bits.MODE16 = 1;
SPI1CON1bits.DISSDO = 1;
SPI1CON1bits.DISSCK = 0;

SPI1STATbits.SPISIDL = 1;
IFS0bits.SPI1EIF = 0;
IFS0bits.SPI1IF = 0;
IEC0bits.SPI1IE = 1;
IPC2bits.SPI1IP = 4;

tmp = SPI1BUF;                      // Фиктивное чтение буфера
SPI1STATbits.SPIROV = 0;       // Сброс флага SPIROV
SPI1STATbits.SPIEN = 1;

ADS1601_sync = 0;
ADS1601_PD = 1;
delay_ms(1000);
oe_6903 = 1;
}


Сообщение отредактировал MasterM12 - Aug 7 2013, 10:21
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01368 секунд с 7
ELECTRONIX ©2004-2016