Страница 2 из 3

Re: Вопрос по Си

Добавлено: Вс апр 11, 2010 16:52:48
Pika4u
Ещё вопрос-есть ли оператор промежутка?
if (dNre3????)(надо указать, dNre3 находится между 200 и 198.

Re: Вопрос по Си

Добавлено: Пн апр 12, 2010 13:45:05
Pika4u
Блин ,люди, прочитал книгу девиса СИ для чайников. Не понял про массивы. Как мне ввести 2 числа в один массив и затем их сравнить?

Re: Вопрос по Си

Добавлено: Пн апр 12, 2010 17:57:47
AI_Disable
Pika4u писал(а):Ещё вопрос-есть ли оператор промежутка?
if (dNre3????)(надо указать, dNre3 находится между 200 и 198.
Для этого пользуют логические операции: if(dNre3<200 && dNre3>198). Правда, данный пример не самый удачный, т.к. условие будет срабатывать только при одном значении - 199.
Pika4u писал(а):Как мне ввести 2 числа в один массив и затем их сравнить?
Когда объявляем массив можем сразу присвоить значения всем элементам: unsigned char mas[2]={200, 198};
Далее можем присваивать значения только по одному: mas[0]=55; mas[1]=64;
Для сравнения двух элементов: if(mas[0]==mas[1])

Re: Вопрос по Си

Добавлено: Пн апр 12, 2010 18:25:35
РадиоЛоматель
AI_Disable писал(а):Для этого пользуют логические операции: if(dNre3<200 && dNre3>198). Правда, данный пример не самый удачный, т.к. условие будет срабатывать только при одном значении - 199.
Пример соответствует вопросу :)

А если в промежуток нужно включить числа 198 и 200, то нужно написать: if(dNre3<=200 && dNre3>=198) ">=" значок "больше либо равен"

А что с массивами непонятного? Эт таблица такая... Номер элемента-значение. Соответственно, можно обратится к любому элементу, зная его номер.

Re: Вопрос по Си

Добавлено: Чт июл 08, 2010 11:52:37
ooogo
подскажите где искать алгортимы на си? Потребовалось мне деление с сотыми долями 16 бит на 8 бит, наверняка кто-то писал, может кому попдалось?

Re: Вопрос по Си

Добавлено: Пт июл 09, 2010 18:12:56
Digikey
деление с сотыми долями 16 бит на 8 бит
unsigned char b;
unsigned short w;
float f;
...................

f = (float)w/b;

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 10:08:23
ooogo
допустим, конечно жрет это все нехило ресурсов. я сразу флоат делил, но как потом при выводе sprintf избавиться от тысячных и др. не нужных знаков?

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 10:23:01
ARV
Pika4u писал(а):Ещё вопрос-есть ли оператор промежутка?
if (dNre3????)(надо указать, dNre3 находится между 200 и 198.
WinAVR при включении GNU-расширения синтаксиса позволяет работать с промежутками значений в операторе switch:

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

switch(var){
case 0...10 : // что-то там
   break;
default:
   break;
}

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 10:35:34
ARV
ooogo писал(а):подскажите где искать алгортимы на си? Потребовалось мне деление с сотыми долями 16 бит на 8 бит, наверняка кто-то писал, может кому попдалось?

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

uint16_t var1; // делимое 
uint8_t var2; // делитель
uint8_t result; // частное 
uint8_t sot; // сотые доли

uint32_t tmp;

tmp = var1 * 100UL;
tmp = tmp / var2;
result = tmp / 100;
sot = tmp % 100;

вы получаете два числа: отдельно целые и отдельно сотые вашего результата деления, которые надо вывести, разделив их точкой. все это будет гораздо экономнее работы с float-ами и тем более с выводом этих float-ов при помощи printf

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 18:56:59
Digikey
как потом при выводе sprintf избавиться от тысячных и др. не нужных знаков
sprintf(buf, "%.2f", f);

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 20:15:56
ooogo
Digikey писал(а): sprintf(buf, "%.2f", f);
Это знаю, а вот про то что в код вижане в настройках надо было выставить работу функции с float, забыл вот и не работала. :)

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 20:38:14
ooogo
ARV думал примерно также, но если переходить к частности т.е. моей задаче, то нужно разделить значение счетчика таймера(таймер тикает от генератора напрямую) на частоту, для получения времени. имеем два байта счетчика и частоту мк 18,432 МГц, чуток подумал, у меня алгоритм получается примерно такой:
1. перевожу счетчик в деситичное значение в переменную unsigned long int;
2. умножаю ее на 1000;
3. делю на 18 432 вычитанием получаю целое частное(unsigned int) и остаток;
4. остаток умножаю на 100 и делю на 18 432 получаю сотые (unsigned char)

получается время в микросекундах в двух переменных, целая часть unsigned int сотые unsigned char, есть ошибки в моей мысле? :)
хотя наверное нет смысла делать вычитание в третьем пунктом, т.к. при сравнении мк все равно делает вычитание и экономии не получу.

Re: Вопрос по Си

Добавлено: Пн июл 12, 2010 22:47:37
Digikey
Если нужна скорость, то может стоит взять кварц на 20.000 Мгц? (для УАРТов делитель обычно настраивается с достаточной точностью) Тогда нужно будет только одно деление и одно умножение:

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

tmp = (counter << 2) + counter;   // быстрое умножение: tmp = 5 * counter
IntResult = tmp/100;              // целая часть mS
DecResult = tmp - 100*IntResult;  // сотые доли  mS

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 08:44:38
ooogo
Digikey писал(а):Если нужна скорость, то может стоит взять кварц на 20.000 Мгц?
идея хорошая, спасибо! Про математику с 20 МГц, как-то даже не подумал. :)
(для УАРТов делитель обычно настраивается с достаточной точностью)
надо попробовать, по даташиту ошибки на скорости 115 Кб -1,4%, вобщем пойду куплю кварц.

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 10:23:42
ooogo
Подскажите для перевода показиний счетчика из двух байтов в одну двух байтную переменную, такой код работать будет?

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

unsigned int tmp;
tmp=tmp+ICR1H;
tmp=tmp<<8;
tmp=tmp+ICR1L;

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 10:53:54
AI_Disable
Винавр умеет работать с парными 8 битными регистрами, как с одним 16 битным, так что можно и так:

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

unsigned int tmp;
tmp=ICR1;

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 11:42:15
ARV
ooogo писал(а):Подскажите для перевода показиний счетчика из двух байтов в одну двух байтную переменную, такой код работать будет?

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

unsigned int tmp;
tmp=tmp+ICR1H;
tmp=tmp<<8;
tmp=tmp+ICR1L;

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

tmp = (ICR1H << 8) + ICR1L; // не проще ли? 

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 13:35:31
ooogo
ARV писал(а):

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

tmp = (ICR1H << 8) + ICR1L; // не проще ли? 
конечно проще, сразу не до петрил :)

Re: Вопрос по Си

Добавлено: Вт июл 13, 2010 22:37:26
Digikey
надо попробовать, по даташиту ошибки на скорости 115 Кб -1,4%
Можно не сомневаться, все будет ОК.

Re: Вопрос по Си

Добавлено: Пт июл 16, 2010 03:20:25
Аlex
ARV писал(а):

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

tmp = (ICR1H << 8) + ICR1L; // не проще ли? 
А не сдвинет ли он 8-ми битную ICR1H и её результатом будет - 0 ? Хотя я могу ошибаться и компилятор всё поймёт... :roll:
В любом случае, я бы советовал писать так:

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

tmp = ((int)(ICR1H) << 8) + ICR1L;