Страница 38 из 386

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

Добавлено: Пн авг 22, 2011 20:31:15
alexey6522
Мастер Ломастер простите за мое не знание в теории, не знал что для вас столь важно название функции во множественном числе или же в ед. Я уже давно определился что я мальчик и хочу работать с числом, просто пример попался для передачи строки.

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

Добавлено: Пн авг 22, 2011 20:37:08
IfoR
Тут такая функция была: itoa(int) - преобразовывает число в строку.

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

Добавлено: Пн авг 22, 2011 20:41:13
Мастер Ломастер
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 - это уже выдача числа в "сыром виде", не в виде строки. надеюсь, все понятно?

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

Добавлено: Вт авг 23, 2011 17:12:39
vitalik_1984
DX168B писал(а):Это тоже самое, что и:

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

PORTD&=~(1<<PD5);
А как вам такая конструкция?

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

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

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

Добавлено: Вт авг 23, 2011 18:50:27
Мастер Ломастер
vitalik_1984 писал(а):А как вам такая конструкция?

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

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

по поводу прелести: не пробовали зимой к проруби в реке сходить? вдруг там щука волшебная есть - вообще не пришлось бы на кнопочки давить...

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

Добавлено: Вт авг 23, 2011 19:53:15
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)


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

Добавлено: Вс авг 28, 2011 14:11:39
Arlleex
Как вот это читать и понимать?

while(!(pPMC->PMC_SR & (1<<0)));

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

Добавлено: Вс авг 28, 2011 17:18:29
Мастер Ломастер
Arlleex писал(а):Как вот это читать и понимать?

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

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

Добавлено: Вс авг 28, 2011 18:56:15
Arlleex
Да, все верно :)
Спасибо за помощь

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

Добавлено: Пн авг 29, 2011 19:04:34
alexey6522
Преобразовываю ASCII код в строку с помощью функции itoa(int, *char, 16);
на выходе получаю char = HEX;
как из HEX *char тип, преобразовать в обычную строку?

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

Добавлено: Пн авг 29, 2011 21:13:31
urry
а что здесь необычного ?
*char - указатель нультерминированной строки, т.е адрес ее первого элемента.
char temp[20];
itoa(1122, temp, 16);

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

Добавлено: Пн авг 29, 2011 21:20:05
alexey6522
К примеру я отправляю с ПК единичку в ком1, он изначально принимается как 49 согласно таблице ASCII, с помощью функции
itoa(inDataInt, outChar, 16); я получаю значение ввиде 31 это HEX уже, а как из HEX получить просто 1?

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

Добавлено: Пн авг 29, 2011 21:24:58
urry
обратное преобразование, наверное
int n=atoi(CString(temp));

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

Добавлено: Вт авг 30, 2011 10:19:43
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;
}
//-----------------------------

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

Добавлено: Вт авг 30, 2011 12:29:59
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';}
	}
На стороне контроллера делаем обратное преобразование , учитывая формат представления - литл ендиан или биг ендиан - как в конкретном компиляторе, я не знаю.

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

Добавлено: Вт авг 30, 2011 13:37:13
alexey6522
Если у меня значение всегда 5-ти значное, не считая знака "-" нельзя ли обойтись без этого алгоритма кодирования, я все-равно не знаю как потом раскодировать его на МК

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

Добавлено: Вт авг 30, 2011 14:04:11
urry
можно
воспользуйтесь вместо itoa sprintf
например
char temp2[10];
signed int l=1;
sprintf(temp2,"%06d",l);

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

Добавлено: Сб сен 03, 2011 18:11:58
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);
Ругайте. Обещаю исправиться, освоиться с этими битовыми операциями, просто раньше никогда приходилось так много ими пользоваться.

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

Добавлено: Сб сен 03, 2011 18:38:55
lix
(1<<0) = это для унификации, вдруг потом придется другой бит писать.
PORTB.1 = 1 не заработает в gcc, так как это не по стандарту си, а просто добавка к синтаксису от производителя компилятора.
avante писал(а):К примеру, хочу в PORTB записать 7 первых бит(0x24)

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

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

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

Добавлено: Сб сен 03, 2011 22:16:15
Мастер Ломастер
lix писал(а):
avante писал(а):К примеру, хочу в PORTB записать 7 первых бит(0x24)

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

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