Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSP430F2618 и SPI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
IBRO25
Здравствуйте товарищи!!! возникла проблемка с SPI (вроде ничего сложного в интерфейсе, но всё же)... написал код:
Код
#include  "msp430f2618.h"
#include <stdio.h>
#include <math.h>

unsigned char MST_Data,SLV_Data;

void main(void)
{
  volatile unsigned int i;

  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                    
  {  
    while(1);                              
                                          
  }    
  BCSCTL1 = CALBC1_1MHZ;                    
  DCOCTL = CALDCO_1MHZ;
  for(i=2100;i>0;i--);                    

  
  P3SEL = 0x3E;                            // порты и вторые ф-ции:SPI-B0 и UART
  P3DIR = 0x5B;                            // SPI-B0 & UART-A1 выбрано в соответствии с направлениями
  P3OUT = 0x31;                               // в соответствии

  UCB0CTL0 |= UCMSB+UCMST+UCSYNC;           // для ЦАП, по заднему и вниз, Mode_1  
  UCB0CTL1 |= UCSSEL_2;                     // SMCLK
  UCB0BR0 = 0x01;                           // /2
  UCB0BR1 = 0;                              //
  UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCB0RXIE;                        

  for(i=50;i>0;i--);                        

  MST_Data = 0x001;                        
  SLV_Data = 0x000;                      

  UCB0TXBUF = MST_Data;                    

  _BIS_SR(LPM0_bits + GIE);                


while(1)
{
  volatile unsigned int i;
  for (i=0xFFFF; i>0; i--);
  while (!(IFG2 & UCB0TXIFG));
  P3OUT &= -0x01;
  P3OUT |= 0x01;
  UCB0TXBUF = UCB0RXBUF;
}
}


вроде компилится, ошибок никаких... но к сожалению, данные не пересылает... пытаюсь разобраться... и дописать очистку мастерского буфера... подскажите, что не так и что я неправильно делаю? и... ещё вопросик: "если у меня приходят сигналы с двух различных источников в проц, как сделать флаги на эти сигналы на выход (чтобы понять, где первый сигнал, а где второй)?"

P.S. видел код по SPI для MSP430F149... но со своим кодом хотелось бы разобраться...

заранее благодарю за все советы и за всю полезную информацию...
rezident
Даю подсказку. Вы при инициализации модуля USCI разрешили прерывание от его приемника, но где у вас функция обработки прерывания от этого источника? Вы в теле main работаете с опросом флага готовности (правда флага передатчика), тогда зачем же разрешаете прерывание от приемника? SPI это такой интерфейс в котором передача идет одновременно с приемом. Поэтому часто бывает достаточно только одного флага/прерывания: или приемника, или передатчика.
Процедура инициализации модуля USART и USCI должна начинаться с установки бита SWRST или UCSWRST соответственно. Об этом написано во всех руководствах (User's Guide). Там же приведена последовательность команд инициализации модуля и даже с примерами. Но тем не менее, большинство начинающих игнорируют эту рекомендацию. Парадокс! laughing.gif
Что у вас используется в качестве ведомого устройства на SPI? Ему что, фреймовая синхронизация не нужна? И сигнала CS у него нету?
Ну и о возможной причине неработоспособности программы. Вы переводите МК в режим энергосбережения перед "суперциклом", выключая ядро. Как вы предполагаете дальнейшее выполнение программы, если ядро "спит", а какого-либо обработчика прерывания (в котором ядро можно было бы разбудить) у вас нету?
IBRO25
мда... нагородил огород... видимо, прочитал, но не осознал... а не могли бы вы кинуть код рабочего примера с инициализацией передачей байтов по SPI для моего микропроцессора? а то, я видимо что-то недопонял, пока читал про SPI и разбирал примеры Тексаса... буду очень признателен и благодарен...

конечно понимаю, что это нагло с моей стороны, просить код, но я первый раз сталкиваюсь с этим интерфейсом, 2 недели изучал его, но, видимо, так и не понял как написать под него рабочий код... ((
rezident
Судя по всему, вы свой код брали из этих примеров TI, так? Но при "творческой переработке" кода, вы зачем-то выкинули функцию обработки прерывания. Ну так дополните свою программу этой функцией! В примерах собственно в прерывании от приемника SPI и происходит прием/передача данных. Так что ваш "суперцикл" для передачи не нужен. Точнее нужен, но лишь для подготовки данных к передаче и обработке принятых данных. Также рекомендую вам пока НЕ использовать режимы энергосбережения до тех пор, пока вы полностью не разберетесь с настройкой и работой периферийных модулей.
SPI это вообще один из самых простых интерфейсов. Работа модуля USCI в режиме SPI представляют из себя по сути работу сдвигового регистра. Через последовательный выход данные передаются и одновременно через последовательный вход принимаются. Чтобы что-то принять, нужно что-то передать. Это первая особенность интерфейса SPI.
Вторая особенность SPI состоит в том, что это синхронный интерфейс. Если во время приема/передачи произошел сбой в тактировании, то вы не можете определить этот факт и уже не будете принимать корректные данные. Чтобы избежать таких неприятностей применяют фреймовую (кадровую) синхронизацию. Поток данных делится на отдельные фреймы (кадры), с помощью которых определяется начало и конец пакета данных. Для реализации фреймовой синхронизации применяют два способа: отдельный сигнал фреймовой синхронизации и временнАя фреймовая синхронизация. В большинстве устройств с интерфейсом SPI имеется отдельный сигнал типа CS, который запрещает/разрешает прием/передачу и при неактивном сигнале сбрасывает аппаратуру SPI. ВременнАя синхронизация используется гораздо реже. При этом способе начало/конец фрейма определяется по паузам в передаче потока данных. При возникновении паузы аппаратура SPI реинициализируется. Это менее надежный способ, чем отдельный сигнал синхронизации, но тем не менее он тоже применим. Применяется в случаях, когда требуется минимальное количество связей между устройствами или когда организуется режим один ведущий-несколько ведомых и нет возможности выделить для каждого ведомого свой отдельный сигнал фреймовой синхронизации.
В общем попробуйте модифицировать свою программу, внимательно читая User's Guide. Если же не понимаете работу прерываний, то задавайте конкретные вопросы.
IBRO25
да, брал оттуда... при "переработке" я выкинул часть кода, т.к. вылетала ошибка, связанная с количеством памяти (почитал в интернете, там написано было, что скорее всего я работаю не с тем микропроцессором (но я же смотрел код под свой!))... ((( по поводу User's Guide: перепрочитал... понял, что не понимаю, как правильно пользоваться регистрами и переменными в них... ((( принцип работы SPI понял...

спасибо за то, что пытаетесь помочь!
IBRO25
Доброго времени суток!! появился ещё параллельный вопрос: "#define X BITY - Привязывание указателя X к входу\выходу P1.Y", а как привязать указатель к выходу P2.Y?

просто у меня по схеме 2 кнопки повешены на p2.6 и p2.7... можно ли так объявить: #define Button1 P2CA6

хотя посмотрел msp430.h, а там есть только P2CA1-P2CA4...

мммм... понял... p2.6 и p2.7 определены битами P2SEL6 и P2SEL7... ТАК?

правильно написал обработчик нажатия на кнопки??

Код
#include "io430.h"

#define Button1 P2SEL6 //тут объявляем кнопку Button1 на вход p2.6
#define Button2 P2SEL7 //тут объявляем кнопку Button2 на вход p2.7

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
    if ((P2IN== Button1)&&(P2IN != Button2)) //если состояние кнопки 1 изменено тогда будет работать
    {
         Func1();
    }
    
    
        if ((P2IN == Button2)&&(P2IN != Button1)) //если состояние кнопки 2 изменено тогда будет работать
    {
         Func2();
    }

  return 0;
}


неправильно(((( блин...

нашёл кое-чё...

Код
void BUTTON()
{
      P2SEL = 0x00;                             // все - порты =0
      P2DIR = 0xBF;                             // все на вывод кроме 6 бита    
      P2OUT = 0xCC;                             // исходно:                    
}
IBRO25
код вроде компилится и ошибок не выдаёт (проверить пока нет возможности):
Код
#include "msp430f2618.h"

int main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  
  P2SEL = P2SEL & ~BIT6 & ~BIT7; //делаем P2.6, P2.7 на инпут

  
  if (!(P2IN&BIT6)&&(P2IN&BIT7))       //если кнопка 2.6 нажата
  {
  
  }
  
  if (!(P2IN&BIT7)&&(P2IN&BIT6))      //если кнопка 2.7 нажата
  {
  
  }
                
  return 0;
}
rezident
IBRO25, у вас ошибка. Регистры PxSEL определяют функцию пина, подключая к нему какой-нибудь периферийный модуль. Направление же работы пина (вход или выход) задается конфигурацией регистров PxDIR. См. внимательно раздел Digital I/O в User's Guide, а справку по определению конфигурации пинов с помощью PxSEL и PxDIR см. в конце datasheet конкретного кристалла. Там обычно приводится блок-схема выходного каскада для каждого пина и таблица для конфигурации.
Для вашего случая конфигурация должна быть задана так.
Код
P2SEL &= ~(BIT6 | BIT7); //P2.6 и P2.7 функционируют как пины GPIO
P2DIR &= ~(BIT6 | BIT7); //P2.6 и P2.7 как входы GPIO
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.