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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

ARV, не здесь, пожалуйста. Идите в "МЯЯЯУ!". К языку религиозные вопросы использования или не использования существующего в нем оператора никакого отношения не имеют.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3693189#p3693189"]Billi34, обычный goto работает только в рамках одной функции. Если есть нужна goto в другую функцию, используйте setjmp()/longjmp()[/uquote]
принял к сведению. Почитаю обучалки. Мне не очень нравится как код работает. Всречаются не верные переходы. И как раз с goto/
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Добрый день, подскажите пожалуйста, что делаю не так.
Стараюсь запустить usb, но этот код работает не правильно.
Код:

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

USB_BTABLE -> EP[number].USB_ADDR_TX = addr_tx;
USB_BTABLE -> EP[number].USB_COUNT_TX = 1;
USB_BTABLE -> EP[number].USB_ADDR_RX = addr_rx;
USB_BTABLE -> EP[number].USB_COUNT_RX = 0x8400;   //размер приемного буфера
Вторая строчка кода перезаписывает первую, а 4 перезаписывает третью. То есть если отслеживать состояние вкладки мемори, то видно как значения перезаписывают друг друга. Выравнивание структуры отключил и sizeof(USB_EPDATA_TypeDef) дает правильный результат. Работаю в Keil.
Код:

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

#define USB                  ((USB_TypeDef *) (0x40005C00))
#define USB_BTABLE_BASE         0x40006000
#define USB_BTABLE               ((USB_BtableDef *)(USB_BTABLE_BASE))

typedef struct{
   __IO uint32_t EPnR[8];
   __IO uint32_t RESERVED1;
   __IO uint32_t RESERVED2;
   __IO uint32_t RESERVED3;
   __IO uint32_t RESERVED4;
   __IO uint32_t RESERVED5;
   __IO uint32_t RESERVED6;
   __IO uint32_t RESERVED7;
   __IO uint32_t RESERVED8;
   __IO uint32_t CNTR;
   __IO uint32_t ISTR;
   __IO uint32_t FNR;
   __IO uint32_t DADDR;
   __IO uint32_t BTABLE;
   //__IO uint32_t LPMCSR;
   //__IO uint32_t BCDR;
} USB_TypeDef;
#pragma pack(2)
typedef struct{
   __IO uint16_t USB_ADDR_TX;
   __IO uint16_t USB_COUNT_TX;
   __IO uint16_t USB_ADDR_RX;
   __IO uint16_t USB_COUNT_RX;
} USB_EPDATA_TypeDef;

typedef struct{
   __IO USB_EPDATA_TypeDef EP[8];
} USB_BtableDef;
#pragma pack()

Код:

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

#pragma pack(1)
//Тип для расшифровки конфигурационного пакета
typedef struct {
   uint8_t bmRequestType;
   uint8_t bRequest;
   uint16_t wValue;
   uint16_t wIndex;
   uint16_t wLength;
} config_pack_t;
//Структура состояний конечных точек
typedef struct {
   uint16_t *tx_buf;
   uint8_t *rx_buf;
   uint16_t status;
   unsigned rx_cnt : 10;
   unsigned tx_flag : 1;
   unsigned rx_flag : 1;
   unsigned setup_flag : 1;
} ep_t;
//Статус и адрес соединения USB
typedef struct {
   uint8_t USB_Status;
   uint16_t USB_Addr;
} usb_dev_t;
#pragma pack()

Еще не понятно, почему sizeof(ep_t) = 12.
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

baghear писал(а):Еще не понятно, почему sizeof(ep_t) = 12.
это как раз понятно: 2 указателя это 8 байт, еще два байта на uint16_t, и еще 2 байта на битоадресуемые поля (всего 13 бит). Итого 12 байт.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Спасибо, Это понял. А что скажете по первой части вопроса?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="baghear",url="/forum/viewtopic.php?p=3694413#p3694413"]Спасибо, Это понял. А что скажете по первой части вопроса?[/uquote]Контроллер F103? У него доступ в PAM только 32-битный. Подробнее вечером.

ЗЫ: Поля структуры USB_EPDATA_TypeDef сделай uint32_t для начала. Ну и вообще, PAM у него "дырявая".
Последний раз редактировалось VladislavS Ср сен 04, 2019 13:33:06, всего редактировалось 1 раз.
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Да 103VE.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="baghear",url="/forum/viewtopic.php?p=3694424#p3694424"]Да 103VE.[/uquote]Через пару часиков скину функцию записи в PAM.

Для F103

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

typedef struct {
  uint32_t ADDR_TX;
  uint32_t COUNT_TX;
  uint32_t ADDR_RX;
  uint32_t COUNT_RX;
} EP_BUF_DSCR;


void WritePAM_TX(uint32_t EPNum, uint8_t *pSrcData, uint32_t cnt)
{
  uint32_t *pv = (uint32_t *)(USB_PMAADDR + (ep_buf_dscr[EPNum].ADDR_TX<<1));  
  for(uint32_t n = 0; n < (cnt + 1) / 2; n++, pSrcData += 2) 
  {
    *pv++ = *((uint16_t *)pSrcData);
  }
  ep_buf_dscr[EPNum].COUNT_TX = cnt;
  EP_Status(EPNum, USB_EP_TX_VALID);  
}
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Подскажите в чем смысл сдвига влево на один бит?

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

int32_t *pv = (uint32_t *)(USB_PMAADDR + (ep_buf_dscr[EPNum].ADDR_TX<<1)); 
И почему RAM дырявая?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="baghear",url="/forum/viewtopic.php?p=3694827#p3694827"]Подскажите в чем смысл сдвига влево на один бит?[/uquote]Ровно потому же, почему инкремент указателя на 32-ю память pv при записи каждых двух бай увеличивает его значение на 4. А указатель буфера-источника на два. USB-память устроена из 32-битных слов, старшие два байта которых пустые. Пощупай это под отладчиком, это хорошо видно, куда и как приходят пакеты. Соответственно и отправлять их надо так же.

[uquote="baghear",url="/forum/viewtopic.php?p=3694827#p3694827"]И почему RAM дырявая?[/uquote]Перенаправлю этот вопрос STM. И от себя дополню вопросом почему они это в RM толком не написали.

Это всё F103 касается, у других контроллеров другие заморочки. И с организацией буфера, и с невыровненым доступом. У меня из-за этого уже целый зоопарк реализаций USB: два для OTG (F107, F411) и три для обычного (F0 и L0, F103, F303). Причём, отличие внутри групп именно в организации этого долбаного буфера.
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

И снова здравствуйте. Наставьте на путь истинный.

t=1;i=0;
while(!PIND.B1&&i<20&&t)
{
if(i<18)
{
t=0 ;
goto mesto_1;
}
Delay_ms(100) ;i++;
}
следующая строка кода


Интересует как в данном случае работает МК в условиях цикла : пока на пин В1 ноль, переменная i меньше 20 и переменная t лог. единица. МК не выходит из цикла. По превышению i более 18 МК переходит в mesto_1. сбрасевает t в ноль. В случае возникновения ПИН В1 лог. единицы при значениях i меньше 18 МК переходит к оператору else.Так я думаю. 20 и 18 величины абстрактные что б внутреннее условие достигло своего значения до окончания цикла.
Последний раз редактировалось Billi34 Пт сен 06, 2019 15:12:59, всего редактировалось 2 раза.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Billi34, это не скомпилиться. Лексема else применятся только с if, но уж никак не с while.
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

Понял ошибку. Суть от этого не меняется. Перефразирую: МК перейдет к этой строке в которой написан оператор else.


Поправил в предидущем посте.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Billi34 писал(а): По превышению i более 18 МК переходит в mesto_1. сбрасевает t в ноль.
Не так. Если i не меньше 18, то сначала t сбрасывается в 0, а затем управление передается на метку mesto_1. А вот где эта метка - мне не ведомо. Внутри цикла ее нет, значит она где-то за пределами цикла и поэтому происходит выход из цикла.
Billi34 писал(а):В случае возникновения ПИН В1 лог. единицы при значениях i меньше 18 МК переходит к оператору else
Опять не так. В случае, если любое из трех логических выражений в while окажется ложным, произойдет выход из цикла и вполнение "следующая строка кода". То есть, выход из цикла произойдет ИЛИ если PIND.B1=0 ИЛИ если i>=20 ИЛИ если t=0
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

Не меньше значит больше? По сути если i равно 10 МК переходит к строке: Delay 100; i++; и далее снова к while?

Добавлено after 2 minutes 14 seconds:
Разумеется mesto_1 расположено выше по тексту кода и МК благополучно туда "выпрыгивает" только условия не выполняются.
Или криво выполняются.

Добавлено after 7 minutes 48 seconds:
Опять не так. В случае, если любое из трех логических выражений в while окажется ложным, произойдет выход из цикла и вполнение "следующая строка кода". То есть, выход из цикла произойдет ИЛИ если PIND.B1=0 ИЛИ если i>=20 ИЛИ если t=0

А вот здесь пожалуйста по подробней: PIND.B1=0 или 1 ?

Добавлено after 3 minutes 16 seconds:
t не меняется по условиям цикла. Только для выхода. i "считается" 2 сек. Остаётся только ПИН В1 и мне надо чтоб с приходом 1 МК перешел к "следующая строка кода"

Добавлено after 2 minutes 26 seconds:
Не так он(код) работает в железе. И с приходом 0 и 1 МК перепрыгивает на mesto_1
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Billi34, дорогой, переходи на светлую сторону. Не надо придумывать алгоритмы, которые не понимает как работает даже автор. Во-первых, забудь оператор goto. Поверь, это не больно. Во-вторых, оформляй функционально законченные фрагменты в виде функций с локализацией всех необходимых для её работы данных/переменных внутри. В-третьих, делай простые циклы с понятными условиями их окончания. Простой и понятный код с большей вероятностью работает правильно. Поднаберёшься опыту - будешь применять продвинутые техники, благо в С, а там глядишь и С++ есть куда двигаться.
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

Ну почему же не понимаю, все очень даже понимаю. И по строкам разложил. А без goto как выскочить из цикла? И в начало цепочки событий?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

А не надо никуда "выскакивать". Перестрой алгоритм по другому. Вот у тебя есть "цепочка событий". Сколько раз она должна выполниться? Напиши цикл который выполняет эту цепочку событий нужное количество раз. А потом будешь внутри цикла писать саму "цепочку".
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Billi34, приведите весь код, тогда покажу, как можно сделать без goto. Только вставляйте его, как Code (кнопочка такая), а не прямо в текст сообщения.
Ответить

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