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

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

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

Сообщение alexey6522 »

Мастер Ломастер простите за мое не знание в теории, не знал что для вас столь важно название функции во множественном числе или же в ед. Я уже давно определился что я мальчик и хочу работать с числом, просто пример попался для передачи строки.
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

Тут такая функция была: itoa(int) - преобразовывает число в строку.
Изображение
/dev/urandom - гигабайты информации.

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

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

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

alexey6522 писал(а):не знал что для вас столь важно название функции во множественном числе или же в ед. Я уже давно определился что я мальчик и хочу работать с числом, просто пример попался для передачи строки.
это важно для вас, а не для меня. программа должна быть написана понятно, но это лирика. ваша функция не может выводить числа, она может выводить только строки. поэтому для вывода ЧИСЕЛ вам надо все менять. вот пример кода (набросок), попробуйте понять разницу между единственным и множественным числом:

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

void send_byte(char byte){
   while((UCSRA&(1<<UDRE)) == 0); // Wait if a byte is being transmitted
   UDR = byte;
}

void send_bytes(const char *data){
   while(*data)
      send_byte(*data++);
}

void send_long(long *datalong){
   char *ptr = datalong;
   char i;
   for(i=0; i<sizeof(long); i++)
      send_byte(*ptr++);
}

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

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

Сообщение vitalik_1984 »

DX168B писал(а):Это тоже самое, что и:

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

PORTD&=~(1<<PD5);

А как вам такая конструкция?

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

set_bit(PORTD,PD1);
clear_bit(PORTD,PD1);

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

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

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

vitalik_1984 писал(а):А как вам такая конструкция?

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

set_bit(PORTD,PD1);
clear_bit(PORTD,PD1);

Прелесть в том, что в среде Визуал студио, даже функции не нужно вручную заколачивать...:) по паре букв и мышью выбор.

на мой взгляд - конструкция так себе: по сравнению с PORTD|=_BV(PD1) слишком много лишних символов. плюс лишь в том, что есть ооооочень слабая надежда, что код с set_bit() будет проще перенести на какой-нибудь другой МК, ARM например.

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

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

Сообщение vitalik_1984 »

Мастер Ломастер писал(а):на мой взгляд - конструкция так себе: по сравнению с PORTD|=_BV(PD1) слишком много лишних символов.
плюс лишь в том, что есть ооооочень слабая надежда, что код с set_bit() будет проще перенести на какой-нибудь другой МК, ARM например.

ну да есть такая вероятность, только заголовочный с описанием макроса поменять:)

А еще плюс- читабельность резко повышается.
Мастер Ломастер писал(а):вдруг там щука волшебная есть - вообще не пришлось бы на кнопочки давить...

Ну не знаю, лично я взял на основе ваших примеров и файла sfr_defs.h смастерил этот макрос.


##
А если в начале вашего исполняемого файла прописать

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

#define set(X)  set_bit(PORTD,X)
#define clear(X) clear_bit(PORTD,X)

то можно дальше писать:

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


Set(rs);
Clear(rw);
delay();
clear(rs)

В поисках истины человек развивается.
Arlleex
Друг Кота
Сообщения: 4435
Зарегистрирован: Сб мар 07, 2009 20:44:36

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

Сообщение Arlleex »

Как вот это читать и понимать?

while(!(pPMC->PMC_SR & (1<<0)));
Не умеешь - не берись, но не взявшись не научишься...
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

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

Arlleex писал(а):Как вот это читать и понимать?

while(!(pPMC->PMC_SR & (1<<0)));
ждать, пока не установится в единицу младший бит в каком-то регистре (ячейке памяти?) PMC_SR - тут, видимо, для ARM-а код, потому что конкретно этот бит означает и где конкретно он находится - я не в курсе. очевидно, pPMC - это указатель на структуру управляющих периферийных регистров, а PMC_SR - это один из этих регистров.
битва с дураками проиграна, победители торжествуют. слава победителям!
Arlleex
Друг Кота
Сообщения: 4435
Зарегистрирован: Сб мар 07, 2009 20:44:36

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

Сообщение Arlleex »

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

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

Сообщение alexey6522 »

Преобразовываю ASCII код в строку с помощью функции itoa(int, *char, 16);
на выходе получаю char = HEX;
как из HEX *char тип, преобразовать в обычную строку?
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

а что здесь необычного ?
*char - указатель нультерминированной строки, т.е адрес ее первого элемента.
char temp[20];
itoa(1122, temp, 16);
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

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

Сообщение alexey6522 »

К примеру я отправляю с ПК единичку в ком1, он изначально принимается как 49 согласно таблице ASCII, с помощью функции
itoa(inDataInt, outChar, 16); я получаю значение ввиде 31 это HEX уже, а как из HEX получить просто 1?
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

обратное преобразование, наверное
int n=atoi(CString(temp));
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

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

Сообщение alexey6522 »

Это-то понятно, у меня столько не состыковок
1. Может ли код приведенный ниже посылать на 7-ми сегментный индикатор отрицательные числа и отоброжать знак минус в отдельном сегменте? До сих пор требовалось посылать только со знаком+

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

#define DIGIT 5
unsigned char cArr[DIGIT];
unsigned int step[DIGIT]={10000,1000,100,10,1};

#define   N0   (0x3F)      //0
#define   N1   (0x06)      //1
#define   N2   (0x5B)      //2
#define   N3   (0x4F)      //3
#define   N4   (0x66)      //4
#define   N5   (0x6D)      //5
#define   N6   (0x7D)      //6
#define   N7   (0x07)      //7
#define   N8   (0x7F)      //8
#define   N9   (0x6F)      //9

unsigned char indikator[10]={N0, N1, N2, N3, N4, N5, N6, N7, N8, N9};

void fnLongToStr(unsigned long tmp) //раскладывает число tmp в массив 5 байтов, т.е если в лонг 0х00000010
{                           //то в массиве 0,0,0,1,6
unsigned char i,atemp;
unsigned long val,temp;
val=tmp;
for (i=0; i<DIGIT; i++)
{
   temp=(unsigned long)step[i];
   atemp=0;
   while(val >= temp)
     {
       atemp++;
       val-=temp;
     }
   cArr[i]=atemp;
}
}
//----------
void fnImageDigit(void) //перекидывает реальные значения этого массива в их образы
{                  //после нее в массиве будет
unsigned char i;
   for (i=0; i<DIGIT; i++)
      {
      cArr[i]=indikator[cArr[i]];
      }
}
//----------
void fnOutByte(unsigned char cByte) //вывод байта на регистр
{
unsigned char mask =0x80;
   do{
   if(mask & cByte)
   {
   PORTD|=_BV(PD5);
   }
   else
   {
   PORTD&=~_BV(PD5);
   }
    PORTD|=_BV(PD6); //Импульс на SH_CP (запись)
    PORTD&=~_BV(PD6);
   mask>>=1;
}while(mask);
}
//----------

void fnShowDigit(unsigned long tmp) //выводит tmp на регистры
{
   unsigned char i;
   fnLongToStr(tmp);
   fnImageDigit();
   for (i=0; i<DIGIT; i++)
   {
   fnOutByte(cArr[i]);
   }
}
//----------


2. требуется получить число с ПК, положительное либо отрицательное, а потом отправить его на индикатор, для отрицательного числа зажечь -G- сегмент, таким образом показать что оно отрицательное
3. разрядность числа 5, диапазон от -99999 до 99999
4. Функция USART_Receive может принимать по символьно, мне нужно собрать это как число, а потом вызовом fnShowDigit отправить на индикатор

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

unsigned long int USART_Receive( void )
{
  while ( !(UCSRA & (1<<RXC)) );
  return UDR;
}
//----------
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

здесь при общении с компом возникает как бы проблема при использовании этих функций - вы не знаете, сколько байт нужно принять.
Пример -1 - 2 байта
0 - 1 байт
-99999 - 6 байт
Можно принимать до получения завершающего нуля (принимать, ест-но тоже с нулем) а можно выступить в роли проктолога.
Т.е. в 32 битной винде инт - это 4 байтовое.
Т.е. передавая эти 4 байта Вы точно уверены, что заполните Ваш сигнед лонг, с которого сначала снимаем знак - для минуса, а затем берете модуль этого числа и выводите обычным способом.

со стороны винды где-то так

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

   union _un{
   signed int l;
   char temp[4];
   }un;
unsigned char temp2[8];

un.l=-12345;// в темп в юнионе эти 4 байта
// переводим их в символьный вид для выдачи тетрадами
// тетрад получится 8
   for(int i=0;i<8;i+=2)
   {
   temp2[i]=un.temp[i/2]&0x0f;
   if(temp2[i] > 0x9){ temp2[i]+='A'-10;}
   else {temp2[i]+='0';}
   temp2[i+1]=un.temp[i/2]>>4;
   temp2[i+1]&=0x0F;
   if(temp2[i+1] > 0x9){ temp2[i+1]+='A'-10;}
   else {temp2[i+1]+='0';}
   }

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

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

Сообщение alexey6522 »

Если у меня значение всегда 5-ти значное, не считая знака "-" нельзя ли обойтись без этого алгоритма кодирования, я все-равно не знаю как потом раскодировать его на МК
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

можно
воспользуйтесь вместо itoa sprintf
например
char temp2[10];
signed int l=1;
sprintf(temp2,"%06d",l);
Аватара пользователя
avante
Родился
Сообщения: 14
Зарегистрирован: Чт авг 25, 2011 15:15:35

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

Сообщение avante »

Добрый вечер уважаемые, борюсь с побитовыми операциями и как-то туго до меня доходит как это все работает, вот например смысл этого:
для меня не понятен, как можно 1 бит сместить на 0 бит в лево и самое главное зачем? Часто встречается в таком виде:

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

PORTD |= (1<<0)
не проще ли PORTD.0=1 ? и вообще одно это и тоже?
В процессе написания кода меня постоянно не покидает ощщущение, что я через чур активно пользуюсь граблями, хотя все делается проще. К примеру, хочу в PORTB записать 7 первых бит(0x24), а последний восьмой не трогать, т.е. он должен остаться таким какаим и был после изменения первых семи битов. Пришлось сооружать вот такие грабли:

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

unsigned char set_led (unsigned char sou)
{
unsigned char t, a;
t = PORTB;
a = 0x0;
a |= sou;
t = ((t >> 7) << 7);
a |= t;
return a;
}

Работает так:

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

PORTB = set_led(0x24);


Ругайте. Обещаю исправиться, освоиться с этими битовыми операциями, просто раньше никогда приходилось так много ими пользоваться.
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

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

Сообщение lix »

(1<<0) = это для унификации, вдруг потом придется другой бит писать.
PORTB.1 = 1 не заработает в gcc, так как это не по стандарту си, а просто добавка к синтаксису от производителя компилятора.

avante писал(а):К примеру, хочу в PORTB записать 7 первых бит(0x24)

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

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

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

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

lix писал(а):
avante писал(а):К примеру, хочу в PORTB записать 7 первых бит(0x24)

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

x=0x24;
PORTB &= 0x80;
PORTB = x & 0x80;
лажа 100%
вот здесь ваш мявтор подробно расписал: http://arv.radioliga.com/content/category/6/33/49/
битва с дураками проиграна, победители торжествуют. слава победителям!
Ответить

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