|
SPI master 4-wire |
|
|
|
Feb 24 2006, 16:08
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Подскажите: 1. Я сконфигурировал SPI в 4-х проводный мастер. Пины : P3SEL=0x0F: P3.0 - STE P3.1 - SIMO P3.2 - SOMI P3.3 - UCLK Перед передачей MASTER - > SLAVE подаём на STE сигнал низкого уровня. Как это правильно сделать в коде? Мой вариант: P3DIR|=0x01; P3OUT|=0x00; не прошёл.
2. Дайте ссылу на литературу где можно подробнее почитать о 4-wire SPI для MSP430. Я пользовался slau056e и msp430f*44* там очень поверхностно Заранее спасибо.
|
|
|
|
|
Feb 26 2006, 01:26
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Дело в том, что я подключаю к микроконтроллеру датчик. Он точно сконфигурирован как SLAVE - у него 4 провода в том числе и STE . Сам SLAVE может послать такой сигнал?
|
|
|
|
|
Feb 26 2006, 10:43
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Проанализировал драйвер датчика там STE как input. Используется для зазрешения передачи и приёма slave и инициируется master-ом.
|
|
|
|
|
Feb 26 2006, 15:13
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Да нет никакого секрета - датчик отпечатков пальцев. То есть вы предлагаете сделать вот так для мастера: P3SEL=0x0E; // конфигурим пины SPI P3DIR=0x01;// P3.0 как универсальный I/O на выход и держим высокий уровень P3OUT=0x01;// P3OUT&=~0x01; // перед началом передачи посылаем низкий уровень p3OUT=0x01; // по окончанию передачи опять востанавливаем высокйй ?
|
|
|
|
|
Feb 27 2006, 15:41
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
для сканирования отпечатка. К контроллеру подключается датчик с одной стороны, с другой модем. Должно получиться что-то типа модуля для передачи отпечатков пальцев. Скажите, а при установке источника тактирования: 1) UTCTL=SSEL1+SSEL0; (1 1 - SMCLK); 2) UTCTL=SSEL1; (1 0 - SMCLK) есть разница между 1 и 2 случаем?
|
|
|
|
|
Mar 2 2006, 03:33
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Ещё один вопрос: когда в Rg FLL_CTL бит XTS_FLL=0 - используется низкочастотный режим. при нём определяется значение битов XCAPxPF. В примерах кодов texas нашёл 2 случая: FLL_CTL0|=XCAP18PF; FLL_CTLO|=XCAP14PF; (Я по началу думал что это ёмкость (в пФ) нагрузочных конденсаторов для кварцевого резонатора, но в документации определено всего 4 значения: 1,6,8,10) Что означают 18 и 14 в записях и по какому принципу они выбираются?
|
|
|
|
|
Mar 2 2006, 10:30
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Все верно. XCAPxxPF соответствуют значению конденсатора в pF. Дело в том, что значения 1pF, 6pF, 8pF и 10pF вы видимо прочитали в User's Guide, которое одно на все семейство MSP430x4xx. Но в даташите MSP430F427 указаны другие значения этих конденсаторов, конкретно для этого кристалла: 0pF, 10pF, 14pF и 18pF. см. таблицу crystal oscillator, LFXT1 oscillator. Параметры подобные этому всегда нужно уточнять в datasheet конкретного кристалла, а не брать из руководства.
|
|
|
|
|
Mar 2 2006, 15:17
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Посмотрел даташит на f499 - c частотами всё так как вы сказали. Но пояснение дано только на использование 0pF при наличие внешних емкостей. 32кГц кристал можно включить пользуясь только XCAPxxPF без внешних емкостей. Разница в емкостях 10, 14, 18 не велика - получается нет принципиальной разницы в использовании?
|
|
|
|
|
Mar 3 2006, 08:35
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
У меня в устройстве: P3.4 для подачи сигнала STE на датчик P3.5 для подачи RESET перед началом инициализации датчика с контроллера P3.6 как IN. К нему подключена кнопка (по нажатию которой мастер инициирует передачу со slave) и STE и RESET низкого уровня P3.6 - активный уровень высокий. начальные значения такие: P3DIR=0x30; на выход P3OUT=0X30; держим высокий уровень Можно ли сбросить каждый бит в отдельности (чтоб состояние других осталось прежним) таким образом: P3OUT&=~0x20; // reset P3OUT=0x30; // восстанавливаем прежнее значение P3OUT&=~0x10; // ste P3OUT=0x30; // по окончанию передачи а также независимо проверять содержимое бита для P3.6 (while (P3IN=0x00) {...}) ??????????????
P.S. спасибо за ссылку на литературу по кристалам - очень помогла.
|
|
|
|
|
Mar 3 2006, 09:11
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Если вы работаете с отдельными битами, то накладывайте маску при операциях с портами во всех случаях. Не Код P3OUT=0x30; а Код P3OUT|=0x30; или Код P3OUT|=BIT4+BIT5; Не Код while (P3IN=0x00) {....} а Код while ((P3IN&0x40)==0) {...} или Код while ((P3IN&BIT6)==0) {...} Макросы BITx определены в заголовочном файле msp430x4xx.h
|
|
|
|
|
Mar 3 2006, 14:47
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
То есть запись P3OUT|=0x30; определяет, что конфигурируются только пины P3.4 P3.5 в остальных сохранится значение по умолчанию после PUC и тогда сброс одного из них будет выглядеть как P3OUT&=~BIT4;?
P.S. подскажите у Texas есть докумментация по языку СИ для MSP430? - очень бы хотелось освоить его
|
|
|
|
|
Mar 3 2006, 15:23
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Отвечу с конца. У TI нет документации по СИ, т.к. фирма TI в основном производит полупроводниковые изделия, а не компиляторы  Для изучения Си начните с азов. Например, прочтите отцов-основателей Керниган, Ричи. "Язык C". В Интернете легко найдете. После этого все будет вполне понятно. В т.ч. и порядок действий в описанных выражениях. Выражение Код P3OUT|=0x30; означает, что - в качестве аргумента берется содержимое регистра P3OUT; - затем выполняется операция побитового сложения P3OUT и константы 0x30; - результат операции записывается снова в регистр P3OUT. В целом выражение эквивалентно такой записи. Код P3OUT=P3OUT|0x30; BIT4 во втором вашем выражении на самом деле определен макросом вида Код #define BIT4 0x10 и компилятор вместо совокупности символов BIT4 везде подставляет его значение 0x10Выражение Код P3OUT&=~BIT4; эквивалентно Код P3OUT=P3OUT&(~0x10); где ~0x10, в свою очередь, компилятор преобразует в его инверсию 0xEF. Т.е. выражение можно было бы записать как Код P3OUT=P3OUT&0xEF; Интересно, а как вы сами ранее в ваших же примерах использовали операцию P3OUT&=~0x20;? По наитию что ли?  Или по аналогии с чем-то?
|
|
|
|
|
Mar 4 2006, 04:21
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
=) блин, ну я и дал маху. Я по выражению UCTL&=~SWRST решил что это обычная бит-инверсия и даже не обратил внимание на знак логического умножения. Тогда получается что при P3OUT|=0x30; Добится сброса P3.4 можно исклфчающим или P3OUT^=0x10;? Тогда по этому же вопрос когда пишем условие while((P3IN&BIT6)==0) запись в скобках имеет значение P3IN&0x40 и проверяется равно ли оно 0?
|
|
|
|
|
Mar 4 2006, 21:42
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Fenriz @ Mar 4 2006, 09:21)  Тогда получается что при P3OUT|=0x30; Добится сброса P3.4 можно исклфчающим или P3OUT^=0x10;? Можно конечно, но только если есть некая определенность этот бит был ранее сброшен и/или что в каком-нибудь другом месте программы этот бит не будет изменен. Накладывание маски по ИЛИ или по И более определено по результату, чем инверсия по XOR. Цитата(Fenriz @ Mar 4 2006, 09:21)  Тогда по этому же вопрос когда пишем условие while((P3IN&BIT6)==0) запись в скобках имеет значение P3IN&0x40 и проверяется равно ли оно 0? Да, P3IN&BIT6 это то же самое P3IN&0x40, если ранее BIT6 определен как 0x40. Цикл внутри while будет выполняться до тех пор, пока 6-й бит сброшен. Можно было бы это же записать как Код while !(P3IN&BIT6) , но такая запись не очень наглядная и в каких-то компиляторах возможно будет обрабатываться неверно. Я вообще не спец по компиляторам, может поэтому последняя запись меня обычно заставляет морщить лоб, в отличие от предыдущей
|
|
|
|
|
Mar 5 2006, 15:32
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Я не совсем понял про "исключающее или". Не могли бы вы объяснить по-конкретнее? И ещё вопрос: при выборе частоты тактирования для SPI: кристал 32кГц, fMCLK - 1МГц. В режиме SPI модуляция не используется и мы UMCTL=0. Нужно ли запретить модуляцию битом SCFQ_M в регистре SCFQCTL (установить бит в 1) или это не обязательно? В Rg UBR0 и UBR1 можно задать любой целый коэффициент деления частоты (не менее 2)?
|
|
|
|
|
Mar 6 2006, 09:57
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Fenriz, извините, но тема все более скатывается для раздела "начинающих". Вы попробуйте все же самостоятельно почитать необходимую литературу. Или как некоторые любят "выражопываться" RTFM.  Без обид, но чтение справочника по Си и User's Manual MSP430x1xx ( MSP430x4xx) Family даст 100% ответы на все ваши вопросы. Скажу только про модуляцию. Вы видимо путаете регистр модуляции USART и модуляцию в FLL. Читайте оба раздела внимательно.
|
|
|
|
|
Mar 6 2006, 13:19
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Я всё понимаю. Спасибо, вы и так мне сильно помогли.
|
|
|
|
|
Mar 11 2006, 05:33
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Не могу понять в чём дело: У меня при приходе данных через SPI должно генерироваться прерывание по которому идёт передача с интерфейса SPI на UART. Текст такой void main (void) { WDTCTL=WDTPW+WDTHOLD; P3SEL=0x0E; // для SPI (USART0) U0CTL=CHAR+SYNC+MM+SWRST; U0TCTL=CKPL+SSEL1+SSEL0+STC; U0BR0=0x02; U0BR1=0x00; U0MCTL=0x00; ME1=USPIE0; U0CTL&=~SWRST; IE1|=URXIE0; P4SEL=0x03; // для UART (USART1) ME2 |= UTXE1 + URXE1; U1CTL |= CHAR+SWRST; U1TCTL |= SSEL1+SSEL0+URXSE; U1BR0=0x09; U1BR1=0x00; U1MCTL=0x08; U1CTL&=~SWRST; IE2 |= URXIE1; _EINT(); while (1) { while (!(IFG1&UTXIFGO)); // проверяем буфер TXBUF0=0xFF; } __interrupt void usart0_rx (void); USART0RX_ISR (usart0_rx) __interrupt void usart0_rx (void){ while (!(IFG1&URXIFG0)); // проверяем принят ли символ целиком while (!(IFG2&UTXIFG1)); // свободен ли TXBUF у UART TXBUF1=RXBUF0;} Среда маркерует строку USART0RX_ISR (usart0_rx) __interrupt void и выдаёт "the operation is unavailable on the current selection". С чем это может быть связано?
|
|
|
|
|
Mar 11 2006, 21:46
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Я не совсем понял каким компилятором вы пользуетесь, но, например, в IAR EW430 прерывание оформляется так Код #pragma vector=UART1RX_VECTOR #pragma type_attribute=__interrupt void uart1_rx_isr(void) { ...... } либо так Код #pragma vector=UART1RX_VECTOR __interrupt void uart1_rx_isr(void) { ...... } мнемонику обозначения векторов (адрес) можно взять из хидера файла. Например, в msp430x44x.h в самом конце файла есть блок дефайнов Код /************************************************************ * Interrupt Vectors (offset from 0xFFE0) ************************************************************/
#define BASICTIMER_VECTOR (0 * 2u) /* 0xFFE0 Basic Timer */ #define PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */ #define USART1TX_VECTOR (2 * 2u) /* 0xFFE4 USART 1 Transmit */ #define USART1RX_VECTOR (3 * 2u) /* 0xFFE6 USART 1 Receive */ #define PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */ #define TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */ #define TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ #define ADC12_VECTOR (7 * 2u) /* 0xFFEE ADC */ #define USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */ #define USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */ #define WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */ #define COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */ #define TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1-6, TB */ #define TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */ #define NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maskable */ #define RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */
#define UART1TX_VECTOR USART1TX_VECTOR #define UART1RX_VECTOR USART1RX_VECTOR #define UART0TX_VECTOR USART0TX_VECTOR #define UART0RX_VECTOR USART0RX_VECTOR #define ADC_VECTOR ADC12_VECTOR
|
|
|
|
|
Mar 12 2006, 15:18
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Я пользуюсь CodeComposer. Когда я вектор задавал как: #pragma vector=UART0RX_VECTOR __interrupt void uart0_rx_isr(void) { ...... } Среда жалуется на грамматику и говорит что значение #pragma vector для неё не определено. В случае когда __interrupt void usart0_rx (void); USART0RX_ISR (usart0_rx) __interrupt void usart0_rx (void){ ...... } жалоб на грамматику нет (лог problems говорит что ошибки и замечания отсутствуют). Но строка маркерутся и при просмотре деклорации для неё "вылазит" та дрянь о которой я писал ранее
Да, чуть не забыл у меня в msp430x44x.h описание несколько отличается.
* Interrupt Vectors (offset from 0xFFE0) ************************************************************/
#define BASICTIMER_ISR(func) ISR_VECTOR(func, ".int00") /* 0xFFE0 Basic Timer */ #define PORT2_ISR(func) ISR_VECTOR(func, ".int01") /* 0xFFE2 Port 2 */ #define USART1TX_ISR(func) ISR_VECTOR(func, ".int02") /* 0xFFE4 USART 1 Transmit */ #define USART1RX_ISR(func) ISR_VECTOR(func, ".int03") /* 0xFFE6 USART 1 Receive */ #define PORT1_ISR(func) ISR_VECTOR(func, ".int04") /* 0xFFE8 Port 1 */ #define TIMERA1_ISR(func) ISR_VECTOR(func, ".int05") /* 0xFFEA Timer A CC1-2, TA */ #define TIMERA0_ISR(func) ISR_VECTOR(func, ".int06") /* 0xFFEC Timer A CC0 */ #define ADC12_ISR(func) ISR_VECTOR(func, ".int07") /* 0xFFEE ADC */ #define USART0TX_ISR(func) ISR_VECTOR(func, ".int08") /* 0xFFF0 USART 0 Transmit */ #define USART0RX_ISR(func) ISR_VECTOR(func, ".int09") /* 0xFFF2 USART 0 Receive */ #define WDT_ISR(func) ISR_VECTOR(func, ".int10") /* 0xFFF4 Watchdog Timer */ #define COMPARATORA_ISR(func) ISR_VECTOR(func, ".int11") /* 0xFFF6 Comparator A */ #define TIMERB1_ISR(func) ISR_VECTOR(func, ".int12") /* 0xFFF8 Timer B CC1-6, TB */ #define TIMERB0_ISR(func) ISR_VECTOR(func, ".int13") /* 0xFFFA Timer B CC0 */ #define NMI_ISR(func) ISR_VECTOR(func, ".int14") /* 0xFFFC Non-maskable */ #define RESET_ISR(func) ISR_VECTOR(func, ".int15") /* 0xFFFE Reset [Highest Priority] */
#define UART1TX_VECTOR USART1TX_VECTOR #define UART1RX_VECTOR USART1RX_VECTOR #define UART0TX_VECTOR USART0TX_VECTOR #define UART0RX_VECTOR USART0RX_VECTOR #define ADC_VECTOR ADC12_VECTOR
|
|
|
|
|
Mar 13 2006, 08:01
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Вам случайно не приходилось встречаться с Olimex development board MSP430?
|
|
|
|
|
Mar 29 2006, 14:06
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Необходим совет:........... приём данных с SPI-slave у меня осуществляется по прерыванию (IE1|=URXIE0), но в некоторых случаях в процессе передачи данных на мастер прерывание необходимо запретить. Можно ли это организовать с помощью команд _DINT(); _EINT();? _DINT(); .... инициация передачи данных на приход которых прерывание не требуется; _EINT();
|
|
|
|
|
Mar 30 2006, 06:12
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Уважаемый resident, пытаюсь отладить программу, но пока безуспешно. МК инициализируется успешно - проверил состояние регистров после прошивки всё соответствует. У меня складывается впечатление, что после выполнения функции обработки прерывания, МК не возвращается к выполнению прерваной операций в main. Можно ли это сделать по средствам команды (или это автоматический процесс)?
|
|
|
|
|
Apr 4 2006, 12:13
|
Группа: Новичок
Сообщений: 10
Регистрация: 26-02-06
Из: Россия, Москва
Пользователь №: 14 695

|
Можно попытаться определить, где висит программа. Например так (независимо, на С написано или на asm). ; тело программы MAIN команда_1 ... команда_101 <-- тут breakpoint ... идти_на_MAIN ; тело обработчика прерывания UART0RX UART0_RX команда_1 ... какой-то_цикл команда_51 ... команда_101 <-- и тут breakpoint выход_из_прерывания Запустить это дело, подождать некоторое время и прервать работу (или же работа сама прервется по bp). Возможны варианты. Основное тело программы (main) не выполняется.. Программа уходит в прерывание, выходит из него и сразу же снова входит. Или же, если в обработчике прерывания есть некий цикл, то возможно зависание внутри него, т.е. не происходит даже выхода из прерывания. Кстати, очень помогает в некоторых точках программы "дергание" определенной ножкой процессора (простой xor). На осциллографе удобно можно смотреть процесс (не)работы программы
--------------------
// OveR
|
|
|
|
|
May 7 2006, 08:22
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 12-12-05
Пользователь №: 12 106

|
Уважаемый resident, по поводу векторов прерывания вы были правы. В тексте программы было разрешено прерывание, функция обработки которого не была определена - как следствие reset vector и контроллер вставал на месте. Ошибку исправил - устройство работает нормально.
У меня есть вопрос: По документации к MSP430x4xx следует, что SPI делает сдвиг (передачу) байта данных, начиная со старшего бита (MSB) и принимает подобным же образом. Можно ли организовать приём на SPI начиная с младшего бита (LSB) - (битреверсию)???????????
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|