Вопросы по С/С++ (СИ)
ARV, не здесь, пожалуйста. Идите в "МЯЯЯУ!". К языку религиозные вопросы использования или не использования существующего в нем оператора никакого отношения не имеют.
- Реклама
ну, я ж не первый начал
всё-всё, не буду больше 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3693189#p3693189"]Billi34, обычный goto работает только в рамках одной функции. Если есть нужна goto в другую функцию, используйте setjmp()/longjmp()[/uquote]
принял к сведению. Почитаю обучалки. Мне не очень нравится как код работает. Всречаются не верные переходы. И как раз с goto/
принял к сведению. Почитаю обучалки. Мне не очень нравится как код работает. Всречаются не верные переходы. И как раз с goto/
- Сообщения: 791
- Зарегистрирован: Вт июн 17, 2014 00:34:26
Добрый день, подскажите пожалуйста, что делаю не так.
Стараюсь запустить usb, но этот код работает не правильно.
Код:
Вторая строчка кода перезаписывает первую, а 4 перезаписывает третью. То есть если отслеживать состояние вкладки мемори, то видно как значения перезаписывают друг друга. Выравнивание структуры отключил и sizeof(USB_EPDATA_TypeDef) дает правильный результат. Работаю в Keil.
Код:
Код:
Еще не понятно, почему sizeof(ep_t) = 12.
Стараюсь запустить 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; //размер приемного буфераКод:
Код: Выделить всё
#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.
это как раз понятно: 2 указателя это 8 байт, еще два байта на uint16_t, и еще 2 байта на битоадресуемые поля (всего 13 бит). Итого 12 байт.baghear писал(а):Еще не понятно, почему sizeof(ep_t) = 12.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Сообщения: 791
- Зарегистрирован: Вт июн 17, 2014 00:34:26
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="baghear",url="/forum/viewtopic.php?p=3694413#p3694413"]Спасибо, Это понял. А что скажете по первой части вопроса?[/uquote]Контроллер F103? У него доступ в PAM только 32-битный. Подробнее вечером.
ЗЫ: Поля структуры USB_EPDATA_TypeDef сделай uint32_t для начала. Ну и вообще, PAM у него "дырявая".
ЗЫ: Поля структуры USB_EPDATA_TypeDef сделай uint32_t для начала. Ну и вообще, PAM у него "дырявая".
Последний раз редактировалось VladislavS Ср сен 04, 2019 13:33:06, всего редактировалось 1 раз.
- Сообщения: 791
- Зарегистрирован: Вт июн 17, 2014 00:34:26
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="baghear",url="/forum/viewtopic.php?p=3694424#p3694424"]Да 103VE.[/uquote]Через пару часиков скину функцию записи в PAM.
Для F103
Для 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
Подскажите в чем смысл сдвига влево на один бит?
И почему RAM дырявая?
Код: Выделить всё
int32_t *pv = (uint32_t *)(USB_PMAADDR + (ep_buf_dscr[EPNum].ADDR_TX<<1)); - Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[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). Причём, отличие внутри групп именно в организации этого долбаного буфера.
[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
И снова здравствуйте. Наставьте на путь истинный.
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 величины абстрактные что б внутреннее условие достигло своего значения до окончания цикла.
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 раза.
Billi34, это не скомпилиться. Лексема else применятся только с if, но уж никак не с while.
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Понял ошибку. Суть от этого не меняется. Перефразирую: МК перейдет к этой строке в которой написан оператор else.
Поправил в предидущем посте.
Поправил в предидущем посте.
Не так. Если i не меньше 18, то сначала t сбрасывается в 0, а затем управление передается на метку mesto_1. А вот где эта метка - мне не ведомо. Внутри цикла ее нет, значит она где-то за пределами цикла и поэтому происходит выход из цикла.Billi34 писал(а): По превышению i более 18 МК переходит в mesto_1. сбрасевает t в ноль.
Опять не так. В случае, если любое из трех логических выражений в while окажется ложным, произойдет выход из цикла и вполнение "следующая строка кода". То есть, выход из цикла произойдет ИЛИ если PIND.B1=0 ИЛИ если i>=20 ИЛИ если t=0Billi34 писал(а):В случае возникновения ПИН В1 лог. единицы при значениях i меньше 18 МК переходит к оператору else
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Не меньше значит больше? По сути если 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
Добавлено 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
Billi34, дорогой, переходи на светлую сторону. Не надо придумывать алгоритмы, которые не понимает как работает даже автор. Во-первых, забудь оператор goto. Поверь, это не больно. Во-вторых, оформляй функционально законченные фрагменты в виде функций с локализацией всех необходимых для её работы данных/переменных внутри. В-третьих, делай простые циклы с понятными условиями их окончания. Простой и понятный код с большей вероятностью работает правильно. Поднаберёшься опыту - будешь применять продвинутые техники, благо в С, а там глядишь и С++ есть куда двигаться.
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Ну почему же не понимаю, все очень даже понимаю. И по строкам разложил. А без goto как выскочить из цикла? И в начало цепочки событий?
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
А не надо никуда "выскакивать". Перестрой алгоритм по другому. Вот у тебя есть "цепочка событий". Сколько раз она должна выполниться? Напиши цикл который выполняет эту цепочку событий нужное количество раз. А потом будешь внутри цикла писать саму "цепочку".
Billi34, приведите весь код, тогда покажу, как можно сделать без goto. Только вставляйте его, как Code (кнопочка такая), а не прямо в текст сообщения.


