|
Пример работы SPI в MSP430F149, совместно с PGA2310 |
|
|
|
Jan 13 2009, 21:38
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
Помогите плиз, мучаюсь с микрухой PGA2310, управляется по SPI, так вот ни одна реализация для MSP430F149 не работает у меня, пришлите код рабочего примера с инициализацией и тупо передачей байтов по SPI. Пожайлуста очень надо!
|
|
|
|
|
Jan 14 2009, 05:22
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 11-03-07
Из: Украина, Харьков
Пользователь №: 26 059

|
Инициализация Код //структуры для SPI struct __TX { char TXData[20]; char CurrByte; char TotalToTX; char TXBusy; };
struct __RX { char RXData[20]; char CurrByte; char TotalRXed; };
void initSPI() { P3SEL = 0x0E; P3DIR = 0x0A; U0CTL = SWRST + SYNC + CHAR + MM; U0TCTL |= SSEL1 + STC + CKPH /*+ CKPL*/; U0BR0 = 0x08; U0BR1 = 0x00; U0MCTL = 0x000; ME1 = USPIE0; U0CTL &= ~SWRST; IE1 |= URXIE0; } Обработчик прерывания Код #pragma vector=USART0RX_VECTOR __interrupt void SPI0_rx (void) { unsigned long spi_buf; spi_buf = U0RXBUF; RX.RXData[RX.CurrByte++] = (unsigned char)(spi_buf&0x00FF); RX.TotalRXed = RX.CurrByte; if ((++TX.CurrByte <= TX.TotalToTX)&&(TX.TXBusy)) { U0TXBUF = TX.TXData[TX.CurrByte]; } else { TX.TXBusy = 0; TX.CurrByte = 0; fDataTransfer = 0; NSS_CONFIG(1); //end SPI Transaction - CS - в "1" } } Использование Код //setting NSS_Config Setting void NSS_CONFIG(char SET) { if(SET) P1OUT |= _BV(4); else P1OUT &= ~_BV(4); }
void do_SPI1_start_TX() { TX.TXBusy = 1; TX.CurrByte=0; RX.CurrByte=0; NSS_CONFIG(0); //end SPI Transaction - CS - в "0" U0TXBUF = TX.TXData[TX.CurrByte]; // TX.CurrByte++; }
}
|
|
|
|
|
Jan 16 2009, 13:39
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
я немного видоизменил, практически ничего совсем, но сигнал попрежнему не передаеться. Точнее осциллографом не смотрел еще пока, но вот на выходе PGA3210 стабильный "0" при подаче на вход переменногг напряжения в 0,5 В 2кГц. Может быть что нибудь посоветуете, например в схеме ключения? Понятно что надо осциллографом глянуть но пока не добраться мне до него, увы. Вот что касаеться примера, то я сменил прирывание по приему на прерывание по передатчики, может быть это неверно совсем?, но подключаеться у меня только MOSI и UCLK., ну и еще CS.
Сообщение отредактировал _AlexMan_ - Jan 16 2009, 13:42
|
|
|
|
|
Jan 16 2009, 14:14
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(_AlexMan_ @ Jan 16 2009, 18:39)  Может быть что нибудь посоветуете, например в схеме ключения? А что можно посоветовать, если вы не показываете свою схему? Телепатию в форумчан тренируете? Цитата(_AlexMan_ @ Jan 16 2009, 18:39)  Вот что касаеться примера, то я сменил прирывание по приему на прерывание по передатчики, может быть это неверно совсем?, но подключаеться у меня только MOSI и UCLK., ну и еще CS. Аналогично. Откуда мы знаем, что на что вы там поменяли и как используете SPI вообще и CS в частности? Схему и исходный код в студию!
|
|
|
|
|
Jan 16 2009, 14:40
|
Частый гость
 
Группа: Свой
Сообщений: 158
Регистрация: 15-01-09
Из: Russia
Пользователь №: 43 426

|
Можно вот так попробовать. Написать SPI вручную, на те же самые выводы, без использования прерываний, и прямым управлением выводов портов. SPI в MSP430 работает своеобразно, и не факт, что заработает сходу, может где то тактового импульса не хватает для PGA2310.А написанный вручную легко проверить, что и как работает, и как PGA2310 на него реагирует. После того как запустите прием и передачу в ручном режиме, потом можно один канал, например передачу сделать в автомате на SPI, а прием опять же вручную. И наконец оба направления в автомате.
|
|
|
|
|
Jan 16 2009, 21:44
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
Вот исходный текст CODE #define bitset(var,bitno) ((var) |= 1 << (bitno)) #define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
#define B1 BIT4&P4IN //B1 - P4.4
void initSPI(); void NSS_CONFIG(char SET); void do_SPI1_start_TX();
//структуры для SPI // структура передачи typedef struct { char TXData[20]; char CurrByte; char TotalToTX; char TXBusy; } __TX;
// структура приема typedef struct { char RXData[20]; char CurrByte; char TotalRXed; } __RX;
__TX TX; __RX RX;
#pragma vector=USART0TX_VECTOR __interrupt void TxD() { if ((++TX.CurrByte < TX.TotalToTX)&&(TX.TXBusy)) { U0TXBUF = TX.TXData[TX.CurrByte];// передача байтов из буффера } else { TX.TXBusy = 0; TX.CurrByte = 0; NSS_CONFIG(1); //end SPI Transaction - CS - в "1" } }
void initSPI() { P3SEL = 0x0E; P3DIR = 0x0A; U0CTL = SWRST + SYNC + CHAR + MM; U0TCTL |= SSEL1 + STC + CKPH /*+ CKPL*/; U0BR0 = 0x08; U0BR1 = 0x00; U0MCTL = 0x000; ME1 = USPIE0; U0CTL &= ~SWRST; IE1 |= UTXIE0; }
//setting NSS_Config Setting void NSS_CONFIG(char SET) { if(SET) bitset(P6OUT,7); else bitclr(P6OUT,7); }
void do_SPI1_start_TX() { TX.TXBusy = 1; TX.CurrByte=0; RX.CurrByte=0; NSS_CONFIG(0); //start SPI Transaction - CS - в "0" U0TXBUF = TX.TXData[TX.CurrByte]; }
void main(void) { int flag = 0; P6DIR |= 0x80; bitset(P6OUT,7); TX.TotalToTX = 2; TX.TXData[0] = 0x2d; // просто для примера TX.TXData[1] = 0x7d; initSPI(); while(1) { if (((B1) == 0)&&(flag == 0)) //B1 is pressed { flag = 1; do_SPI1_start_TX(); } } } , все вроде предельно просто, но не работает  Вот используемая схема соединений
|
|
|
|
|
Jan 17 2009, 06:43
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 11-03-07
Из: Украина, Харьков
Пользователь №: 26 059

|
Цитата(_AlexMan_ @ Jan 16 2009, 15:39)  я сменил прирывание по приему на прерывание по передатчики Во-первых, как и говорил rezident, установите глобальные прерывания (__enable_interrupt()), кроме того, у SPI принцип работы заключается в том, что передача байта от мастера одновременно означает прием байта от Slave. Поэтому вектор прерывания можно было не менять. Ну и, в довершение, хотя на данный момент это не актуально, в while() проверять кнопку так, как Вы это делаете, мягко говоря, нехорошо. Контроллер за очень маленькое время напередает кучу данных по SPI. Такую работу хорошо делать по таймеру. И обычно надо сделать антидребезг.
|
|
|
|
|
Jan 20 2009, 11:48
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 11-03-07
Из: Украина, Харьков
Пользователь №: 26 059

|
Цитата(_AlexMan_ @ Jan 16 2009, 23:44)  #pragma vector=USART0TX_VECTOR __interrupt void TxD() { ... } [/code] все вроде предельно просто, но не работает  Там есть еще одна тонкость. Преывание USART0TX_VECTOR в MSP430 работает по освобождению буфера, а не по фактической передаче байта. Это позволяет, в числе прочего, не делать задержек при передаче массивов – сразу после стоп-бита идет старт бит следующего байта. Но если буфер освободился, то это означает лишь, что можно класть в буфер следующий байт, а не то, что произошел обмен байтами. Поэтому использовать надо именно как я показывал - USART0RX_VECTOR. Стормозил - это надо было сразу заметить
|
|
|
|
|
Jan 20 2009, 15:55
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
Исправил все замечания, за них спасибо. Все таки посмотрел осциллографом, тактирующие импульсы не идут, но если в режиме отладке прогонять то в обработчик прерывания по приему заходит, но при этом я ничего не подключаю на вход MISO! Проверил бит LISTEN там 0. А сама PGA молчит как и прежде. Может кто нибудь подсобит с программной реализацией SPI, хотелось бы тогда уж и с ней попытать счастья
Сообщение отредактировал _AlexMan_ - Jan 20 2009, 15:57
|
|
|
|
|
Jan 20 2009, 19:01
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 11-03-07
Из: Украина, Харьков
Пользователь №: 26 059

|
Цитата(_AlexMan_ @ Jan 20 2009, 17:55)  Все таки посмотрел осциллографом, тактирующие импульсы не идут На всякий случай - осциллограф аналоговый или цифровой? Все-таки эти тактирующие импульсы идут всего-лишь за время 16/fтакт (при двух передаваемых байтах) – единицы микросекунд – и не углядишь
|
|
|
|
|
Jan 21 2009, 08:15
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
аналоговый, но при развертки 1мкс должно же что то происходить на экране, а не просто отображаться на тактирующем выходе стабильно 0, а на MOSI почему то стабильно 1. А тактирующие импульсы идут всегда как только произошла инициализация SPI или только непосредственно при передачи данных?
|
|
|
|
|
Jan 21 2009, 11:31
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 11-03-07
Из: Украина, Харьков
Пользователь №: 26 059

|
Так, на всякий случай. Посмотри, пожалуйста, с каким именно USART ты работаешь - там их два, и, может быть, просто не тот настроили и не с тем работаем. Код, который я приводил, предназначен для USART0. Это первая проверка. Во-вторых, попробуй такой код. Код </P><P>void main(void) { P6DIR |= 0x80; bitset(P6OUT,7); initSPI(); //прерывания не разрешаем!!! //все делаем по флагу while(1) { //для проверки линию CS не дергаем - //пусть слейв не мучается U0TXBUF = 'A'; while (!(IFG1 & UTXIFG0)); } }
</P><P> Он все время передает байты и в таком режиме ты точно увидишь, идет что-то или нет на линии SCLK. Кстати, проверишь сразу линию MOSI.
|
|
|
|
|
Jan 22 2009, 21:25
|
Группа: Новичок
Сообщений: 7
Регистрация: 13-01-09
Пользователь №: 43 325

|
Нет уарт то точно тот, было бы обидно в этом ошибиться). Я посмотрел цифровым осциллографом вариант без обработки прерываний: данные передаються и тактирующие импульсы тоже имеются, проблема во времени установки и снятия сигнала CS. вот сейчас сигнал снимаеться раньше чем осуществляется передача второго байта коэфициэнтов. И выставляется намного раньше подачи первого тактирующего импульса. Какими должны быть данные временные интервалы между фронтами CS и тактирующими импульсами?
Сообщение отредактировал _AlexMan_ - Jan 22 2009, 21:40
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|