MSP430 Прием данных.

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

MSP430 Прием данных.

Сообщение TmYAG »

Здравствуйте, уважаемые форумчане!
Не могу разобраться как принимать посылку из нескольких байт. Код ниже.
И еще один вопрос по коду:
Спойлер

Код: Выделить всё

#include "msp430g2553.h"
#include "stdbool.h"
/*
 * main.c
 */

void initADC(void);
int tempOUT(void);
void initUART();
void UARTWriteString(char *str);
void UARTReadString();
unsigned char data;
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;//Останавливаем стоожевой таймер
    DCOCTL = CALDCO_1MHZ;    //Настраиваем систему основного тактирования на 1МГц
    BCSCTL1 = CALBC1_1MHZ;
    initADC();               //Инициализируем АЦП   
    initUART();              //Инициализируем UART
exit:
    UARTWriteString("Waiting for input!");// Ждем ввода
    while (!(IFG2&UCA0RXIFG));//Проверяем буфер приема
    data = UCA0RXBUF; //То, что пришло записываем в переменную
    if (data == 0xFF)
    {
    while(1)
   {
          __delay_cycles(100000);//Сюда нужно передавать задержку переданную с компа
          volatile int t; // Переменная уйдет в регистр, но мы ее увидим при отладке
          t = tempOUT();  //Возвращаем значение температуры
          char s[11];     // Для перевода int в строку нам потребуется массив char
          sprintf(s,"%d", t); //Переменная t выводится в буфер s
          char *ch = s;       // Массив в функцию передавать нельзя, но указатель на него можно ;)
          UARTWriteString(ch);//Пишем в порт
          UARTWriteString(" ");//Разделим значения между собой
          /**/
          __delay_cycles(100000);//...и сюда
   }
    }
    else {
      UARTWriteString("Wrong format");//Пишем в порт
      goto exit;
    }
}

void initADC()
{
   ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON; // Включаем АЦП
   ADC10CTL1=INCH_10+ ADC10DIV_3;//Канал с которого ведется преобразование 10(INCH_10)
                          //ADC10DIV_3- контролирует время разрешенное на преобразование
}

int tempOUT()
{
   int T = 0;
   int tmp = 0;
   ADC10CTL0 |= ENC + ADC10SC;     //Включаем преобразование когда ENC = 1
                          //Начинам преобразование, когда ADC10SC = 1
   while(ADC10CTL1 & ADC10BUSY);
   T = ADC10MEM;
   ADC10CTL0&=~ENC;
   tmp = (0.413 * T - 277.7 );
   return (int)tmp;
}

void initUART()
{
   P1SEL = BIT1 + BIT2 ;      // P1.1 = RXD, P1.2=TXD
   P1SEL2 = BIT1 + BIT2 ;      // P1.1 = RXD, P1.2=TXD
   UCA0CTL1 |= UCSWRST;        // Этот бит блокирует работу прерываний от UART и работу
                               // сдвигового регистра чтобы не мешать
                               // настройке (грубо говоря отключает UART).
   UCA0CTL1 |= UCSSEL_2;       // Наш UART будет работать от
                                // SMCLK (Sub-main clock), то есть от 1MHZ.
   UCA0BR0 = 104;              // Делитель частоты для SMCLK (1000000 / 9600).
   UCA0BR1 = 0x00;
   UCA0MCTL = UCBRS1 + UCBRS0;   // Модуляция UCBRSx = 3
   UCA0CTL1 &= ~UCSWRST;      // Включаем UART обратно.
   //IE2 |= UCA0RXIE;      //Разрешаем прерывания   
}
//Функция записи в порт
void UARTWriteString(char *str)
{
   for (int i = 0; str[i]; i++)
   {
      while (!(IFG2&UCA0TXIFG));
      UCA0TXBUF = str[i];
   }
}


У меня есть необходимость обработать ошибку ввода в прошивке. if(data == 0xFF)... то значения температуры засылаются в порт, иначе, вывести сообщение об ошибке и вернуться к ожиданию ввода. Знаю, что использование goto -моветон. Кроме того этот метод работает не совсем так как я задумал. После вывода сообщения об ошибке осуществляется переход на строку

Код: Выделить всё

UARTWriteString("Waiting for input!");
но при повторном вводе правильного значения код возвращается

Код: Выделить всё

UARTWriteString("Wrong format");
сюда и вместо температуры я вижу "Waiting for input! Wrong format".
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

При отладке выяснил, что data не та, которую я прописываю. почему-то неправильно читается(
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: MSP430 Прием данных.

Сообщение BCluster »

А причем тут несколько байт?
Что значит "не то что прописываю"? Скажем, послали 0xFF, и видим что там другое значение?
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

Это два разных вопроса. Так я могу отправить значения от 0x00 до 0xFF(0-255), а мне нужно отсылать 1000 и т.д.
Другой вопрос это в том что не проходит то значение, которое я посылаю. Я посылаю 0xFF а при отладке вижу data = 0x30С проблемой неправильности ввода я разобрался я передавал строку а не HEX.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: MSP430 Прием данных.

Сообщение BCluster »

TmYAG писал(а): Я посылаю 0xFF а при отладке вижу data = 0x30С проблемой неправильности ввода я разобрался я передавал строку а не HEX.

так уже правильно видите ? честно, нифига не понятно как вы пишете
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

Постараюсь писать понятнее) да вижу правильно. Ошибка была в том, что в настройках терминала было установлено не HEX значение а строка.
1. Как принимать несколько байт?
2. Как можно обойтись без goto в коде, который я написал.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: MSP430 Прием данных.

Сообщение BCluster »

Если не менять структуру программы то goto можно убрать так:

Код: Выделить всё

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;//Останавливаем стоожевой таймер
    DCOCTL = CALDCO_1MHZ;    //Настраиваем систему основного тактирования на 1МГц
    BCSCTL1 = CALBC1_1MHZ;
    initADC();               //Инициализируем АЦП   
    initUART();              //Инициализируем UART
while (1)
{
    UARTWriteString("Waiting for input!");// Ждем ввода
    while (!(IFG2&UCA0RXIFG));//Проверяем буфер приема
    data = UCA0RXBUF; //То, что пришло записываем в переменную
    if (data == 0xFF)
    {
    while(1)
   {
          __delay_cycles(100000);//Сюда нужно передавать задержку переданную с компа
          volatile int t; // Переменная уйдет в регистр, но мы ее увидим при отладке
          t = tempOUT();  //Возвращаем значение температуры
          char s[11];     // Для перевода int в строку нам потребуется массив char
          sprintf(s,"%d", t); //Переменная t выводится в буфер s
          char *ch = s;       // Массив в функцию передавать нельзя, но указатель на него можно ;)
          UARTWriteString(ch);//Пишем в порт
          UARTWriteString(" ");//Разделим значения между собой
          /**/
          __delay_cycles(100000);//...и сюда
   }
    }
    else {
      UARTWriteString("Wrong format");//Пишем в порт
      continue;
    }
}
}

Но я бы, наверное, вообще по другому построил программу. Но не суть.
Так и должно быть, что значение считывается один раз, а потом крутится в бесконечном цикле, и повторный ввод будет только после рестарта?

Несколько байт обычно принимают при помощи таймера, и/или прерывания по приему. А известно или нет, сколько байт принять надо?
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

А известно или нет, сколько байт принять надо?

Произвольное число.
Несколько байт обычно принимают при помощи таймера, и/или прерывания по приему.

А можно подробнее? Я посмотрел статьи на TI про отправку нескольких байт, там кто-то заикнулся про Timer A, но подробностей хочется.
Такой вариант, видимо не сработает

Код: Выделить всё

int i = 0;
unsigned char* data;
while (data[i] != "\n")
{
    while (!(IFG2&UCA0RXIFG));
    data[I] = UCA0RXBUF;
    i++;
}
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: MSP430 Прием данных.

Сообщение BCluster »

Такой точно нет

Код: Выделить всё


int i = 0;
unsigned char* data; // куда указывает этот указатель? в лес? :)
while (data[i] != "\n") // data[i] еще нету, т.е. не прочитан
{
    while (!(IFG2&UCA0RXIFG));
    data[I] = UCA0RXBUF; // i!=I
    i++;
}



А вот этот возможно будет :))) Если, конечно, признак конца строки передаваться будет

Код: Выделить всё

int i = 0;
unsigned char data[10]; //макс 10 тут, думаю разумные пределы определить можно... Если нет, то надо динамически выделять память
do
{
    while (!(IFG2&UCA0RXIFG));
    data[i] = UCA0RXBUF;   
}
while ( data[i++] != "\n" )
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

ну это всего навсего опечатка)))
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

так или иначе, все равно не получается. На следующей итерации код ждет новой посылки. И мк пфиг на то что я посылаю строку, принимает он все равно лишь первый байт
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: MSP430 Прием данных.

Сообщение BCluster »

while (!(IFG2&UCA0RXIFG));
в этой строке сидит постоянно или как?
SergKT
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Сб сен 28, 2013 09:22:38

Re: MSP430 Прием данных.

Сообщение SergKT »

В данном случае, не лишним был-бы вопрос о протоколе передачи данных.

Вопрос в том, можно ли изначально узнать сколько байт данных будет передаваться, либо существует ли признак окончания передачи пакета данных?
Если таких признаков нет, то отличается ли интервал времени между посылками байт в одном пакете и интервалом между пакетами данных?

Исходя из ответов, и нужно строить алгоритм приема.
Либо ждать признаки конца пакета данных.
Либо запускать таймер после приема каждого байта и уже он будет информировать, что вновь принятый байт входит в текущий пакет, или время ожидания истекло, а значит пакет принят полностью.
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

BCluster писал(а):
while (!(IFG2&UCA0RXIFG));
в этой строке сидит постоянно или как?

Да верно!
SergKT писал(а):В данном случае, не лишним был-бы вопрос о протоколе передачи данных.

Вопрос в том, можно ли изначально узнать сколько байт данных будет передаваться, либо существует ли признак окончания передачи пакета данных?
Если таких признаков нет, то отличается ли интервал времени между посылками байт в одном пакете и интервалом между пакетами данных?

Исходя из ответов, и нужно строить алгоритм приема.
Либо ждать признаки конца пакета данных.
Либо запускать таймер после приема каждого байта и уже он будет информировать, что вновь принятый байт входит в текущий пакет, или время ожидания истекло, а значит пакет принят полностью.

Передаю по UART (я новичок, поэтому особо много протоколов и не знаю)
Узнать сколько байт передается. Произвольное число. Известно, что передаваемые данные только числа, поскольку я передаю задержку для _delay(). Признак окончания передачи по идее должен быть, например "\0"
Проблема в другом. В качестве тестов я посылаю строку 1234 из COM-port toolkit. Так вот я использую код:
int i = 0;
unsigned char data[10]; //макс 10 тут, думаю разумные пределы определить можно... Если нет, то надо динамически выделять память
do
{
while (!(IFG2&UCA0RXIFG));
data[i] = UCA0RXBUF;
}
while ( data[i++] != '\0' )
И код циклится. А происходит это, когда первая итерация прошла и в data[0] записалась 1, на этапе второй итерации код словно ждет когда я пошлю новую строку, а не когда передастся 2 из передаваемой строки.
SergKT
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Сб сен 28, 2013 09:22:38

Re: MSP430 Прием данных.

Сообщение SergKT »

Вот давайте еще раз разберемся по пунктам и с формулировками.

1. Ваше устройство передаёт данные.
2. Другое Ваше устройство эти данные принимает и отображает ?
3. В указанном цикле передачи, условие окончания, это код 0 в буфере, но он не передается.
4. Принимающее устройство как определяет, что пакет данных закончился ?
Ждет код 0, или по тайм-ауту?

Если строка передается из ТолКит, условие окончания пакета скорее всего отсутствует, и принимающее устройство должно понять это по тайм-ауту.

В общем смысл такой. Нужно согласовать свойства пакета, в передающем и принимающем устройстве, иначе "кина не будет".
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: MSP430 Прием данных.

Сообщение TmYAG »

1. Мое устройство сначала принимает данные из внешнего интерфейса (написанного на Qt) а затем с заданной задержкой начинает их отправлять в тот же интерфейс.
2. Верно
3. Вот с этим я и не могу разобраться.
4. Я думал по символу конца строки. Но Вы говорите, что из терминала этот конец строки не отправляется. стало быть во избежании проблем лучше делать через тайм аут. Другое дело, что я не знаю, каким образом обрабатывать тайм аут. Только учусь и не приходилось разбираться.
По идее я могу протестировать это следующим образом. посылать строку 1234. а признаком окончания передачи сделать data[i] = '4';
я должен буду увидеть 1234.
Но повторюсь. При отладке возникает чувство, что принимается только 1-й байт.
SergKT
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Сб сен 28, 2013 09:22:38

Re: MSP430 Прием данных.

Сообщение SergKT »

Ну раз и отправляет и принимает инфу ваши устройства, всё значительно проще.
Я так понял, что передаются только цифры от 0 до 9.
Значит для синхронизации потока нужно всего-то добавить в выходную строку символ насала и символ конца данных.
Например отправлять не 1234 а =1234. (в конце точка).
Это избавит от нескольких проблем.
Во первых принимающий алгоритм даже при сбое синхронизации в потоке сможет всегда ждать символ "=", для того, чтобы начать прием данных.
Во вторых при приеме обычного символа "." (точка), алгоритм сможет надежно понять, что пакет закончился, и принятые данные нужно обработать.
При этом эти символы "=" и "." легко вставить в терминале, для проверки принимающего алгоритма, и корректно примутся терминалом при проверке передающего алгоритма.
Соответственно код "0" передавать не нужно.
Надеюсь не очень сложно сформулировал свою идею.
Удачи.
Ответить

Вернуться в «Разные вопросы по МК»