Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: UART на MSP430F2131
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Slash
Мне нужно реализовать UART на MSP430F2131. У этого МК нет аппаратного UART, а есть Timer UART с 3-мя Capture/Compare Registers.
Я пока развожу плату, поэтому мне пока нужно разобраться в функциях ног МК.

Расскажите, пожалуйста, на пальцах назначение выходов, предназначеных для ССRx.

Вот часть таблицы из даташита, оставил только непонятное:

P1.1/TA0 Timer_A, capture: CCI0A input, compare: Out0 output
P1.2/TA1 Timer_A, capture: CCI1A input, compare: Out1 output
P1.3/TA2 Timer_A, capture: CCI2A input, compare: Out2 output
P1.5/TA0 Timer_A, compare: Out0 output
P1.6/TA1 Timer_A, compare: Out1 output
P1.7/TA2 Timer_A, compare: Out2 output
P2.2TA0 Timer_A, capture: CCI0B input
P2.3/TA1 Timer_A, compare: Out1 output
P2.4/TA2 Timer_A, compare: Out2 output

В чем разница этих функций? В общем, ничего пока не понятно...

Спасибо.
Dog Pawlowa
Цитата(Slash @ Nov 20 2008, 17:46) *
В чем разница этих функций?

Разницы в функциях нет, они (одинаково названные) абсолютно идентичны.
Вы можете вместо обычного GPIO включить функцию на этот вывод.
Поэтому Вы должны выбрать вначале способы реализации функций прибора, потом определить, какие выводы будут работать в каких режимах, а потом разводить плату.
Будете действовать иначе - работа может оказаться впустую.
И вообще даташит почитать не мешает (если Вы схемотехник).
Если Вы только проектировщик печатной платы - стребуйте схему у схемотехника.
Если Вы и то, и другое, и программист вдобавок... Хм...
IgorKossak
Slash, выделил Ваш вопрос в отдельную тему.
Не следует влезать в чужую с разнородными вопросами только лишь по признаку "чайниковости".
rezident
Цитата(Slash @ Nov 20 2008, 18:46) *
Мне нужно реализовать UART на MSP430F2131. У этого МК нет аппаратного UART, а есть Timer UART с 3-мя Capture/Compare Registers.
slaa078a (Implementing a UART Function with Timer_A3) вы надеюсь уже вдоль и поперек изучили? wink.gif
Цитата(Slash @ Nov 20 2008, 18:46) *
В чем разница этих функций? В общем, ничего пока не понятно...
Все эти пины, могут работать как выходы PWM (в режиме работы таймера compare). Но не все как входы регистров захвата (режим capture). Те которые могут обозначены как capture: CCIxx input. Вот на это и обратите внимание. На вашем месте, я бы начал с реализации программы, а не с трассировки платы.
Slash
Цитата(rezident @ Nov 20 2008, 20:09) *
slaa078a (Implementing a UART Function with Timer_A3) вы надеюсь уже вдоль и поперек изучили? wink.gif

Спасибо!
Всего раз 5 прочел, видимо не доходит smile.gif Еще раз 10 прочту, если будут вопросы, задам.
Плата почти разведена, но пару дорожек переразвести неложно. Теперь да, буду писать программу.
rezident
Цитата(Slash @ Nov 20 2008, 22:56) *
Всего раз 5 прочел, видимо не доходит smile.gif Еще раз 10 прочту, если будут вопросы, задам.
Вот тут оно же, но по-русски. Или в Компэловском сборнике апликух читайте..
Slash
Спасибо всем за советы, продолжаю работу smile.gif Работаю с IAR 4.11B и MSP430f2131.

IAR дает несколько способов обращения к битам. Мне нужно присвоить битам TAMC регистра TACTL значение "3".

1 вариант:
Код
TACTL_bit.TAMC = 3;


Должен быть второй вариант, какой он? (По аналогии с BCSCTL1 = RSEL0 + RSEL1 + RSEL2;)
Ведь TAMC 2-х битовое поле.

Почему TAMC константа со значением 0х20, как с этим работать?

Вот фрагмент "io430x21x1.h" :
Код
__no_init volatile union
{
  unsigned short TACTL;  /* Timer A Control */
  
  struct
  {
    unsigned short TAIFG         : 1;  /* Timer A counter interrupt flag */
    unsigned short TAIE          : 1;  /* Timer A counter interrupt enable */
    unsigned short TACLR         : 1;  /* Timer A counter clear */
    unsigned short               : 1;
    unsigned short TAMC          : 2;  /* Timer A mode control 0 */
    unsigned short TAID          : 2;  /* Timer A clock input divider */
    unsigned short TASSEL        : 2;  /* Timer A clock source select */
    unsigned short               : 6;
  } TACTL_bit;  
} @ 0x0160;


enum {
  TAIFG               = 0x0001,
  TAIE                = 0x0002,
  TACLR               = 0x0004,
  TAMC                = 0x0020,
  TAID                = 0x0080,
  TASSEL              = 0x0200,
};
Сергей Борщ
Цитата(Slash @ Nov 24 2008, 16:02) *
1 вариант:
Код
TACTL_bit.TAMC = 3;
Это выливается в чтение, наложение маски по "И", наложение маски по "ИЛИ", запись. И так для каждого поля, которое вы хотите прописать. Если в регистре три поля, и вам нужно прописать все три, то вместо записи одной константы получите минимум 12 команд.
Цитата(Slash @ Nov 24 2008, 16:02) *
Должен быть второй вариант, какой он? (По аналогии с BCSCTL1 = RSEL0 + RSEL1 + RSEL2;)
Ведь TAMC 2-х битовое поле.
Код
TACTL = (0*TAIFG) | (1*TAIE) | (1*TACLR) | (2*TAMC) и т.д.

Цитата(Slash @ Nov 24 2008, 16:02) *
Почему TAMC константа со значением 0х20, как с этим работать?
Эта константа описывает положение младшего бита в поле. Умножаете на значение поля - получаете значение нужных битов.
rezident
Зачем обязательно придумывать что-то свое? Используйте стандартные и рекомендуемые производителем TI символьные обозначения регистров и битов. Найти их можно в хедере конкретного кристалла. Для вашего случая это msp430x21x1.h. В аттачменте его содержимое из среды IAR EW430 4.11B. В частности альтернативные названия битов и групп битов таймера А выглядят вот так
CODE
/* Alternate register names */
#define CCTL0 TACCTL0 /* Timer A Capture/Compare Control 0 */
#define CCTL1 TACCTL1 /* Timer A Capture/Compare Control 1 */
#define CCTL2 TACCTL2 /* Timer A Capture/Compare Control 2 */
#define CCR0 TACCR0 /* Timer A Capture/Compare 0 */
#define CCR1 TACCR1 /* Timer A Capture/Compare 1 */
#define CCR2 TACCR2 /* Timer A Capture/Compare 2 */
#define CCTL0_ TACCTL0_ /* Timer A Capture/Compare Control 0 */
#define CCTL1_ TACCTL1_ /* Timer A Capture/Compare Control 1 */
#define CCTL2_ TACCTL2_ /* Timer A Capture/Compare Control 2 */
#define CCR0_ TACCR0_ /* Timer A Capture/Compare 0 */
#define CCR1_ TACCR1_ /* Timer A Capture/Compare 1 */
#define CCR2_ TACCR2_ /* Timer A Capture/Compare 2 */

#define TASSEL1 (0x0200) /* Timer A clock source select 0 */
#define TASSEL0 (0x0100) /* Timer A clock source select 1 */
#define ID1 (0x0080) /* Timer A clock input divider 1 */
#define ID0 (0x0040) /* Timer A clock input divider 0 */
#define MC1 (0x0020) /* Timer A mode control 1 */
#define MC0 (0x0010) /* Timer A mode control 0 */
#define TACLR (0x0004) /* Timer A counter clear */
#define TAIE (0x0002) /* Timer A counter interrupt enable */
#define TAIFG (0x0001) /* Timer A counter interrupt flag */

#define MC_0 (0*0x10u) /* Timer A mode control: 0 - Stop */
#define MC_1 (1*0x10u) /* Timer A mode control: 1 - Up to CCR0 */
#define MC_2 (2*0x10u) /* Timer A mode control: 2 - Continous up */
#define MC_3 (3*0x10u) /* Timer A mode control: 3 - Up/Down */
#define ID_0 (0*0x40u) /* Timer A input divider: 0 - /1 */
#define ID_1 (1*0x40u) /* Timer A input divider: 1 - /2 */
#define ID_2 (2*0x40u) /* Timer A input divider: 2 - /4 */
#define ID_3 (3*0x40u) /* Timer A input divider: 3 - /8 */
#define TASSEL_0 (0*0x100u) /* Timer A clock source select: 0 - TACLK */
#define TASSEL_1 (1*0x100u) /* Timer A clock source select: 1 - ACLK */
#define TASSEL_2 (2*0x100u) /* Timer A clock source select: 2 - SMCLK */
#define TASSEL_3 (3*0x100u) /* Timer A clock source select: 3 - INCLK */

#define CM1 (0x8000) /* Capture mode 1 */
#define CM0 (0x4000) /* Capture mode 0 */
#define CCIS1 (0x2000) /* Capture input select 1 */
#define CCIS0 (0x1000) /* Capture input select 0 */
#define SCS (0x0800) /* Capture sychronize */
#define SCCI (0x0400) /* Latched capture signal (read) */
#define CAP (0x0100) /* Capture mode: 1 /Compare mode : 0 */
#define OUTMOD2 (0x0080) /* Output mode 2 */
#define OUTMOD1 (0x0040) /* Output mode 1 */
#define OUTMOD0 (0x0020) /* Output mode 0 */
#define CCIE (0x0010) /* Capture/compare interrupt enable */
#define CCI (0x0008) /* Capture input signal (read) */
#define OUT (0x0004) /* PWM Output signal if output mode 0 */
#define COV (0x0002) /* Capture/compare overflow flag */
#define CCIFG (0x0001) /* Capture/compare interrupt flag */

#define OUTMOD_0 (0*0x20u) /* PWM output mode: 0 - output only */
#define OUTMOD_1 (1*0x20u) /* PWM output mode: 1 - set */
#define OUTMOD_2 (2*0x20u) /* PWM output mode: 2 - PWM toggle/reset */
#define OUTMOD_3 (3*0x20u) /* PWM output mode: 3 - PWM set/reset */
#define OUTMOD_4 (4*0x20u) /* PWM output mode: 4 - toggle */
#define OUTMOD_5 (5*0x20u) /* PWM output mode: 5 - Reset */
#define OUTMOD_6 (6*0x20u) /* PWM output mode: 6 - PWM toggle/set */
#define OUTMOD_7 (7*0x20u) /* PWM output mode: 7 - PWM reset/set */
#define CCIS_0 (0*0x1000u) /* Capture input select: 0 - CCIxA */
#define CCIS_1 (1*0x1000u) /* Capture input select: 1 - CCIxB */
#define CCIS_2 (2*0x1000u) /* Capture input select: 2 - GND */
#define CCIS_3 (3*0x1000u) /* Capture input select: 3 - Vcc */
#define CM_0 (0*0x4000u) /* Capture mode: 0 - disabled */
#define CM_1 (1*0x4000u) /* Capture mode: 1 - pos. edge */
#define CM_2 (2*0x4000u) /* Capture mode: 1 - neg. edge */
#define CM_3 (3*0x4000u) /* Capture mode: 1 - both edges */

Для вашего же случая (вы видимо хотите запустить таймер в режиме Up/Down?) строка будет выглядеть таким образом
Код
TACTL|=MC_3;

что эквивалентно
Код
TACTL|=MC1|MC0;

или
Код
TACTL|=0x30;
Slash
Сергей Борщ, rezident, спасибо, стало понятнее.

Вот только каким все-таки хедером пользоваться io430x21x1.h или msp430x21x1.h?


Код

TACTL_bit.TAMC = 3; // не проходит с msp430x21x1.h
TACTL|=MC1|MC0;  // не проходить с io430x21x1.h
rezident
Цитата(Slash @ Nov 25 2008, 13:19) *
Вот только каким все-таки хедером пользоваться io430x21x1.h или msp430x21x1.h?
Первые (io430x....h) это поделие фирмы IAR System, а вторые (msp430x....h) это стандартные заголовочные файлы фирмы TI. Об этом в заголовках файлов написано.
Из io430x21x1.h
Цитата
/********************************************************************
*
* Standard register and bit definitions for the Texas Instruments
* MSP430 microcontroller.
*
* This file supports assembler and C/EC++ development for
* MSP430x21x1 devices.
*
* Copyright 1996-2004 IAR Systems. All rights reserved.
*
* $Revision: 4349 $
*
********************************************************************/

Из msp430x21x1.h
Цитата
/********************************************************************
*
* Standard register and bit definitions for the Texas Instruments
* MSP430 microcontroller.
*
* This file supports assembler and C development for
* MSP430x21x1 devices.
*
* Texas Instruments, Version 1.2
*
* Rev. 1.0, Setup
*
* Rev. 1.1, Removed unused def of TASSEL2
* Rev. 1.2, added definitions for Interrupt Vectors xxIV
*
********************************************************************/

Кроме того, первый пригоден для использования с IAR С и C++, а TI-ский для "чистого" C. Поскольку я C++ для программирования MSP430 не применяю, то поэтому пользуюсь стандартным хедером от TI.
Slash
Подскажите, пожалуйста, в чем может быть ошибка?
Отлаживаю устройство через JTAG при внешнем питании - все нормально. Как только пытаюсь тоже самое сделать при питании от самого JTAG - ничего не получается, IAR пишет "Initializing Hardware" и выводит ошибку. Причем тестером вижу - питание подается.
rezident
Slash, вы наверное считаете, что телепатические способности требуют постоянной тренировки? wink.gif
Какой именно FET и какая схема подключения у вас?
Slash
smile.gif smile.gif
Отладчик MSP-FET430UIF, схему приложил. Может еще что-то забыл?
rezident
Цитата(Slash @ Dec 25 2008, 11:57) *
Отладчик MSP-FET430UIF, схему приложил. Может еще что-то забыл?
Угу. Забыли. Вы нарисовали какой-то свой собственный 8-и контактный разъем JTAG. А у MSP-FET430UIF вообще-то 14-и пиновый разъем. И нет сигнала ни с обозначением +3.3V, ни VPRG. Зато есть VCC_IN (VCC_SENSE, VCC_TARGET) - pin4, вход FET и VCC_OUT (VCC_TOOL, VCC_EXT) - pin 2, выход FET. Если вы питаете TRAGET-систему от собственного питания, то питание MSP430 (+3.3V в вашем случае) должны подключать в пину 4 (VCC_IN). Если же вы хотите запитать TARGET от MSP-FET, то должны перекоммутировать его цепь питания (+3.3V у вас) на пин 2 разъема FET (VCC_OUT). Вы такую операцию делаете или забыли?
Slash
Цитата(rezident @ Dec 25 2008, 16:14) *
Вы такую операцию делаете или забыли?

Да, я такую операцию делаю. У меня два переходника со стандартного 14 контактного разъема на мой 8 контактный с обеими вариантами подачи +3,3В от FET-а и в FET.
rezident
Тогда скорее всего проблема с величиной тока нагрузки. Кроме MSP430 что-то еще подключено к цепи +3,3В?
Slash
Еще подключены:
ADUM5401
ADM3312
HEF4051 - 3шт.

А какая нагрузка допустима? Думал, что где-то до 100мА можно нагружать FET.
rezident
Цитата(Slash @ Dec 26 2008, 15:21) *
А какая нагрузка допустима? Думал, что где-то до 100мА можно нагружать FET.
Поскольку MSP-FET430UIF питается от USB-порта, а в качестве стабилизатора напряжения питания TARGET применяется TPS76601, то судя по схемотехнике, теоретически - 200мА. В реальности же более, чем на 50мА я бы не рассчитывал. Потому, что согласно спецификации USB2.0 USB-device до инициализации имеет право потреблять не более 100мА. Но TUSB3410 вроде не умеет "требовать" дополнительное питание после инициализации. Так что эти 100мА нужно распределять и на питание самого MSP-FET430UIF и на питание TARGET-системы.
Slash
Ясно, спасибо.
Пока у меня не прошел период детских болезней, многие глюки сами рассасываются через некоторое время smile.gif Может и это пройдет.
Slash
Здравствуйте!

Вопрос больше по принципам программирования для микроконтроллеров.

К примеру, задача получить по UART число, сделать его двоично-десятичное преобразование и вывести на ЖК индикатор.

Как лучше (с точки зрения "правильности" программирования):

1) Объявить глобальную структуру, все функции становятся void Function (void) { }, в обработчике прерывания можно менять содержимое структуры.

2) Объявить локальную структуру в main, в функции передавать указатели на структуру. Вот, к примеру, понятен ли такой код с указателями?

Код
struct b
{
    unsigned int number;           // число
    unsigned int bdcNumber[10];    // число, в двоично-десятичном представлении
    unsigned char rIdx;            // индекс чтения буфера
    unsigned char cntr;            // счетчик числа элементов в буфере
};

struct b buff, *pbuff = &buff;

        
void BDC (struct b *k)
{
    if (k->number < 9)
    {
        k->cntr = 0;
        k->bdcNumber[k->cntr] = k->number;  
    }
    else
    {
        for (k->cntr = 0; k->number > 9; (k->cntr)++)
        {
            k->bdcNumber[k->cntr] = k->number % 10;
            k->number /= 10;
        }
        k->bdcNumber[k->cntr] = k->number;
    }
}


Меня смущают такие конструкции
Код
k->bdcNumber[k->cntr] = k->number % 10;
Это нормально?

До каких размеров программ разумно пользоваться глобальными переменными? А ведь есть контроллеры с 64к флеша.
chert_kol
Меня смущают такие конструкции
Код
k->bdcNumber[k->cntr] = k->number % 10;
Это нормально?

До каких размеров программ разумно пользоваться глобальными переменными? А ведь есть контроллеры с 64к флеша.
[/quote]


Поступить можно просто-посмотреть как это выглядить в ассемблере...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.