Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

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

Вт апр 18, 2017 15:07:30

даже еще проще нужно быть :)))
Код:
typedef enum{
   STATE_OFF,
   STATE_LEFT,
   STATE_RIGHT,
   STATE_ALARM
} states;

states state;
volatile int counter;

interrupt [TIM1_COMPA] void timer1_compa_isr(void){
   counter++;
}

void main(void){
   // тут добавить настройки таймера и портов
   while(1){
      if(!alarm_butt)      state = STATE_ALARM;
      else if(!left_butt)  state = STATE_LEFT;
      else if(!right_butt) state = STATE_RIGHT;
      else                 state = STATE_OFF;

      if(counter & 1)
         switch(state){
            case STATE_LEFT:   left_on;             break;
            case STATE_RIGHT:  right_on;            break;
            case STATE_ALARM:  right_on;  left_on;  break;
         }
      else {
         left_off;
         right_off;
      }
   }
}
я в прошлый раз главный цикл пропустил :))) не могу код писать без нормального редактора...

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

Чт апр 20, 2017 19:53:25

Всем привет, может кто помочь дописать код в этом проекте? http://arduino-diy.com/arduino-svetodiodnyy-kub-4x4x4
затея такая к имеющемуся коду добавить ручное управление через терминал, смысл такой подрубаю терминал отправляю команду 1 куб переходит в ручное управление, все светодиоды гаснут (0 возвращает в мануал в котором гоняеет эффекты) в ручном управлении я посылаю команды формата (x1 y1 z1 q1) где загорается 1 светодиод по координатам x1y1z1, q1 это включение светодиода q0 выключение, ну как то так, все переменные примерно условно, вроде бы максимально просто, файл с кодом прилагаю(в статье тоже самое в скетче)за помощь накину сотни три рублей на вискас :hunger:
Вложения
прошивка.h
(16.24 KiB) Скачиваний: 685

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

Чт май 18, 2017 20:44:18

Сегодня залез в один проект микрочиповский - решил прилизать и несколько шероховатостей сгладить... ПОка колупался, смотрю, предлагает поставить более свежие версии. Ну я и поставил. В результате, почему-то компилятор стал придираться сильнее чем раньше. Т.е. выдаёт целую толпу предупреждений. И все одного типа:
main.c:767: warning: (373) implicit signed to unsigned conversion
Целую толпу заборол понаставив буковок "u" у числовых констант. Но вот одну не могу забороть. Самое обидное, связано с тем, что я на предыдущей странице описывал, как попытался заменить дефайны на энумы. Вобчем код:
Код:
typedef enum KEY_DEFINITION {
    KEY_NO_DATA = 0u,
    KEY_SET  = 0x40u,
    KEY_MODE = 0x10u,
    KEY_RELEASE = 0x02u
} keys_t;

#define KEYMASK (unsigned char)(KEY_SET | KEY_MODE)

unsigned char kbdread(void) {
  unsigned char readkey;
  static unsigned char repeated, prevkey;
    
  readkey 
= (PORTC ^ KEYMASK) & KEYMASK;

Вышепомянутую ошибку выдаёт на вот эту, последнюю строчку. PORTC в хедерах определен как
Код:
#define PORTC PORTC
extern volatile unsigned char           PORTC               @ 0x007;

Не могу понять, где еще тут что знаковое?
Пробовал написать #define KEYMASK ((unsigned char)KEY_SET | (unsigned char)KEY_MODE) - не помогло.

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

Чт май 18, 2017 21:56:19

Какой компилятор и проц ?

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

Чт май 18, 2017 22:12:25

Не могу понять, где еще тут что знаковое?

Компилятор любит все приводить к int, например, это
Код:
(PORTC ^ KEYMASK) & KEYMASK

Если бы переменные были unsigned int, то результат таким бы и остался, но если размерность меньше, то будет int.

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

Чт май 18, 2017 22:36:09

Компилятор любит все приводить к int, например, это
Код:
(PORTC ^ KEYMASK) & KEYMASK
Вообще, странно. На каком бы вдруг основании, компилятору приводить это выражение к int. При том, что все части выражения - unsigned char.
Мало того, в левой части присваивания, тоже unsigned char.
:dont_know:

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

Чт май 18, 2017 23:23:43

main.c:767: warning: (373) implicit signed to unsigned conversion
Код:
  readkey = (PORTC ^ KEYMASK) & KEYMASK

Вышепомянутую ошибку выдаёт на вот эту, последнюю строчку.
Не могу понять, где еще тут что знаковое?

Разбейте строчку на две:
Код:
  int tmp = (PORTC KEYMASK) & KEYMASK;
readkey tmp

На вторую точно должен ругнуться, а вот ругнётся-ли на первую? Ещё в дизасм листинг можно глянуть какие деяния он с операндами сотворить пытается.

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

Пт май 19, 2017 06:05:07

Проблема явно в typedef enum {}. Потому как стоит эти маски задать просто через #define, как ошибки нет.
Код:
#define KEY_SET (1u<<6)
#define KEY_MODE (1u<<4)
#define KEY_RELEASE (1u<<1)
#define KEYMASK (KEY_SET | KEY_MODE)

Какой компилятор и проц ?
XC8 v1.42 pic16f723a

погуглил... понял, что в данном случае применять enum, действительно плохая идея:
1. Избегайте логических операций с константами enum, иначе могут появляться предупреждения несоответствия типа Warning[Pe188]. Причина в том, что операторы логики дают в результате своей работы целый тип, а не тот тип, который определен в typedef enum. Задавать битовый маски константами enum тоже плохая идея.

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

Пт июн 02, 2017 22:26:12

Доброго времени суток. Написал простой цикл типа "бегущий светодиод". Сперва одним вариантом, потом другим.
Код:
   while(1)
   {

      PORTE.OUT = ~led;
      _delay_ms(BLINK_DELAY_MS);
      led <<= 1;
      if (led == 0) led=0b00000001;
   }

   while(1)
   {
      for   (led = 0b00000001;led != 0;led <<= 1)
      {
         PORTE.OUT = ~led;
         _delay_ms(BLINK_DELAY_MS);
      }
   }

Оба работают одинаково :))) Где (в какой литературе) можно почитать, когда какие типы циклов использовать предпочтительнее ? И вообще про хорошие манеры кода на Си.
Просто нашел еще, что можно вообще написать конструкцию типа if (!(led <<= 1)) led=0b00000001; и оно блин работает... Только вот понять такую конструкцию, мой неокрепший мозг пока еще не готов. И поэтому собственно интересует, надо ли к таким конструкциям привыкать (тренировать мозги), или надо наоборот, раскидывать операторы построчно ?

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

Пт июн 02, 2017 23:09:29

Эта конструкция - ровно те же две последние строки первого варианта

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

Сб июн 03, 2017 06:34:58

Я понимаю. Я хочу знать, "правильно" ли так писать, или надо (желательно, принято и т.п) расписывать в 2 строки.

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

Пн июн 05, 2017 12:51:26

Если вам это понятно и вы не пишете руководство для новичков, то вполне нормально. Я и сам вечно начинающий в Си (и не только), но обычно объединяю подобные выражения (что-то вроде if (!(--cnt)) cnt = N).

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

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

Пн июн 05, 2017 12:58:17

Zhuk72 писал(а):Я и сам вечно начинающий в Си
и я :)
Пока_без_кота писал(а):Я хочу знать, "правильно" ли так писать, или надо (желательно, принято и т.п) расписывать в 2 строки
Моё мнение - чем проще, тем лучше. иногда принцип чуть меняется: чем ближе к сути происходящего, тем лучше.
но если хорошо подумать, оба варианта есть одно и то же.

бритва Оккама не подводит :)

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

Вт июн 13, 2017 15:22:08

Наверное люди делятся на две категории: одни понимают указатели, другие нет :))

Не так давно я об этом уже спрашивал, потом забросил, т.к. не до того было, сейчас перечитал, потом на других ресурсах почитал... Да, я все-таки из второй категории.

Имеется функция вывода текста на графический дисплей, к которому прилагается двухмерный массив констант размерностью 159*5 байт, содержащий символы:
Код:
const unsigned char  lcd_font[159][5] =
{
   0x00, 0x00, 0x00, 0x00, 0x00,  // sp - 0
   0x00, 0x00, 0x2f, 0x00, 0x00,  // ! - 1
   0x00, 0x07, 0x00, 0x07, 0x00,  // " - 2
   0x14, 0x7f, 0x14, 0x7f, 0x14,  // # - 3
   0x24, 0x2a, 0x7f, 0x2a, 0x12,  // $ - 4
и т.д.
}


Функция выглядит так:
Код:
void lcd_out (unsigned char row, unsigned char col, unsigned char *text)
{
  unsigned char ch, i;
  unsigned char *ptr;
 
  lcd_setxy(row,col*6);
  ptr = lcd_font;            // a value of type "const unsigned char (*)[5]" cannot be assigned to an entity of type "unsigned char *"
  while (*text != "\0")    // operand types are incompatible ("unsigned char" and "char *")
  {
    ch = *text;
    if ((ch >= 32) && (ch <= '~')) ch -= 32;
        else ch = 255;
    for (i = 0; i < 5 ; i++)
    {
      lcd_send(*(ptr+ch * 5 + i),DTA);
    }
    lcd_send(0,DTA);  // Additional space
    text++;
  }
}


Вызываю функцию так:
Код:
  lcd_out(1,3,"test\0");


Что я делаю неправильно?
Ошибки указаны выше, плюс есть еще предупреждение, касающееся вызова функции. Его я скопировать не могу, оно в виде подсказки вылезает, но говорится там о конвертации между указателем и целым с изменением знака :shock:

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

Вт июн 13, 2017 15:42:45

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

Кстати, "test\0" - ноль в конце лишний, текст в двойных кавычках всегда автоматически дополняется нулем.

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

Вт июн 13, 2017 15:54:38

Сейчас убегаю, дома постараюсь переварить.
Но я ведь именно массив хочу передать, чтобы он посимвольно вывел его на дисплей.

Про "\0" я в курсе, я это уже в добавил на всякий случай, мало ли что. Вдруг этот радикальный Кайл и это за ошибку считает.

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

Вт июн 13, 2017 16:23:03

Первая ошибка связана с тем, что вы пытаетесь присвоить неконстантному указателю значение константного. Это "по закону" запрещено, ибо таким образом появляется "дырка", позволяющая изменить константные данные.
А зачем Вам вообще нужен указатель ptr ?
Про вторую ошибку уже сказали - виноваты двойные кавычки. Символ обрамляется в одинарные.
Ну а проще написать так :
Код:
  while (*text)
  {
Этого будет достаточно.

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

Вт июн 13, 2017 20:49:49

Спасибо за подсказки.
Сделал так (точнее вернул на место)
Код:
  lcd_send(lcd_font[ch][i],DTA);
, но все-таки хотелось бы понять почему нельзя через указатель сделать то же самое.
Вычитал тут, правда по плюсам, что может быть const int *ptr и int *const ptr. Оба определения у меня проходят, но ptr = lcd_font все равно вызывает ошибку.
Да и ворнинг на вызове функции остался:
passing 'char [5]' to parameter of type 'unsigned char *' converts between pointers to integer types with different sign

, хотя все скомпилировалось.

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

Вт июн 13, 2017 20:55:14

Zhuk72 писал(а):Вычитал тут, правда по плюсам, что может быть const int *ptr и int *const ptr.
Один - указатель на константу int, другой - указатель-константа на int.
Т.е. , в одном случае нельзя менять данные по указателю, в другом - нельзя менять сам указатель, но данные по нему можно.
Если будет const int* const ptr, то это будет указатель-константа на константные данные. Т.б. нельзя будет изменять ни указатель, ни данные по нему.
Всё, что находится до символа "*", относится к данным, на которые указывает указатель. Всё, что после символа - к самому указателю.

Zhuk72 писал(а):но ptr = lcd_font все равно вызывает ошибку.
ptr должен быть указателем на такой же тип, с такими же квалификаторами, как и lcd_font.

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

Вт июн 13, 2017 21:01:28

Массив-то двумерный, а указатель - на одномерный.
Кстати, странно, что на саму инициализацию массива не ругается.
Ответить