Вопросы по С/С++ (СИ)
сбрасываются, только в другом таймере, я его вырезал из примера вместе с сбросом (не доглядел при упрощении кода), проблема уже решена, проблема была в плате, не допаял..
- Реклама
Здравствуйте, коты:)
пытаюсь освоить кейл и попутно блютуз микросхемку bluenrg.
компилирую пример от производителя - все ок.
когда попытался это дело перетащить в свой проект, кейл начал ругаться на нулевые размеры некоторых массивов:
typedef __packed struct _evt_le_meta_event{
uint8_t subevent;
uint8_t data[0]; // ругается сюда error: #94-D: the size of an array must be greater than zero
} PACKED evt_le_meta_event;
два вопроса к сообществу:
1. зачем вообще нужны нулевые массивы в структуре? как-то "застолбить" место?
2. как успокоить кейл и не поломать библиотечный код?
пытаюсь освоить кейл и попутно блютуз микросхемку bluenrg.
компилирую пример от производителя - все ок.
когда попытался это дело перетащить в свой проект, кейл начал ругаться на нулевые размеры некоторых массивов:
typedef __packed struct _evt_le_meta_event{
uint8_t subevent;
uint8_t data[0]; // ругается сюда error: #94-D: the size of an array must be greater than zero
} PACKED evt_le_meta_event;
два вопроса к сообществу:
1. зачем вообще нужны нулевые массивы в структуре? как-то "застолбить" место?
2. как успокоить кейл и не поломать библиотечный код?
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
--------------------------
Пишу на Си за еду
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Если один и тот же компилятор на идентичный код ругается в зависимости от проекта - то попробуйте сравнить настройки проектов из примера и вашего. Вероятно в части включения поддержки разных фич языка есть разница.slavokhire5 писал(а): компилирую пример от производителя - все ок.
когда попытался это дело перетащить в свой проект, кейл начал ругаться на нулевые размеры некоторых массивов:
[...]
2. как успокоить кейл и не поломать библиотечный код?
Возможно это структура есть заголовок данных нефиксированного (неизвестного) размера. Программа обращается к элементам массива data в зависимости от типа события subevent - зная что событие номер 1 тащит с собой десять байт - оперируем индексами 0-9, а событие номер 2 содержит сто байт - значит допустимо обращаться до 99-го индекса. Ну а sizeof такой структуры вернёт чистый размер заголовка - без данных.slavokhire5 писал(а):typedef __packed struct _evt_le_meta_event{
uint8_t subevent;
uint8_t data[0]; // ругается сюда error: #94-D: the size of an array must be greater than zero
} PACKED evt_le_meta_event;
два вопроса к сообществу:
1. зачем вообще нужны нулевые массивы в структуре? как-то "застолбить" место?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Здравствуйте коты:)
у меня вопрос по указателям (см. коменты в коде)
UPD1:и после выполнения строчки if (cc->opcode != opcode) я падаю в hard fault. если ее закоментить, то все хорошо. я так понимаю, это что-то с адресацией не так?
UPD2:поэкспериментировал с данными в dataBuff. допустим, он содержит значения 0x04, 0x0e, 0x04, 0x01, 0x0c, 0xfc, 0xaa.....
тогда в сс->opcode будет лежать 0xaafc, а в сс->ncmd будет 0x01. если сс->ncmd сделать типа uint16_t, то в сс->ncmd будет 0x0c01. т.е. байты меняет местами и почему-то отбрасывается 0x0c.
вся проблема в том, что я ковыряю примеры bluetooth от stm. перетаскиваю их с stm32l053 на stm32f030. теоретически в библиотеке должно быть все правильно, значит где-то косячу я.
у меня вопрос по указателям (см. коменты в коде)
Код: Выделить всё
....
typedef __packed struct _evt_cmd_complete{
uint8_t ncmd;
uint16_t opcode;
} PACKED evt_cmd_complete;
.....
int hci_send_req(struct hci_request *r, BOOL async)
{
...
uint8_t *ptr;
evt_cmd_complete *cc;
......
ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); // HCI_EVENT_HDR_SIZE == 2
// dataBuff типа uint8_t. в нем лежат значения 0x04, 0x0e, 0x04, 0x01, 0x0c, 0xfc.....
// в результате *ptr = 0x01
......
cc = (void *) ptr; // сс->ncmd = 0x01, cc->opcode == 0x00FC, хотя по логике должен быть равен 0x0CFC. что неправильно?
....
}
UPD2:поэкспериментировал с данными в dataBuff. допустим, он содержит значения 0x04, 0x0e, 0x04, 0x01, 0x0c, 0xfc, 0xaa.....
тогда в сс->opcode будет лежать 0xaafc, а в сс->ncmd будет 0x01. если сс->ncmd сделать типа uint16_t, то в сс->ncmd будет 0x0c01. т.е. байты меняет местами и почему-то отбрасывается 0x0c.
вся проблема в том, что я ковыряю примеры bluetooth от stm. перетаскиваю их с stm32l053 на stm32f030. теоретически в библиотеке должно быть все правильно, значит где-то косячу я.
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
--------------------------
Пишу на Си за еду
- Сообщения: 291
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
Твой целовой MCU умеет обращаться по невыровненным данным? Конкретно с твоим MCU не разбирался, но не все "умеют" обращаться к невыровненным данным. С этим связаны и другие, описываемые проблемы.slavokhire5 писал(а):после выполнения строчки if (cc->opcode != opcode) я падаю в hard fault.
Например, посмотри sizeof () твоей структуры, думаю, будешь удивлен.
- Реклама
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Похоже компилятор проигнорировал просьбу упаковать структуру. Байты меняются местами потому что платформа Little Endian.slavokhire5 писал(а): у меня вопрос по указателям (см. коменты в коде)поэкспериментировал с данными в dataBuff. допустим, он содержит значения 0x04, 0x0e, 0x04, 0x01, 0x0c, 0xfc, 0xaa.....Код: Выделить всё
.... typedef __packed struct _evt_cmd_complete{ uint8_t ncmd; uint16_t opcode; } PACKED evt_cmd_complete; .....
тогда в сс->opcode будет лежать 0xaafc, а в сс->ncmd будет 0x01. если сс->ncmd сделать типа uint16_t, то в сс->ncmd будет 0x0c01. т.е. байты меняет местами и почему-то отбрасывается 0x0c.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 23
- Зарегистрирован: Пт окт 17, 2014 12:42:38
Доброго времени суток. Есть маленькая задачка,только или я дурак или лыжи не едут. Выход -это обычный быстрый шим. На входе есть переменный резистор,установлен в среднее положение на входе шима нет. При вращении резистора от среднего положения вправо или влево у нас должен увеличиваться шим до максимально значения. Считываем 8 бит ацп и загоняем в OCR предварительно отняв 125 едениц ,то мы получаем в каждую сторону 125 шагов,что будет вялятся примерно половина заполнения шим,потом умножаем на 2. Ну и принципе на выходе мы имеем ,если резистор крутить от среднего положения в право ,на выходе будет менятся шим от 0-255. А теперь вопрос ,как сделать чтобы от середины резистора при вращении влево тоже менялся шим от 0 до 255 ? Ну принципе из куска понятно ,что это управление реверсом моторчика одним резистором со средним положением.
Спасибо
if (ReadADC(3)>130) // ход в перед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<2); // включить другую диагональ моста
speed = (ReadADC(3)-125)*2;
OCR2B=speed;
}
Спасибо
if (ReadADC(3)>130) // ход в перед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<2); // включить другую диагональ моста
speed = (ReadADC(3)-125)*2;
OCR2B=speed;
}
я так понимаю, просто надо так: speed = abs(ReadADC(3)-125)*2;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 23
- Зарегистрирован: Пт окт 17, 2014 12:42:38
Судя по всему нет,это не то. Выше я код написал ,для случая если резистор крутить от середины в право , а как сделать когда крутишь от середины влево ? Я понимаю что надо что то про инвертировать ,ARV писал(а):я так понимаю, просто надо так: speed = abs(ReadADC(3)-125)*2;
но что-то не догоняю как...
то, что я порекомендовал, вы проверили? или просто обдумали?
насколько я понял, сам реверс вы делаете переключением плеч полумоста, а ШИМ просто задает "амплитуду". так вот, в вашем коде добавка функции abs даст ситуацию, когда в среднем положении резистора будет выдаваться 0, а по мере сдвига к краям - положительные значения в пределах примерно от 0 до 250, т.е. амплитуда будет плавно нарастать.
насколько я понял, сам реверс вы делаете переключением плеч полумоста, а ШИМ просто задает "амплитуду". так вот, в вашем коде добавка функции abs даст ситуацию, когда в среднем положении резистора будет выдаваться 0, а по мере сдвига к краям - положительные значения в пределах примерно от 0 до 250, т.е. амплитуда будет плавно нарастать.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Причём этот ноль надо будет ловить с точностью в 1/256ARV писал(а):в среднем положении резистора будет выдаваться 0
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Сообщения: 23
- Зарегистрирован: Пт окт 17, 2014 12:42:38
Я правильно понял ,что это как то так ?
if (ReadADC(3)>133) // ход в перед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<2); // включить другую диагональ моста
speed = ((ReadADC(3)-122)*2)+11;
OCR2B=speed;
}
if ((ReadADC(3)>120)&&(ReadADC(3)<133))
{
OCR2B=0;
}
if (ReadADC(3)<120) // ход назад
{
PORTD &=~(1<<2); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<1); // включить другую диагональ моста
speed = abs((ReadADC(3)-122)*2)+11;
OCR2B=speed;
}
То что шим будет не с нуля ,принципе не имеет значения...
Или есть более красивое решение ? ПС Сильно не пинайте ,только учу СИ.
if (ReadADC(3)>133) // ход в перед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<2); // включить другую диагональ моста
speed = ((ReadADC(3)-122)*2)+11;
OCR2B=speed;
}
if ((ReadADC(3)>120)&&(ReadADC(3)<133))
{
OCR2B=0;
}
if (ReadADC(3)<120) // ход назад
{
PORTD &=~(1<<2); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<1); // включить другую диагональ моста
speed = abs((ReadADC(3)-122)*2)+11;
OCR2B=speed;
}
То что шим будет не с нуля ,принципе не имеет значения...
Или есть более красивое решение ? ПС Сильно не пинайте ,только учу СИ.
вот так будет понятнее?
вообще говоря, задержки при переключениях диагоналей - это глупость: приведет к искажению ШИМа. правильный алгоритм должен быть чуток иной:
1. определяем "зону нуля" - значение АЦП, которое соответствует остановленному состоянию
2. измерили АЦП
3. проверили, вошли в зону нуля или нет
4. если в зоне - выключили ШИМ
5. если вне зоны, то надо сравнить знак этого результата АЦП с предыдущим результатом
6. если знаки совпадают, то перейти к п.8
7. если знаки разные, то для положительного значения текущего значения АЦП включить одну диагональ, для отрицательного - другую
8. задать скорость по абсолютному значению АЦП.
9. запомнить знак результата АЦП для следующей итерации
10. повторять в цикле с п.2
Код: Выделить всё
int adc = 2*(ReadADC(3) - 125);
if(adc < 0) { // назад
PORTD &=~(1<<2); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<1); // включить другую диагональ моста
} else { // вперед
PORTD &=~(1<<1); // выключить одну диагональ моста
_delay_ms(1); // пауза
PORTD|=(1<<2); // включить другую диагональ моста
}
OCR2B= abs(adc);1. определяем "зону нуля" - значение АЦП, которое соответствует остановленному состоянию
2. измерили АЦП
3. проверили, вошли в зону нуля или нет
4. если в зоне - выключили ШИМ
5. если вне зоны, то надо сравнить знак этого результата АЦП с предыдущим результатом
6. если знаки совпадают, то перейти к п.8
7. если знаки разные, то для положительного значения текущего значения АЦП включить одну диагональ, для отрицательного - другую
8. задать скорость по абсолютному значению АЦП.
9. запомнить знак результата АЦП для следующей итерации
10. повторять в цикле с п.2
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 23
- Зарегистрирован: Пт окт 17, 2014 12:42:38
- Сообщения: 23
- Зарегистрирован: Пт окт 17, 2014 12:42:38
В связи с похоронами родного человека,немного было не до проекта...
Набросал код,пока не проверял,можно ли упростить или как-то более правильнее написать алгоритм ? Допусти имея мертвую зону в диапазоне 120-134 ацп, 0-120 перевести от 0 ,до 255 ?
Так как стиль у меня больше наверное не сишный ,а для промышленных контроллеров. Более 15 лет программирования разных промышленных контроллеров,а там язык отличается...
И еще ругается на ABS компилятор.
Warning 1 implicit declaration of function 'abs' [-Wimplicit-function-declaration]
Может что подключить надо ?
//--------------------------------ручной режим---------------------------------------------------
void manual()
{
PORTC &=~(1<<0); //выключить поворот
PORTD &=~(1<<6); //тоже
PORTD &=~(1<<5); //тоже
if (((ReadADC(3))>122)&&(ReadADC(3)<132)) //среднее положение ручки
{
OCR2B=0; // выключить шим
TCCR2A=0x00; // тоже
PORTD &=~(1<<1); // отключаем мост
PORTD &=~(1<<2); // тоже
}
else
{
int adc = 2*(ReadADC(3) - 135);
if(adc < 0) // назад
{
PORTD &=~(1<<2); // выключить одну диагональ моста
PORTD|=(1<<1); // включить другую диагональ моста
}
else // вперед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
PORTD|=(1<<2); // включить другую диагональ моста
}
OCR2B = abs(adc);
}
Набросал код,пока не проверял,можно ли упростить или как-то более правильнее написать алгоритм ? Допусти имея мертвую зону в диапазоне 120-134 ацп, 0-120 перевести от 0 ,до 255 ?
Так как стиль у меня больше наверное не сишный ,а для промышленных контроллеров. Более 15 лет программирования разных промышленных контроллеров,а там язык отличается...
И еще ругается на ABS компилятор.
Warning 1 implicit declaration of function 'abs' [-Wimplicit-function-declaration]
Может что подключить надо ?
//--------------------------------ручной режим---------------------------------------------------
void manual()
{
PORTC &=~(1<<0); //выключить поворот
PORTD &=~(1<<6); //тоже
PORTD &=~(1<<5); //тоже
if (((ReadADC(3))>122)&&(ReadADC(3)<132)) //среднее положение ручки
{
OCR2B=0; // выключить шим
TCCR2A=0x00; // тоже
PORTD &=~(1<<1); // отключаем мост
PORTD &=~(1<<2); // тоже
}
else
{
int adc = 2*(ReadADC(3) - 135);
if(adc < 0) // назад
{
PORTD &=~(1<<2); // выключить одну диагональ моста
PORTD|=(1<<1); // включить другую диагональ моста
}
else // вперед
{
PORTD &=~(1<<1); // выключить одну диагональ моста
PORTD|=(1<<2); // включить другую диагональ моста
}
OCR2B = abs(adc);
}
подключить math.h или определить abs самостоятельно:
#define abs(x) ((x) < 0 ? -(x) : (x))
что касается упрощения алгоритма, то достаточно 1 раз обратиться к чтению АЦП, а не трижды.
#define abs(x) ((x) < 0 ? -(x) : (x))
что касается упрощения алгоритма, то достаточно 1 раз обратиться к чтению АЦП, а не трижды.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
попросили сделать бутафорскую режиссерскую хлопушку та что с бегущими красными циферками)
суть какая когда "рычажок"(кнопка не нажата)) хлопушки поднят в индикаторах хаотично бегают цифры когда рычажок опущен(кнопка нажата) на индикаторе показывается номер дубля и после поднятия опускания дубль прибавляется, но!! пока рычажок опущен то номер дубля показывается на индикаторе.
что получилось у меня: рычажок поднят цифры бегают, закрываю хлопушку подсказывает дубль 1, поднимаю цифры бегают - опускаю дубль 2 и т.д, если держать хлопушку закрытой то дубли сами с интервалом в 1 секунду прибавляются(через задержку), реализовал в двух циклах, первый проверяет нажатие кнопки,если кнопка не нажата циферки бегают, кнопка нажата срабатывает брейк (вываливается из цикла) и переходит во второй цикл тоже проверяет кнопку если нажата то происходит вывод номера дубля с задержкой и пока кнопка нажата естественно дубли сами прибавляются только хлопушку открыть срабатывает брейк и переходит на бегающие цифры . все это безобразие происходит в общем цикле.
вопрос как остановить прибавление дублей пока кнопка нажата не могу сообразить как реализовать этот алгоритм?
контроллер Мега32 , 8 индикаторов.
суть какая когда "рычажок"(кнопка не нажата)) хлопушки поднят в индикаторах хаотично бегают цифры когда рычажок опущен(кнопка нажата) на индикаторе показывается номер дубля и после поднятия опускания дубль прибавляется, но!! пока рычажок опущен то номер дубля показывается на индикаторе.
что получилось у меня: рычажок поднят цифры бегают, закрываю хлопушку подсказывает дубль 1, поднимаю цифры бегают - опускаю дубль 2 и т.д, если держать хлопушку закрытой то дубли сами с интервалом в 1 секунду прибавляются(через задержку), реализовал в двух циклах, первый проверяет нажатие кнопки,если кнопка не нажата циферки бегают, кнопка нажата срабатывает брейк (вываливается из цикла) и переходит во второй цикл тоже проверяет кнопку если нажата то происходит вывод номера дубля с задержкой и пока кнопка нажата естественно дубли сами прибавляются только хлопушку открыть срабатывает брейк и переходит на бегающие цифры . все это безобразие происходит в общем цикле.
вопрос как остановить прибавление дублей пока кнопка нажата не могу сообразить как реализовать этот алгоритм?
контроллер Мега32 , 8 индикаторов.
сделайте изменение счетчика не во втором цикле, а между двумя циклами
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
с этим разобрался. Спасибо.ARV писал(а):сделайте изменение счетчика не во втором цикле, а между двумя циклами
теперь вопрос про прерывания, надо выключать с кнопки без фиксации: настроил так
Код: Выделить всё
volatile unsigned char sleepEnabled = 0;
ISR(INT2_vect)
{
if (sleepEnabled == 0)
{
sleepEnabled = 1;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
sleep_mode();
cli();
}
sleepEnabled = 0;
}работает но нестабильно, много повторных нажатий, кнопка подтянута через резистор, внутренний резистор тоже включен.
Нужно ли в теле программы разрешать прерывания( без разрешения работает).
если нужен код целиком то вечером скину.
- Сообщения: 369
- Зарегистрирован: Пт фев 01, 2013 21:05:30
Как сравнивать массивы указателей разных типов?
Работает, но с предупреждением.
Код: Выделить всё
uint8_t * Buf;
...
if(Buf=="String\r"){Код: Выделить всё
..\Src\usbd_cdc_if.c(45): warning: #42-D: operand types are incompatible ("char *" and "uint8_t *")


