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

 
 
> MSP430F2132. И снова UART, Прошу помощи новичку в MSP430
Зураб
сообщение Aug 11 2010, 15:35
Сообщение #1





Группа: Участник
Сообщений: 10
Регистрация: 11-11-07
Пользователь №: 32 244



Доброго времени суток, уважаемые коллеги!
Волею судеб, так сказать, перешёл от AVR и 51-х к MSP430 и вот уже три дня бьюсь с UART на MSP430F2132. Почитал форум, использовал примеры, но всё напрасно. Короче, помогите. Итак: пишу программу в ИАР 5.10.1, запускаю в Протеусе 7.7, пробовал и в железе. Частота кварца 7372800Hz, хочу получить битрейд 9600. Вот код:
Код
#include  "msp430x21x2.h"

#define RX_BUFFER_SIZE 24
unsigned char rx_buffer[RX_BUFFER_SIZE];

unsigned char rx_wr_index=0,rx_rd_index=0;
volatile unsigned char rx_counter=0;
unsigned char rx_buffer_overflow=0;
unsigned char i, b, command, ks, valid, addr[2], dat[16];
unsigned char *pdat = dat;

void pins_init(void){
  P1DIR=0xFF;
  P1OUT=0x11;
}

void osc_init(void){
  BCSCTL1 |= XTS;                           // ACLK = LFXT1 = HF XTAL
  BCSCTL3 |= LFXT1S1;                       // 3 – 16MHz crystal or resonator
  do
  {
    IFG1 &= ~OFIFG;                         // Clear OSCFault flag
    for (i = 0xFF; i > 0; i--);             // Time for flag to set
  }
  while (IFG1 & OFIFG);                     // OSCFault flag still set?
  BCSCTL2 |= SELM_3 + SELS;                 // MCLK = SMCLK = LFXT1 (safe)  
}

void uart_init(void){
  P3DIR |= BIT4;
  P3SEL = 0x30;
  UCA0CTL1 |= UCSSEL_3;                     // SMCLK
  //UCA0CTL0 = UCMSB;
  UCA0BR0 = 0x00;                           // 7372800Hz/9600 = 0x0300
  UCA0BR1 = 0x03;
  UCA0MCTL = 0;                             // Modulation UCBRSx = 0
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;  
}  

unsigned char get(void)
{
  unsigned char data;
  //wdt_reset();
  while(rx_counter==0){};
  data=rx_buffer[rx_rd_index];
  if(++rx_rd_index == RX_BUFFER_SIZE){
    rx_rd_index=0;
  }    
  __bic_SR_register(GIE);
  --rx_counter;
  __bis_SR_register(GIE);
  return data;
}

void put(unsigned char data){
    while (!(IFG2 & UCA0TXIFG));
    UCA0TXBUF = data;
}

void put0(unsigned char num){
    for(i=0;i<num;i++)put(0);
}

unsigned char receivedata(void){
    command=get(); //приняли команду 1 байт
    // принимаем адрес 2 байта
    for(i=0;i<2;i++){      
        addr[i]=get();
    }          
    //вычисляем контрольную сумму и ...
    b=0x55^command^addr[0]^addr[1];
    // ... одновременно принимаем данные 16 байт
    for(i=0;i<16;i++){
        dat[i]=get();
        b=b^dat[i];
    }
    ks=get();//приняли контрольную сумму
    //далее проверка контрольной суммы
    if(b!=ks){
    // контрольная сумма некорректна
        put(0x55);
        put(0x41);
        put(0x01);
        put0(17);
        put(0x15);
    return 1;
    }else return 0;        
}

void main(void){
  WDTCTL = WDTPW + WDTHOLD;
  pins_init();
  osc_init();
  uart_init();
  __bis_SR_register(GIE);

  while(1){
    b=get();
    if(b==0x55){ //нашли метку во входной информации, далее принимаем все 20 байтов
      receivedata();
      //основной процесс обработки и выполнения команд
      if(command==0x10){
      //case 0x10:
        // проверяем валидность ключевой комбинации
        valid=1;
        if(addr[0]!=0x12)valid=0;
    if(addr[1]!=0x34)valid=0;
        if(valid){
      put(0x55);
      put(0x41);
      put(0x02);
      put0(17);
      put(0x16);          
        }else{
      put(0x55);
      put(0x41);
      put(0x03);
      put0(17);
      put(0x17);          
        }  
      }
    }
  }
}  



// USCI A0/B0 Receive ISR
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  if(!(UCA0STAT & UCRXERR))
     {
      rx_buffer[rx_wr_index]=UCA0RXBUF;
      if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
      if (++rx_counter == RX_BUFFER_SIZE)
        {
          rx_counter=0;
          rx_buffer_overflow=1;
        }
     }
}

Кидаю по ком-порту последовательность 55.10.12.34.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.63, получаю через раз C5. Почему так? Что не правильно? В протеусе все частоты (MCLK, SMCLK, ACLK выставил равными кварцевой частоте).
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Зураб
сообщение Aug 12 2010, 09:42
Сообщение #2





Группа: Участник
Сообщений: 10
Регистрация: 11-11-07
Пользователь №: 32 244



Спасибо за быстрый ответ!
Цитата
Как именно вы проверяете работу UART?

К сожалению, дебаггера пока нет. Пытаюсь сначала симулировать в Протеусе, затем с помощь BSL загружаю в железо. Сейчас убедился, что Протеус и железо ведут себя по разному. Видимо из-за Simulation is not running in real time... Думаю теперь тестировать только в железе.
Сейчас пытаюсь разобраться с DCO. Мозги кипят.
Цитата
Надежнее тактировать MCLK от DCO

То есть можно оставить MCLK всегда тактироваться от DCO? А как же стабильность частоты?
Цитата
после сброса или включения питания MCLK тактируется от DCO

Значит DCO по умолчанию настроен на какую-то частоту? На какую? Если источником синхросигнала для UART выбрать кварц, а MCLK оставить как есть от DCO будет ли моя программа работать (я насчёт синхронизации процессора и UART)? В железе не работает.
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 12 2010, 16:20
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Зураб @ Aug 12 2010, 15:42) *
То есть можно оставить MCLK всегда тактироваться от DCO?
Да, можно. Я считаю, что не просто можно, а даже нужно! smile.gif
Цитата(Зураб @ Aug 12 2010, 15:42) *
А как же стабильность частоты?
А что там со стабильностью DCO? Вроде не хуже 1% во всем рабочем температурном диапазоне при условии стабильности питания. И почему вас волнует стабильность частоты тактирования ядра микроконтроллера? Где вы еще используете MCLK? Для USCI используется SMCLK или ACLK, которые как раз лучше от кварцевого генератора затактировать. Аналогично с таймерами, если вы хотите отсчитывать временные интервалы.
Цитата(Зураб @ Aug 12 2010, 15:42) *
Значит DCO по умолчанию настроен на какую-то частоту? На какую?
Около 1МГц. Это в даташите указано.
Цитата(Зураб @ Aug 12 2010, 15:42) *
Если источником синхросигнала для UART выбрать кварц, а MCLK оставить как есть от DCO будет ли моя программа работать (я насчёт синхронизации процессора и UART)? В железе не работает.
Источником тактового сигнала для UART может выбираться внешний сигнал, поступающий на пин UC0CLK, или внутренние тактовые сигналы SMCLK или ACLK, которые в свою очередь могут тактироваться от DCO или от кварцевого генератора (LFXT или XT2, второго нет в вашем кристалле) или от VLO. Программу выполняет ядро процессора, которое тактируется только от MCLK. UART работает сам по себе, вне зависимости от работы или неработы (спячки) ядра.
Вам видимо нужно более тщательно разобраться с устройством и функционированием Basic Clock Module в MSP430.
Go to the top of the page
 
+Quote Post



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

 


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


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