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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
shurikss123
Грызет канифоль
Сообщения: 271
Зарегистрирован: Пн окт 25, 2010 20:47:04
Откуда: Казахстан, Астана

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

Сообщение shurikss123 »

IfoR писал(а):DX168B, я, наверно, не совсем в теме, но может быть так:

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

#include <avr\io.h>
#include <util\delay.h>
#include <avr\pgmspace.h>

const char b[] = {128,64,32,16,8,4,2,1};

int main(void)
{
    DDRB=0xFF;

    for(int j =0;j<sizeof(b);j++)
    {
        PORTB = b[j];
        _delay_ms(500);
    }
    for(;;);
}
 


:dont_know:


Огромное спасибо тебе человек прям огроменное, я немного посчитал помучал потрогал погрел и сделал вывод что мне нафиг не нужно чтоб у меня была погрешность в 0.01% мне хватит и 1% чтоб понять что там на улице вобшем то что там мы считали все только для того чтоб вывести погрешность в 0.01% а на один процент достаточно и этого

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


   LCDinit();
   LCDclr();

   SCH_Enable();
   SCH_Reset();
   SCH_Start();
   SCH_Write(0b00000011);
   SCH_Meas();
   i=SCH_Read(0);
   b=SCH_Read(1);
   temp=i<<8;
   temp=temp+b;

   uint16_t temperatura=(temp-4010)/10;

   sprintf(Buf,"T=%3u",temperatura);

   LCDGotoXY(0,0);
   LCDsendString(Buf);

   SCH_Enable();
   SCH_Reset();
   SCH_Start();
   SCH_Write(0b00000101);
   SCH_Meas();
   i=SCH_Read(0);
   b=SCH_Read(1);
   temp=i<<8;
   temp=temp+b;

   uint16_t humidity=((0.367*temp)-20.468);

   sprintf(Buf,"RH=%3u",humidity);

    LCDGotoXY(6,0);
   LCDsendString(Buf);


вывод такой T=229 RH=356
ну типа 22.9 и 35.6
Изображение
Мастер на все руки, кручу, кручу, кручу и матерюсь
Повелитель паяльной станции, лома, и пинцета!!!
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

IfoR писал(а):DX168B, я, наверно, не совсем в теме, но может быть так:

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

#include <avr\io.h>
#include <util\delay.h>
#include <avr\pgmspace.h>

const char b[] = {128,64,32,16,8,4,2,1};
......
 


:dont_know:

В доках пишут, что надо его так объявлять, иначе не видать массива во флеше.

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

const char b[] PROGMEM = {128,64,32,16,8,4,2,1};

Оно работает и в сгенерированном листинге на АСМе массив присутствует.
а функция strcpy_P(ram, flash); копипастит из флеша в ОЗУ. И только от туда уже в портБ.
На АСМе это просто делается:
.......
ldi ZL, Low(ARRAY*2)
ldi ZH, High(ARRAY*2)
ldi r17, 0x08
LOOP:
lpm r16, Z+
out PORTB, r16
rcall DEL01
dec r17
brne LOOP
......

А тут как? Я уже заип*л этот Гугл запросами... :kill: :)))
Ладно. Попробую с указателями, как в x86. Если не получится, то пойду дальше курить мануалы. :)
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

А так ты пробовал? А то я нет. Но по идее должно же работать. Ну я не знаю.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ну пока только так, как выложил первый раз, то есть через ОЗУ.
Сейчас попробовал с указателем и покурив мануалы, сделал так:

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

#include <avr\io.h>
#include <util\delay.h>
#include <avr\pgmspace.h>

char array[] PROGMEM = {128,64,32,16,8,4,2,1};

char *a; //Указатель на массив

int main(void)
{
   DDRB=0xFF;
   a=array; //Передаём адрес массива указателю
   for(int j=0;j<8;j++)
   {
      PORTB = pgm_read_byte(a); //вытаскиваем данные в порт, используя указатель
      _delay_ms(500);
      a++; //увеличиваем адрес массива в указателе на единицу
   }
}

Теперь работает без использования ОЗУ. :)
То есть так, как я и хотел. :)

Это я просто примеры пишу для тренировки.
Далее сделаю два указателя и многомерный массив в виде таблицы и попробую ходить по элементам, используя указатели. Типа выбор строки и столбца.
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ещё один вопрос:
Имеем двухмерный массив данных:

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

   float array[12][3] = {{0.0, 2.5, 0.0}, //l
                     {0.5, 3.0, 0.0}, //a  //x, y, z

                     {1.5, 3.0, 0.0}, //b
                     {2.0, 3.5, 0.0}, //c

                     {2.5, 3.5, 0.0}, //d
                     {3.0, 3.0, 0.0}, //e

                     {3.0, 2.0, 0.0}, //f
                     {2.5, 1.5, 0.0}, //g

                     {2.5, 0.5, 0.0}, //h
                     {2.0, 0.0, 0.0}, //i

                     {0.5, 0.0, 0.0}, //j
                     {0.0, 0.5, 0.0}}; //k

Это по трёхмерной графике. Как можно получить отдельно количество блоков в массиве и количество элементов в одном блоке массива?
sizeof(array) работает для обычных массивов, а тут как?

ПОЗЖЕ:
Разобрался. Работает.
Для количества блоков пишем sizeof(*array)
А для количества элементов в блоке sizeof(**array)
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

float array[12][3]; // 12 - элементный массив, элементами которого есть 3-элементные массивы float
sizeof(array) // размер всего огорода в штуках char
sizeof(array[0]) // размер одного элемента "внешнего" массива, т.е. размер 3-элементного массива float
sizeof(array[0][0]) // == sizeof(float)

sizeof(array) / sizeof(array[0][0]) // в данном случае 36 == 12*3
sizeof(array) / sizeof(array[0]) // в данном случае 12
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ну, я уже сориентировался, скормив его sizeof'у в виде указателя. :)))
Ведь название массива по сути и является указателем на него.
Массив я представил себе в виде массива адресов, по этому так и сделал.
Но всё равно спасибо за пинок. :) :beer:
Последний раз редактировалось DX168B Вс авг 21, 2011 19:38:22, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

DX168B писал(а):ПОЗЖЕ:
Разобрался. Работает.
Для количества блоков пишем sizeof(*array)
А для количества элементов в блоке sizeof(**array)
Что имеется ввиду под «количеством блоков» ?
Если количество подмассивов, то просто случайно совпало.

В данном случае (для float array[12][3])
Размер подмассива sizeof(*array) == sizeof(array[0]) == 3 * sizeof(float) == 3 * 4 == 12

«правильное» 12 (количество подмассивов) можно получить при помощи sizeof(array) / sizeof(*array)

Ну а sizeof(**array) == sizeof(float)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ну вот, для эксперимента пошёл на изврат:

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


   float array[12][3] = {{0.0, 2.5, 0.0},
                     {0.5, 3.0, 0.0},

                     {1.5, 3.0, 0.0},
                     {2.0, 3.5, 0.0},

                     {2.5, 3.5, 0.0},
                     {3.0, 3.0, 0.0},

                     {3.0, 2.0, 0.0},
                     {2.5, 1.5, 0.0},

                     {2.5, 0.5, 0.0},
                     {2.0, 0.0, 0.0},

                     {0.5, 0.0, 0.0},
                     {0.0, 0.5, 0.0}};

   float array1[3];

   glBegin(GL_LINE_LOOP);
   glColor3f(0.0f,1.0f,0.0f);

      for(int i=0;i<sizeof(*array);i++)
      {
         for(int j=0; j<sizeof(**array);j++)
         {
            array1[j] = array[i][j];
         }
         glVertex3f(array1[0], array1[1], array1[2]);
      }
   glEnd();


Получил в итоге правильно работающую конструкцию. :)
Отрисовывается всё тот же многоугольник, координаты точек которого приведены в этом массиве.

А на счёт блоков - это я так, своими словами. Не люблю научную терминологию.
Он состоит из 12 элементов и каждый элемент состоит из трёх значений. В данном случае, из трёх чисел с плавающей запятой.
Последний раз редактировалось DX168B Вс авг 21, 2011 19:54:32, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
oleg-him
Открыл глаза
Сообщения: 44
Зарегистрирован: Чт янв 31, 2008 15:51:25
Откуда: прим. край

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

Сообщение oleg-him »

День добрый! очень сильно нужна ваша помощь! хочу переделать схему и программу измерителя ёмкости http://radioded.ru/content/view/77/49/ на ATtiny2313, под микроконтроллер атмега8, светодиодные индикаторы, кварц 8Мгц, и без использования сдвигового регистра.
да, есть куча подобных схем, но они либо с ЖК индикатором, либо с кварцем 10 Мгц, что неприемлемо т.к. нет этих деталей. что нужно в прошивке поменять???
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

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

Сообщение alexey6522 »

Извините что влезаю в ваш разговор!
к примеру у меня есть число длинной 5 байт закодированное в 16-hex (0x065B4F666D) это будет 54321,
как добавить 0x06 (это единица в 10-ой системе) к числу 0x065B4F666D, что бы получить 54322
Я думал что все как обычно 0x065B4F666D+0x06 или 0x065B4F666D+0x0600000000
И ошибся в своем убеждении, может я не правильно мыслю, ведь это не привычная нам система счисления,
ведь в двоичной системе счисления нельзя просто добавить 1 и получить следующее число по порядку
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

То есть вы пытаетесь проделать арифметическую операцию с мнемоническими значениями ASCII?

Такое не прокатит. По моему надо выполнить операцию на уровне физических значений и потом преобразовать это в ASCII.
Типа (Код Visual Studio):

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

char disp[20] = "54321"; //наше число ASCII
char num[20] = "1"; //число ASCII, которое надо прибавить.
int a = 0; //тут целочисленная переменная с которой будем проделывать операции
int b = 0; //тут будет складываемое число
a = atoi(disp); //преобразуем ASCII число в int число
b=atoi(num);
a=a+b; //складываем преобразованные числа
itoa(a, disp, 10); //преобразуем результат обратно в ASCII
Последний раз редактировалось DX168B Вс авг 21, 2011 20:22:23, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

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

Сообщение alexey6522 »

Приведу полный код своей программы

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

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// составляем из сегментов цифры
#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};
unsigned char y=0; //переменная y

void export_data (unsigned long long data)
{
  unsigned char i; //переменная i
  for (i=0;i<40;i++) {
    if (!(data&0x8000000000)){
      PORTD&=~_BV(PD5); //Выставляем биты данных на PD5 (DATA канал)   
     }
    else {
     PORTD|=_BV(PD5);
     }
    PORTD|=_BV(PD6); //Импульс на SH_CP (запись)
    PORTD&=~_BV(PD6);
    data<<=1;
  }

   PORTD|=_BV(PD7); //Импульс на ST_CP (защелка - вывод на индикатор записанных данных)
    PORTD&=~_BV(PD7);
}

int main(void)
{
  long int DS=0;   //переменная DS
  unsigned int i=0;    //переменная i
  PORTD=0x00; //Первоначально устанавливаем на всех выходах 0
  DDRD=0xff; //установить PD0-PD2 как выходы
  while (1)  //Бесконечный цикл
   {   
      export_data(0x065B4F666D);   //Отправляем данные на сдвиговый регистр
   }
}


в месте вызова export_data(0x065B4F666D); //Отправляем данные на сдвиговый регистр
отправляются данные на 7-ми сегментный индикатор, мне нужно из этого организовать счетчик чисел от 0 до 99999
был предложен код, как мне его изменить под себя, т.е. из 16 битного счетчика в 40 битный

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

    DS=(indikator[i] << 8) | indikator[j]; //Закодированное число в 16hex системе исчисления
    export_data(DS);  //Отправляем данные на сдвиговый регистр
   if (j==9)
  {
   j = 0;         
   if (i==9) // Если i > 9 то обнуляем
     i=0;
   else i++;
   }
   else j++;
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Вам надо использовать массив

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

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

для преобразования двоичного числа в символы семисегментного индикатора.
А операции надо проделывать именно с двоичными числами.
На АСМе я делал, а до Си пока не доходило. Сейчас подумаем....
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

alexey6522

Добавляем функцию:

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


unsigned long long toDigital
(unsigned long int i)
{
     unsigned long long result=0;
     int r;
     
     for 
(r=0; r<5; r++)
     { result = (result>>8)|(indikator[(unsigned char)(i%10)]<<32); i/=10; }

     return result;
}
 


В функции main меняем:

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

//...

unsigned long int s=0;

while (1)  //Бесконечный цикл
   {   
      export_data
(toDigital(s++));   //Отправляем данные на сдвиговый регистр
     if (s>99999) s=0;
     _delay_ms(500); // Ждём полсекунды
   }

//...
 


Код традиционно не проверял. :roll:
Последний раз редактировалось IfoR Вс авг 21, 2011 21:31:06, всего редактировалось 1 раз.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

DX168B писал(а):Получил в итоге правильно работающую конструкцию. :)
Отрисовывается всё тот же многоугольник, координаты точек которого приведены в этом массиве.
Я рад за Вас.
А теперь попробуйте отрисовать 7-угольник. Или 13.
И проверьте после отрисовки -- сохраняется ли значение array[0][0];
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

DX168B, э-э-э... странные операции ты выполняешь.
Может быть я не обладаю некоторыми знаниями, т.ч. потом кто нить поправьте.
Во-первых: sizeof возвращает размер типа в байтах, а не в элементах. Что-бы найти количество элементов, надо сделать типа этого:

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

sizeof(array)/sizeof(float)

Во-вторых: Один раз обращаться по указателю можно, т.к. фактически array и является указателем на массив. По идее операция *array должна вернуть первый элемент в массиве. Но вот второе обращение по указателю уже лишнее. Данный массив это НЕ указатель на указатели на элементы типа float. Это указатель на элементы типа элементы типа float. :) Т.е, это не массив указателей, а массив массивов - он представляется в памяти как обычный большой одномерный массив. Т.ч. что вернёт операция **array я без понятия. :dont_know:

Хотя, если компилятор как-то настроен так, что он представляет представляет массив в виде указателей, то тогда такая конструкция может действительно работать. Но я не знаю как это делается.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ifor
Вот именно, он так и понимает его и как набор указателей и как набор данных. Ту вся фишка в том, в каком виде ты его скормишь. или скажешь x = array[0][1]; или x=*array[0][1];
В первом примере ты получишь данные, а во втором - адрес. :)
Другие методы получения размеров вызывают артефакты при отрисовке. В том числе и те методы, которые вы мне объясняете. Всё из за того, что он получает неверные значения размеров.
Я вообще мог статично указать размеры в циклах и не париться, но мне хочется привязать отрисовку полностью к массиву.
avreal

Ну и???? Добавление ещё одного элемента вызывает нервный тик у компилятора.
И ругается он не на *array или **array, а на сам массив. :))) Я даже вычистил всю функцию, оставив только массив. Ругаеццо и sizeof(**array) тут не причём. :)

: truncation from 'const double' to 'float'


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

   float array[13][3] = {{0.0, 2.5, 0.0},
                     {0.5, 3.0, 0.0},

                     {1.5, 3.0, 0.0},
                     {2.0, 3.5, 0.0},

                     {2.5, 3.5, 0.0},
                     {3.0, 3.0, 0.0},

                     {3.0, 2.0, 0.0},
                     {2.5, 1.5, 0.0},

                     {2.5, 0.5, 0.0},
                     {2.0, 0.0, 0.0},

                     {0.5, 0.0, 0.0},
                     {0.0, 0.5, 0.0},

                     {0.2, 0.2, 0.0}}; //<- Error


Да там нечётный элемент и не нужен, так как библиотека дорисовывает сама последнюю грань.
Если нам надо нарисовать шестиугольник, то мы указываем шесть координат. Последняя точка находится там, где и первая. Если нужен семиугольник, то указываем тоже шесть координат, только меняем их расположение относительно друг к другу в пространстве так, чтобы последняя точка не находилась там же, где и первая. А библиотека сама прорисует линию от шестой точки к первой. Получим семиугольник. Для рисования треугольника, достаточно указать 4 точки. :)
Последний раз редактировалось DX168B Вс авг 21, 2011 22:45:58, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

Да уж. Компилятор действительно распознаёт конструкцию **array как array[0][0]. А попробуй только передать такой массив функции с параметром типа float**. Что-то я не понимаю в этой жизни.
Последний раз редактировалось IfoR Вс авг 21, 2011 22:43:26, всего редактировалось 1 раз.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

PORTD&=~_BV(PD7);

Скажите откуда взялась эта конструкция?Меня интересует конкретно _BV(PD7).
Просто в CVavr есть конструкция типа Portb.7= X где Х это 0 или 1.
А как это реализовать методами языка,ведь при стандартном раскладе нужно писать
Portb|=(0<<PB7)|(1<<PB0) вроде так.
В поисках истины человек развивается.
Ответить

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