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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

Аlex писал(а):
HHIMERA писал(а):Очень смелое заявление... :))
А что, я не прав ? :))

ПисАли не дураки... а пользователи разные бывают... бывает по ошибке, бывает по недопониманию или незнанию...
Ограничения и нюансы то присутствуют...
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
phanis
Вымогатель припоя
Сообщения: 513
Зарегистрирован: Сб фев 19, 2011 18:04:08
Откуда: Татарстан, пос. Актюбинский
Контактная информация:

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

Сообщение phanis »

Не знаю на сколько я правильно ставлю вопрос, но он таков:
Можно ли как нибудить сделать такой союз структуры и массива чтобы при фомировании ответа на запрос (например модбаса но не обязательно) от МК элемент Data был переменной длинны, но при этом элемент СRC был всегда в конце ответа,ну т.е. сам ответ тоже переменной длинны ?
Что типа этого.

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

union{
unsigned char Buffer[100];
struct{
unsigned char Addr;
unsigned char Command;
unsigned char *Data;//элемент переменный длинны
unsigned int *CRC16;
};
}PAKET;
Реклама
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Ну для начала длина с одной буквой н пишется.
А чтобы даже передать массив разной длины нужно обозначить ее самую эту длину.
В поисках истины человек развивается.
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

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

Сообщение Goldsmith »

phanis писал(а):Можно ли как нибудить сделать такой союз структуры и массива чтобы при фомировании ответа на запрос (например модбаса но не обязательно) от МК элемент Data был переменной длинны, но при этом элемент СRC был всегда в конце ответа,ну т.е. сам ответ тоже переменной длинны ?
Если я правильно понял вопрос, Вас интересует структура вроде [заголовок пакета][тело пакета переменной длины][CRC]?

В соответствии со стандартом C99 (§6.7.2.1 п. 16):
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.
"Гибкий" массив (т.е. массив, размер которого неизвестен во время компиляции) обязан быть последним членом структуры, добавить после него CRC не получится. Вам придется самостоятельно выудить значение CRC как 2 (или 4, или какую Вы там длину CRC используете) последних байта этого массива. Компилятор тут не помощник, он обязан знать смещение каждого члена структуры во время компиляции.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Реклама
Эиком - электронные компоненты и радиодетали
Davydov
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт авг 16, 2012 21:34:24

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

Сообщение Davydov »

Доброго всем времени суток!
Помогите пожалуйста прояснить, как грамотнее сделать:
На INT0 приходил лог. 1, срабатывает прерывание, внутри прерывания АЦП преобразует значение и далее над ним производятся некие операции:

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

interrupt [2] void INT_0(void) //Обработка прерывания
{
 delay_us(10);
 ADCSRA = (1 << ADSC);
 while ((ADCSRA&(1 << ADIF))== 0);
 GET_ADC = (ADCL|ADCH << 8);
...

...операции над значением...

...
}       
Заранее благодарен за ответ :beer:
Если бы это было так, это бы еще ничего. Если бы ничего, то так бы оно и было. Но так как это не так, так оно и не эдак. Такова логика вещей. (с)
Реклама
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Для начала не нужно в прерывании ждать пока появится результат ацп, можно сделать запуск ацп, а потом в прерывании ацп считать значение, и если вычисления на связаны с делением или выводом на экран, то можно их сделать тут.
А вот это совсем тут не нужно.

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

delay_us(10);
В поисках истины человек развивается.
Реклама
Davydov
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт авг 16, 2012 21:34:24

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

Сообщение Davydov »

vitalik_1984 писал(а):Для начала не нужно в прерывании ждать пока появится результат ацп, можно сделать запуск ацп, а потом в прерывании ацп считать значение

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

delay_us(10);

Просто тут такая штука, что напряжение на АЦП появляется вместе с прерыванием INT0. Тогда у меня ещё вопрос, а как тогда лучше сконфигурировать запуск АЦП? Непрерывное преобразование или по внешнему прерыванию INT0, а если по INT0 тот как он себя поведёт? МК - mega8
Если бы это было так, это бы еще ничего. Если бы ничего, то так бы оно и было. Но так как это не так, так оно и не эдак. Такова логика вещей. (с)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Так и делайте

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


iinterrupt 
[EXT_INT0void ext_int0_isr(void)
{
 ADCSRA = (<< ADSC);
}
 
 

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


unsigned int adc_data
;
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
} 
void main
(void)
{...........
..............
while(
1){
if(
adc_data){
//.........вычисления........
adc_data=0;
}
 
Аватара пользователя
eess9
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

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

Сообщение eess9 »

Привет всем!
Вопрос следующий. Есть кусок кода который принимает команды от RC5 пульта. Игнорируется все кроме команды (последние 5 бит). Далее эта переменная (command) по USART передается на комп. Код USART рабочий, принимал с компа данные и посылал их обратно; прием и передача работает. Но на комп приходят постоянно ноли от RC5. Следовательно бок в куске обработки сигнала с пульта. Внешнее прерывание настроено на любое изменение уровня сигнала от TSOP.
Спойлер

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

EMPTY_INTERRUPT(BADISR_vect)
 
#define Tmin 40
#define Tmax 68 
#define TminK 22
#define TmaxK 34

uint8_t i = 0,j=0;
unsigned char sct_bit = 0;     
unsigned char RC5_buffer;
uint8_t centre =  0;             
uint8_t not_korr = 0;             
unsigned char Timer = 0;           
unsigned char command = 0;   

void rc5_ti_stop(void)
{       
      GIMSK|=0x00;
      TCCR0B = 0x00;
      TCNT0 = 0;
      sct_bit = 0;
}

ISR(INT0_vect)
{
   Timer = TCNT0;   
   TCNT0 = 0;     
   not_korr = 1;                         
   if(sct_bit==0)
   {
      //PORTD^=(1<<PD4);
        TCCR0B = 0x04;
      if ((PIND & (1 << PD2)) == 0)
         RC5_buffer^=1<<sct_bit;
        sct_bit++;           
        centre = 1;           
    }
   else
   {
        if ((Timer>TminK)&&(Timer<TmaxK))
      { 
         //PORTD^=(1<<PD5);
            if (centre)
         {
                centre = 0;
                not_korr = 0;
            }
         else
         {
                centre = 1;
            if ((PIND & (1 << PD2)) == 0)
               RC5_buffer^=1<<sct_bit;
                sct_bit++;
                not_korr=0;
            }
      }
        if ((Timer>Tmin)&&(Timer<Tmax))
      {
         //PORTD^=(1<<PD6);
            if ((PIND & (1 << PD2)) == 0)
            RC5_buffer^=1<<sct_bit;
            sct_bit++;
            not_korr = 0;
        }                             
        if (not_korr == 1)
      {             
           rc5_ti_stop();   
            RC5_buffer = 0;     
        }
        if (sct_bit == 14)
      { 
         //PORTD^=(1<<PD4);     
            command=0;
         rc5_ti_stop();
         j=0;
         for (i=13;i>7;i--)
         {
            if(bit_is_set(RC5_buffer, i))
               command^=1<<j;
            j++;
         }
         RC5_buffer = 0;
         EIFR=0x40;   
        }                                                                         
    }   
}

ISR(TIMER0_OVF_vect)
{   
   rc5_ti_stop();       
   RC5_buffer = 0;       
   GIMSK|=0x40;
   EIFR=0x40; 
}

Может кто заметит ошибку? Буду признателен.
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

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

Сообщение menzoda »

Не нашел раздела с алгоритмами, поэтому спрошу здесь.

Есть программный демодулятор FSK. На его выходе получаю сигнал, который необходимо привести к окончательному виду с двумя уровнями 0 и 1:
Изображение

В нормальном случае я получаю сигнал как на верхней картинке. Выделить из него цифровой очень просто: больше нуля - "1", меньше - "0". Ну можно еще ввести некоторый гистерезис.
В случае некоторых помех сигнал становиться, как на второй картинке - меньше по амплитуде и смещенный вверх (вниз). Теперь я уже не могу использовать простое правило "больше нуля - 1, меньше - 0". Мне необходимо как-то опустить сигнал на свое место. Как можно это сделать?

П.С.: Пробовал некоторые виды ФВЧ. Работает хорошо, но я не могу его использовать: при необходимых параметрах возникает переполнение (плавающей точки в МК к сожалению нет).
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

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

Сообщение ut1wpr »

Правила форума читали? На счёт оформления постов?
ploop




Зависит от частоты. Простейший путь, уйти от действующей постоянной составляющей разделительным конденсатором. А вход АЦП подвязать к исуксственно созданой средней точке между 0 и VCC. Грубо, но иногда работает. Повторяю, от частоты и формы сигнала сильная зависимость.
С уважением,
Виктор.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

eess9 писал(а):Может кто заметит ошибку? Буду признателен.

Для начала сравните чем отличаются две процедуры обработки прерывания.
Спойлер

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

 
EMPTY_INTERRUPT
(BADISR_vect)
 
#define Tmin 40 
#define Tmax 68  
#define TminK 22 
#define TmaxK 34 

uint8_t i = 0,j=0;
unsigned char sct_bit = 0;     
unsigned char RC5_buffer
; 
uint8_t centre 
=  0;              
uint8_t not_korr 
= 0;             
unsigned char Timer 
= 0;           
unsigned char command 
= 0;    

void rc5_ti_stop
(void)
{
       
      GIMSK
|=0x00;
      TCCR0B = 0x00;
      TCNT0 = 0;
      sct_bit = 0;
}
  

Удивительно как ваш компилятор это мог пропустить.Даже без компиляции понятно, что она закончится крахом.
И снабдите ваш код комментариями, может сами ошибку найдете.
Такое ощущение, что из CVAVR код частями слизан.
Что за волшебные числа?

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

 EIFR=0x40; 
 

Следующая запись не произведет никакого эффекта.

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


GIMSK
|=0x00
 

для очистки бита нужно и (&) а не или(|)
в данном случае можно было вообще присвоить 0x00
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

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

Сообщение Goldsmith »

menzoda писал(а):Мне необходимо как-то опустить сигнал на свое место. Как можно это сделать?

    1. Определяем пиковые значения Umin, Umax.
    2. Вычисляем размах сигнала Upp=Umax-Umin и среднее значение Umid=(Umax+Umin)/2.
    3. Убираем постоянную составляющую, нормируем амплитуду: Uout=(Uin-Umid)*K/Upp

Хотя лично я предпочел бы убрать постоянную составляющую аппаратно, разделительным конденсатором или трансформатором.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

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

Сообщение menzoda »

Goldsmith писал(а):
menzoda писал(а):Мне необходимо как-то опустить сигнал на свое место. Как можно это сделать?

    1. Определяем пиковые значения Umin, Umax.
    2. Вычисляем размах сигнала Upp=Umax-Umin и среднее значение Umid=(Umax+Umin)/2.
    3. Убираем постоянную составляющую, нормируем амплитуду: Uout=(Uin-Umid)*K/Upp

Хотя лично я предпочел бы убрать постоянную составляющую аппаратно, разделительным конденсатором или трансформатором.

Аппаратно никак, весь демодулятор программный. А насчет максимума я тоже думал, но тут возникает сложность вычисления этого максимума. Сигнал то идет непрерывно, и мне понадобится движущееся окно, в котором я буду измерять максимум и минимум. В голову приходит только вариант с массивом значений (наше окно), добавлением очередного значения, выкидыванием старого, и расчетом новых мин. макс. на всем массиве. Сложновато...
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

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

Сообщение Goldsmith »

menzoda писал(а):мне понадобится движущееся окно, в котором я буду измерять максимум и минимум.
Совершенно верно. Заводим кольцевой буфер на один-два периода, заносим в него разумное количество отсчетов (думаю, 8 или 16 должно хватить).

menzoda писал(а):В голову приходит только вариант с массивом значений (наше окно), добавлением очередного значения, выкидыванием старого, и расчетом новых мин. макс. на всем массиве. Сложновато...
В кольцевом буфере новое значение автоматически затрет самое старое. А если не делать буфер слишком большим, то и искать в нем не будет накладно. Нам ведь главное - не пропустить верхнюю и нижнюю горизонтальные площадки, несколько отсчетов за период вполне хватит.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

че за?) только что начал осваивать С++,и поторю вопрос че за .... ошибка?и как ее исправить?
Вложения
Безымянный.GIF
(75.49 КБ) 320 скачиваний
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

все разобрался ошибка была в том что я неподключил sours к проекту,но сейчас я немогу откомпелировать,почему?может быть это иззо неправильной установки проги,открыл другой проект пытался изменить таже фигня.
Вложения
Безымянный.GIF
(80.17 КБ) 349 скачиваний
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

нашел косяк -прога косячная,а в протеусе програ написанная на С пошагово отлаживается? каким файлом(расширением) тогда прошивать?
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25217
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

Goldsmith писал(а):
menzoda писал(а):Мне необходимо как-то опустить сигнал на свое место. Как можно это сделать?

    1. Определяем пиковые значения Umin, Umax.
    2. Вычисляем размах сигнала Upp=Umax-Umin и среднее значение Umid=(Umax+Umin)/2.
    3. Убираем постоянную составляющую, нормируем амплитуду: Uout=(Uin-Umid)*K/Upp

Хотя лично я предпочел бы убрать постоянную составляющую аппаратно, разделительным конденсатором или трансформатором.

И правильно предпочли бы...
Потому что алгоритм вычисления среднего неверный.
Для доказательства этого достаточно взять два сигнала, которые дадут по такому алгоритму одинаковый результат, но будут иметь очевидно разные средние значения. Например меандр и очень короткие импульсы той же амплитуды.
Что бы понять как правильно реализовать вычисление среднего значения сигнала, достаточно обратиться к математике интегрирующего конденсатора...
1. Создаем скользящее окно с интервалом дискретизации соответствующем спектру сигнала по теореме Котельникова.
2. Вычисляем среднее значение буфера скользящего окна.
Среднее значение и будет нулем сигнала при его знаковом представлении.
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

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

Сообщение Goldsmith »

КРАМ писал(а):алгоритм вычисления среднего неверный.
Для доказательства этого достаточно взять два сигнала, которые дадут по такому алгоритму одинаковый результат, но будут иметь очевидно разные средние значения. Например меандр и очень короткие импульсы той же амплитуды.
В общем случае для произвольного сигнала - конечно, неверный, и придется интегрировать. Но в данном случае это продолжение разговора из другой темы про манчестерское кодирование (наверное, в ней и нужно было продолжать).

То есть мы заранее знаем, что: 1) среднее значение исходного сигнала за период равно нулю, 2) ширина импульса либо T, либо T/2. При этих условиях среднее арифметическое между пиками дает очень хорошее приближение к "истинному" среднему, а в вычислительном плане обойдется дешевле.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Ответить

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