Вопрос по Си

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
Pika4u
Поставщик валерьянки для Кота
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

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

Сообщение Pika4u »

Ещё вопрос-есть ли оператор промежутка?
if (dNre3????)(надо указать, dNre3 находится между 200 и 198.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Аватара пользователя
Pika4u
Поставщик валерьянки для Кота
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

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

Сообщение Pika4u »

Блин ,люди, прочитал книгу девиса СИ для чайников. Не понял про массивы. Как мне ввести 2 числа в один массив и затем их сравнить?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Аватара пользователя
AI_Disable
Сверлит текстолит когтями
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб
Контактная информация:

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

Сообщение 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])
Аватара пользователя
РадиоЛоматель
Мудрый кот
Сообщения: 1733
Зарегистрирован: Чт авг 21, 2008 22:03:30
Откуда: Одесса(Украина)
Контактная информация:

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

Сообщение РадиоЛоматель »

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


Пример соответствует вопросу :)

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

А что с массивами непонятного? Эт таблица такая... Номер элемента-значение. Соответственно, можно обратится к любому элементу, зная его номер.
(*tmp) &= ~( ( (param1 & (1<<PARAM1_BIT6)) || ((param2==PARAM2_TRUE)&&(--param3)) ) ? (param1 & (~param2)) : (Func1() | FUNC1_FLAGS) );
Люблю Си...
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

подскажите где искать алгортимы на си? Потребовалось мне деление с сотыми долями 16 бит на 8 бит, наверняка кто-то писал, может кому попдалось?
Digikey
Встал на лапы
Сообщения: 90
Зарегистрирован: Пн мар 08, 2010 02:59:04

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

Сообщение Digikey »

деление с сотыми долями 16 бит на 8 бит
unsigned char b;
unsigned short w;
float f;
...................

f = (float)w/b;
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

допустим, конечно жрет это все нехило ресурсов. я сразу флоат делил, но как потом при выводе sprintf избавиться от тысячных и др. не нужных знаков?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

WinAVR при включении GNU-расширения синтаксиса позволяет работать с промежутками значений в операторе switch:

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

switch(var){
case 0...10 : // что-то там
   break;
default:
   break;
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Сообщение 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
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Digikey
Встал на лапы
Сообщения: 90
Зарегистрирован: Пн мар 08, 2010 02:59:04

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

Сообщение Digikey »

как потом при выводе sprintf избавиться от тысячных и др. не нужных знаков

sprintf(buf, "%.2f", f);
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

Digikey писал(а):sprintf(buf, "%.2f", f);

Это знаю, а вот про то что в код вижане в настройках надо было выставить работу функции с float, забыл вот и не работала. :)
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение 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, есть ошибки в моей мысле? :)
хотя наверное нет смысла делать вычитание в третьем пунктом, т.к. при сравнении мк все равно делает вычитание и экономии не получу.
Digikey
Встал на лапы
Сообщения: 90
Зарегистрирован: Пн мар 08, 2010 02:59:04

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

Сообщение Digikey »

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

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

tmp = (counter << 2) + counter;   // быстрое умножение: tmp = 5 * counter
IntResult = tmp/100;              // целая часть mS
DecResult = tmp - 100*IntResult;  // сотые доли  mS
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

Digikey писал(а):Если нужна скорость, то может стоит взять кварц на 20.000 Мгц?

идея хорошая, спасибо! Про математику с 20 МГц, как-то даже не подумал. :)
(для УАРТов делитель обычно настраивается с достаточной точностью)

надо попробовать, по даташиту ошибки на скорости 115 Кб -1,4%, вобщем пойду куплю кварц.
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

Подскажите для перевода показиний счетчика из двух байтов в одну двух байтную переменную, такой код работать будет?

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

unsigned int tmp;
tmp=tmp+ICR1H;
tmp=tmp<<8;
tmp=tmp+ICR1L;
Аватара пользователя
AI_Disable
Сверлит текстолит когтями
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб
Контактная информация:

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

Сообщение AI_Disable »

Винавр умеет работать с парными 8 битными регистрами, как с одним 16 битным, так что можно и так:

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

unsigned int tmp;
tmp=ICR1;
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

ooogo писал(а):Подскажите для перевода показиний счетчика из двух байтов в одну двух байтную переменную, такой код работать будет?

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

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

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

tmp = (ICR1H << 8) + ICR1L; // не проще ли? 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

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

Сообщение ooogo »

ARV писал(а):

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

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

конечно проще, сразу не до петрил :)
Digikey
Встал на лапы
Сообщения: 90
Зарегистрирован: Пн мар 08, 2010 02:59:04

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

Сообщение Digikey »

надо попробовать, по даташиту ошибки на скорости 115 Кб -1,4%
Можно не сомневаться, все будет ОК.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

ARV писал(а):

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

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

А не сдвинет ли он 8-ми битную ICR1H и её результатом будет - 0 ? Хотя я могу ошибаться и компилятор всё поймёт... :roll:
В любом случае, я бы советовал писать так:

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

tmp = ((int)(ICR1H) << 8) + ICR1L;  
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»