Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

lix писал(а):

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

x=0x24;
PORTB &= 0x80;
PORTB = x & 0x80;

Правильно написать

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

x=0x7f;
PORTB |= нужные_данные & x;


иначе сначала при
PORTB &= 0x80;
остается старший бит, если установлен
а потом устанавливаются по маске 00100100 биты 2ой и 5й.
ведь 0x24=00100100

Обновление:И то даже не устанавливаются, там же в порту нули останется просто старший бит, если был установлен.
Последний раз редактировалось vitalik_1984 Вс сен 04, 2011 20:39:48, всего редактировалось 2 раза.
В поисках истины человек развивается.
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Re: Вопросы по С/С++ (СИ)

Сообщение lix »

ога. ошибся.
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: Вопросы по С/С++ (СИ)

Сообщение alexey6522 »

Помогите разобраться :( У меня есть программа написанная на C++ builder которая отправляет строку на COM порт. С ее помощью я на порт посылаю один символ, скажем это будет 1, в протеусе при симуляции он принимается нормально как HEX число 31, либо DEC это уже 49 в зависимости от заданных параметров

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

itoa(что, куда, кодировка);

НО ЕСЛИ Я ОТПРАВЛЯЮ СТРОКУ с компа '1234', получается сумбур в виде, для HEX 4915338243 и для DEC кодировки 319926f3, самое смешное что первый символ соответствует первому переданному символу всегда!!! Что делать?
А вообще должно получиться что-то типа 31323334 или 49505152
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

Из Вашего сообщения неясно, что принимает неправильно .
Проект на протеусе с виртуальным ком портом ? Или живое железо ?
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: Вопросы по С/С++ (СИ)

Сообщение alexey6522 »

С компа передается нормально, виртуальный порт тоже работает нормально, так как конектюсь своей прогой к терминалу принимается и передается нормально, а вот на мое устройство в протеусе принимается плохо если отправляю строку, а если просто один символ то все нормально, видимо при передачи или при приеме строка состоящая более 1 байта кодируется, а раскодировать не могу.
Пример: отправил я 1234, а получил 319926f3, может так и должно быть, но как мне эту строку расшифровать?
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

ничего не нужно расшифровывать - так и идет. Проверьте на совпадение скоростей, ошибку уарта при вычислении скорости для заданной частоты кварца, проверьте, 1 бит стоповый у Вас или полтора - 2, сделайте паузу при выдаче на ком порт, там на миллисекунду остановите поток после выдачи очередного байта - возможно, Вы что-то длинное делаете в самом прерывании и оно не успевает раздуплиться, наконец, сделайте контроль ошибок в самом проекте на мк.
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: Вопросы по С/С++ (СИ)

Сообщение alexey6522 »

Да, дело было в стоповом бите!! Спасибо :)
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: Вопросы по С/С++ (СИ)

Сообщение alexey6522 »

Вот установил я глобальное прерывание sli() если есть байты на прием, то основная программа останавливается и выполняется подпрограмма. Мне нужно все полученные байты занести в массив, а потом с помощью функции atoi преобразовать в long
Пример:

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

char USART_Receive(void)
{
  while ( !(UCSRA & (1<<RXC)) );
  return UDR;
//----------
ISR(USART_RXC_vect)
{
  signed char s=0;
  s=USART_Receive();
}

int main(void)
{
sei();//устанавливаем бит глобального разрешения прерываний
while(1)
{
какая-то программа, выполн. до прерывания, а потом опять продолжаем
....
}
}
}
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Re: Вопросы по С/С++ (СИ)

Сообщение BerZerK-ku »

alexey6522 писал(а):Вот установил я глобальное прерывание sli() если есть байты на прием, то основная программа останавливается и выполняется подпрограмма. Мне нужно все полученные байты занести в массив, а потом с помощью функции atoi преобразовать в long


Можно сделать так:

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

volatile char cRx = 0;
volatile char cnt = 0;
volatile char cMas[20];
long lNumber;

ISR(USART_RXC_vect)
{
  cMas[cnt] = UDR;
  if (cMas[cnt] = 0x00) cRx = 1;
  cnt++;
}

int main(void)
{
/* Настройка периферии */
sei();//устанавливаем бит глобального разрешения прерываний
while(1)
{
  if (cRx)
  {
    lNumber = atol(cMas);
    cnt = 0;
    cRx = 0;
  }
какая-то программа, выполн. до прерывания, а потом опять продолжаем
....
}
}
Аватара пользователя
Hispanus
Грызет канифоль
Сообщения: 262
Зарегистрирован: Сб мар 26, 2011 14:17:14
Откуда: Оренбург

Re: Вопросы по С/С++ (СИ)

Сообщение Hispanus »

Не получается инициализировать интерфейс SPI в PCWHD (компилятор CSS PIC) для pic 16f628a - не подскажите, как назначить его ножкам соответсвующий режим работы и почему у меня не работают функции setup_spi, write_spi, read_spi..вроде компилятор их поддерживает, а они не определяются...может быть есть альтернативные варианты? :)
У радио нет будущего. Летательные аппараты тяжелее воздуха невозможны. Скоро выяснится, что рентгеновские лучи - мистификация.

[i]Лорд Кельвин, физик, 1899 г.[/i]
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

BerZerK-ku, так, собственно, делать нежелательно.
1. Представьте, что Вы зацепили половину пакета - в этом случае программа навеки собьется - она спокойно будет брать вторую половину из следующего пакета и так далее.
2.Нужно обязательно обрабатывать ошибки приема - пропуск стопового бита, переполнение буфера.

Я здесь уже советовал делать синхронизацию начала пакета по времени - если в течении некоторого времени нет прерывания по приему, таймер сбрасывает счетчик начала пакета в 0. Т.е. мы зацепили полпакета, сбросили таймер при приеме очередного байта, дальше пауза между пакетами - таймер сбрасывает счетчик в 0 и принятая информация - полпакета - отбрасывается, потому что счетчик не досчитал до 4 или сколько там байт. Следующий пакет приходит правильный.
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Re: Вопросы по С/С++ (СИ)

Сообщение BerZerK-ku »

urry писал(а):1. Представьте, что Вы зацепили половину пакета - в этом случае программа навеки собьется - она спокойно будет брать вторую половину из следующего пакета и так далее.
2.Нужно обязательно обрабатывать ошибки приема - пропуск стопового бита, переполнение буфера.

1. Повнимательнее посмотрите программу и вспомните что такое строка.
2. Согласен, без проверок не обойтись. Но тогда еще надо добавить контрольную сумму, чтобы увеличить уверенность в правильно принятой посылке. И простейший пример из нескольких строк превратится в кучу функций.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение urry »

:)
1.неубедительно, потому что Вы не проводите контроль за заполнением массива - и, если опять- же захватите первых полпакета, скажем, с размером полного пакета 16 байт, куда он будет писать ? Правильно, куда угодно после 20 байт массива.
2. Я как бы против "простейших примеров" - лучше выкладывать полный код (кучу функций), пусть разбираются.
По крайней мере, стараюсь так делать. А то молодежь решит, что обработка исключений - это лишнее.
rus-us
Открыл глаза
Сообщения: 60
Зарегистрирован: Сб сен 03, 2011 20:46:59

Re: Вопросы по С/С++ (СИ)

Сообщение rus-us »

Подскажите, пожалуйста, новичку по CVAVR + C.

Допустим, имеем такой код:

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

void make1(void) {
...
// 5 секунд
}

void make2(void) {
...

}

while (0) {
          make1();
          make2();
    };

Получается, в данном случае, основной цикл останавливается, пока не выполнится функция make1()?
Возможно ли в АВР + Си запускать какой то код в фоне, или в отдельном потоке?

Спасибо!
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

rus-us писал(а):Возможно ли в АВР + Си запускать какой то код в фоне, или в отдельном потоке?
да, возможно. в фоне - по прерываниям, например, от таймера. в виде отдельного "потока" - если применять одну из доступных RTOS или "почти RTOS"
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

rus-us писал(а):Получается, в данном случае, основной цикл останавливается, пока не выполнится функция make1()?

Спасибо!

если перед make1() сделать запись sei(); то возможно.
Ну конечно же прерывания от таймера и их обработка тоже нужны.
В поисках истины человек развивается.
rus-us
Открыл глаза
Сообщения: 60
Зарегистрирован: Сб сен 03, 2011 20:46:59

Re: Вопросы по С/С++ (СИ)

Сообщение rus-us »

Мастер Ломастер писал(а):да, возможно. в фоне - по прерываниям, например, от таймера. в виде отдельного "потока" - если применять одну из доступных RTOS или "почти RTOS"

Спасибо!

RTOS - понятно.

Насчет прерываний.
Есть какие-то ограничения/рекомендации на код в прерываниях?

Допустим, нужно проверять состояние ног МК не реже 1 сек.
В основном цикле получается минимум 5 сек.

А вот такой вариант программы допускается?

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

прерывание по времени(1секунда){
       проверяем состояние ноги1;
       проверяем состояние ноги2;
       .....
       проверяем состояние ногиN;
       
       // на сработавшую ногу ставим флаг
       // который обрабатываем в основном цикле.
       
}


void make1(void) {
...
// 5 секунд
}


while (0) {
          make1();

          еще какие-то действия;

    };
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

rus-us писал(а):А вот такой вариант программы допускается?
допускаться-то допускается, однако пока вы там 5 секунд что-то будете делать, флаги, которые вы выставили в прерывании кто будет анализировать? если задержка в реакции на эти флаги допустима - все нормально. но по-хорошему либо make1() надо делать по кусочкам в основном цикле, либо внутри нее делать анализ флагов время от времени... есть и другие варианты :)
битва с дураками проиграна, победители торжествуют. слава победителям!
rus-us
Открыл глаза
Сообщения: 60
Зарегистрирован: Сб сен 03, 2011 20:46:59

Re: Вопросы по С/С++ (СИ)

Сообщение rus-us »

Мастер Ломастер писал(а):допускаться-то допускается, однако пока вы там 5 секунд что-то будете делать, флаги, которые вы выставили в прерывании кто будет анализировать? если задержка в реакции на эти флаги допустима - все нормально. но по-хорошему либо make1() надо делать по кусочкам в основном цикле, либо внутри нее делать анализ флагов время от времени... есть и другие варианты :)


Мне главное не упустить изменения на ногах. Анализ флагов можно будет оптимизировать, с этим проблем не будет :)

П.С. какие другие варианты? :)
Аватара пользователя
Hispanus
Грызет канифоль
Сообщения: 262
Зарегистрирован: Сб мар 26, 2011 14:17:14
Откуда: Оренбург

Re: Вопросы по С/С++ (СИ)

Сообщение Hispanus »

Есть ли возможность программной реализации spi в мк, в котором он аппаратно не реализован (pic16f628a). Если есть, как будет выглядеть инициализация его выводов?...компилятор pic c compile..перелопатил весь интернет и ничего не нашёл.
У радио нет будущего. Летательные аппараты тяжелее воздуха невозможны. Скоро выяснится, что рентгеновские лучи - мистификация.

[i]Лорд Кельвин, физик, 1899 г.[/i]
Ответить

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