Перейти к содержанию
    

Кто то может уже натыкался на данную проблему, подскажите пожалуйста

Пишу:

unsigned long long i;
i=(((unsigned long long)1)<<0x20);

так вот без ошибки компилирует если сдиг не более 0x1F, если 0x20 и больше выдает ошибку - Warning[Pe063]: shift count is too large

Как это победить, в чем проблема?

Изменено пользователем IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не ошибка, а предупреждение, что разрядность типа long long в IAR STM8 - 32 бита.

Выход, например,через оформление переменной i в виде класса/структуры с соответственной обработкой.

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То что 32 бита это я уже понял, как примерно оформить?

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

struct U64 {
  uint32_t low, hi;
};

 

 

ну и дальше пишете набор необходимых вам арифметических операций

 

Если у вас просто биты, то возможно будет удобнее работать с массивом байт

struct Mask {
  byte d[8];
};

void mask_clear(Mask *m) { memset(m->d, 0, sizeof(m->d); }
void mask_set(Mask *m, unsigned no) { m->d[no/8] |= (1<<(no%8)); }
void mask_clear(Mask *m, unsigned no) {}
void mask_put(Mask *m, unsigned no, bool v) {}
bool mask_test(Mask *m, unsigned no) {}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня единственная операция, это сдвиг вправо(влево) в цикле 64 раза...

Вот и не пойму как разделить это дело ...

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я ничего не напутал, то что-то в таком духе

struct U64 {
  uint32_t low, hi;
};

U64 u64_lshift(U64 a, unsigned b) {
  U64 r;
  if (b < 32) {
    r.low = a.low<<b;
    r.hi = (a.hi<<b) + (a.low >> (32-b));
  }
  else {
    r.low = 0;
    r.hi = a.low << (b-32);
  }
  return r; 
}

А вообще можно погуглись, может что и по оптимальнее найдется

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну похоже..

я вот не пойму в чем прикол, IAR именно для STM8, в справке такой тип есть, если в него число больше 32 бит не записывать типа предупреждений нет и все работает....

Косяк IAR -?

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я вот не пойму в чем прикол, IAR именно для STM8, в справке такой тип есть, если в него число больше 32 бит не записывать типа предупреждений нет и все работает....

Косяк IAR -?

 

посмотрите хидеры, попробуйте сделать sizeof(U64). На авр-ках uint64_t работает...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

посмотрите хидеры, попробуйте сделать sizeof(U64). На авр-ках uint64_t работает...

Сейчас гляну....

 

Сейчас гляну....

 

А не знаете как макрос использовать __delay() и так и сяк не хочет..........

 

 

посмотрите хидеры, попробуйте сделать sizeof(U64). На авр-ках uint64_t работает...

Непонятно, подлючаю только это #include <iostm8l152c6.h>

Там нет описания типов данных, что то подключается автоматом...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не знаете как макрос использовать __delay() и так и сяк не хочет..........

Я с stm8 не сталкивался

 

 

Непонятно, подлючаю только это #include <iostm8l152c6.h>

Там нет описания типов данных, что то подключается автоматом...

ну дык он скорее всего подключает какие-то другие хидеры и в конце концов подключаются системные хидеры с описанием типов

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня единственная операция, это сдвиг вправо(влево) в цикле 64 раза...

Вот и не пойму как разделить это дело ...

Если у Вас единственный сдвиг 0x01 конкретно на 64 бита, то для структуры достаточно операции

struct U64 {
  uint32_t low, hi;
};

low = 0x00;  
hi   = 0x01;

А если встречается различное количество сдвигов то удобнее тип оформить в виде массива 8 байт d[8] и

саму сдвижку производить на ассемблере по алгоритму:

1. d[0] - логический сдвиг для заноса в carry-флаг старшего бита

2. с d[1] - и далее - циклический сдвиг

 

на С сдвиг на 1 приблизительно так:

unsigned char carry;

 carry = d[0];
 d[0]<<=0x01;
 for (i=1; i<8;i++)
 {
   if(carry&0x80)
     {
        carry=d[i];
        d[i]<<=0x01;
        d[i]|=0x01;
     }
   else
     {
        carry=d[i];
        d[i]<<=0x01;
     }
 }

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это все ужасно долго, нужно сделать 1 сдвиг, потом передача в DMA и т.д. потом еще сдвиг и т.д. всего 60 - 62 раза, а если делать так это ай-ай ............

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это все ужасно долго, нужно сделать 1 сдвиг, потом передача в DMA и т.д. потом еще сдвиг и т.д. всего 60 - 62 раза, а если делать так это ай-ай ............

 

Это "ужасно долго" делает именно IAR для восьмибитных процессоров.

Только система команд STM8 имеет возможность сдвига слова, что позволяет свести операцию над 64-разрядным типом

к 4-м операторам сдвига вместо 8-ми. С предварительным оператором очистки флага carry разумеется.

И так это он повторяет в цикле 62 раза для каждого i=(0x01)<<62;

 

Для ускорения разумнее организовать цикл с модификацией: i<<=1;

 

Если Вы желаете, чтобы это выглядело коротко на экране, то можете сделать что-то подобное:

 

#define SimpleShift(p, n) do{memset(p,0,8); p[n/8]<<=(n%8);}while(0);

 

 

и вместо i=(0x01) << 62 вставить

SimpleShift(&i, 62);

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сечас попробую так временные интервалы измерить.....

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это все ужасно долго, нужно сделать 1 сдвиг, потом передача в DMA и т.д. потом еще сдвиг и т.д. всего 60 - 62 раза, а если делать так это ай-ай ............

Ну тогда вам ассемблер нужен. По моему опыту яр для стм8 плохенько умеет оптимизировать. Делал i2c ногодрыгом с разгоном (порядка 2 Мбит/м) - сделал на ассемблере. Отлично получилось. Могу пример предоставить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...