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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

delete
Последний раз редактировалось urry Ср окт 19, 2011 09:00:06, всего редактировалось 2 раза.
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

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

Сообщение O-LED »

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

по логике вроде как не должна, а на практике, после перезагрузки остаётся прошлое значение.

кодевижн 2.03
:dont_know:
KIT
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

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

Сообщение md5sum »

По логике как-раз должна! Иначе накой eeprom?
— Не говорите мне что делать и я не скажу куда Вам идти...
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

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

Сообщение O-LED »

md5sum писал(а):По логике как-раз должна! Иначе накой eeprom?
тогда почему при первом включении после прошивки в переменной нужное значение? ведь после прошивки происходит обычный старт контроллера, точно такой же как и при замыкании вывода ресет на землю.......

по идеи, каждый старт должен записывать в переменную str значение 0

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

eeprom unsigned char    str=0;


а вот если при объявлении переменной ей ничего не присваивать, тогда и должно сохраняться "старое" значение. а если старого не было(при первом включении) то в переменной должен быть всякий мусор.

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

eeprom unsigned char    str;
KIT
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

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

Сообщение md5sum »

O-LED писал(а):

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

eeprom unsigned char    str=0;

Говорит компилятору о необходимости создать *.eep файл и залить его в МК при прошивке.
Если программа в процессе своей работы изменит значение переменной, то при следующем старте значение на 0 не сбросится.
— Не говорите мне что делать и я не скажу куда Вам идти...
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

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

Сообщение O-LED »

т.е. строчки

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

eeprom unsigned char    str=0;
и

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

eeprom unsigned char    str;
однозначны?
и присваивать значения можно только в теле программы?
KIT
Аватара пользователя
Garin
Потрогал лапой паяльник
Сообщения: 351
Зарегистрирован: Пн сен 12, 2011 12:13:46

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

Сообщение Garin »

Подскажите пожалуйста как нужно в коде на СИ для вольтметра сделать инвертирование показаний

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

    U_izm = 0;
  }
  else
  {
   U_izm += read_adc(1);  //Вольтметр
   U_izm = 1023 - U_izm ; //инвертирование
   U_izm =  U_izm ;
  } 

Сделав так получил только полурезультат , то есть выводился результат на экран от 0 до 1023.
С моими измениями стало правильно инвертировано , но диапазон показаний уменьшился от 146 до 0
Аватара пользователя
Кислый
Поставщик валерьянки для Кота
Сообщения: 2095
Зарегистрирован: Чт апр 08, 2010 18:50:01
Откуда: Краснодар
Контактная информация:

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

Сообщение Кислый »

А теперь тоже самое и внятно :D
RETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код
@hobbyelectronics
Аватара пользователя
AVT-28
Потрогал лапой паяльник
Сообщения: 378
Зарегистрирован: Вс сен 11, 2011 12:35:11

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

Сообщение AVT-28 »

Изучаю mikroC чем можно заменить itoa и utoa ? Раньше был другой компилятор
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

AVT-28 писал(а):Изучаю mikroC чем можно заменить itoa и utoa ?

sprintf ?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

У меня тут возникла пока неразрешимая для меня проблема. (Разбираюсь с 1-wire (DS1820). пишется в Keil для silabs c8051f314)

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

void ow_reset(void);

void main (void)
{
while(1)
{
if (ow_reset() == 0)
{
write_1(1 , "good");
}
else
{
write_2(1 , "bad");
}
}
}


void ow_reset(void)
{
bit presence;
DQ = 0; //pull DQ line low
DelayUS(640); // leave it low for 480us
DQ = 1; // allow line to return high
DelayUS(94); // wait for presence
presence = DQ; // get presence signal
DelayUS(501); // wait for end of timeslot

} // 0=presence, 1 = no part




Так вот пытаюсь компилировать - выдает ошибку С193 в этом месте (if (ow_reset() == 0)).

Так же пытался сделать как написано было в примере к 1-wire. Но тут возник другой вопрос.

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


unsigned char ow_reset(void)
{
unsigned char presence;
DQ = 0; //pull DQ line low
delay(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part


Вот эта функция. Как мне правильно ее объявить и потом вызвать для сравнения if (ow_reset() == 0) ? А то я много вариантов перепробовал и пока не очень получилось. Разве что только глобальную переменную использовать.
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

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

Сообщение Леонид Иванович »

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

//---------- Генерация импульса сброса: ----------

bool TReset(void)
{
  char si;
  Port_OWP1_0;                 //OWP <- 0
  Delay_us(500);               //delay 500 uS
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP1_Z;                 //OWP <- 1
  Delay_us(14);                //delay 14 uS
  if(Pin_OWP1)                 //если OWP = 0, то ошибка
  {
    Delay_us(52);              //delay 52 uS
    if(!Pin_OWP1)              //если OWP = 1, то ошибка
    {
      __restore_interrupt(si); //восстанавление прерываний
      Delay_us(250);           //delay 250 uS
      if(Pin_OWP1)             //если OWP = 0, то ошибка
      {
        return(1);             //если ошибок нет, термометр присутствует
      }
    }
  }
  __restore_interrupt(si);     //восстанавление прерываний в случае ошибки
  return(0);
}

//---------- Запись/чтение байта по однопроводной шине: ----------

char TByte(char dat)
{
  char res;
  for(char i = 0; i < 8; i++)
  {
    res = res >> 1;
    if(TBit(dat & 1)) res |= 0x80;
     else res &= ~0x80;
    dat = dat >> 1;
  }
  return(res);
}

//---------- Запись/чтение бита по однопроводной шине: ----------

bool TBit(bool b)
{
  char si;
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP1_0;                 //OWP <- 0
  Delay_us(2);                 //delay 2 uS
  if(b) Port_OWP1_Z;           //bit = 1, OWP <- 1
  Delay_us(13);                //delay 13 uS
  bool owp = Pin_OWP1;         //чтение порта
  Delay_us(45);                //delay 45 uS
  Port_OWP1_Z;                 //OWP <- 1
  __restore_interrupt(si);     //восстанавление прерываний
  Delay_us(2);                 //delay 2 uS
  return(owp);
}
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

спасибо. разобрался
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

Добрый день.

У меня тут непонимание случилось. Беру температуру с датчика DS1820.
За основу функцию отсюда ( http://www.maxim-ic.com/app-notes/index.mvp/id/162 ) для получения и преобразования температуры.

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

float read_temp(void)

{
unsigned char get[10];
unsigned char temp1, temp2, temp5;
float temp3, temp4;
int k;
ow_reset();
write_byte(0xCC);
write_byte(0xBE);
DelayUS(139);
ow_reset();
write_byte(0xCC);
write_byte(0x44);
for (k=0;k<9;k++){get[k]=read_byte();} // получаю 9 байт

temp1 = get[1]; //байт знака
temp2 = get[0]; //байт значения температуры

if (temp1 <= 0x80)
{
temp3 = temp2;
temp4 = temp3*0,5;
FLAG = "plus";  //это для дополнительной проверки. на ЛСД отображается верно.
}
else
{
temp5 = ~temp2+0x01; //инвертирую и прибавляю 1
temp3 = temp5;
temp4 = temp3*(-0,5); //добавляю знак
FLAG = "minus";
}
return(temp4); //функция возвращает значение во float

}



Дальше

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

void main (void)
{
while (1)
{      
////////////////////////////////////////////
//Переменные объявлены как: //////
//const char *chTEMP;                   // 
//const char *FLAG;                     //
/////////////////////////////////////////

sprintf(chTEMP, "%f", read_temp()); // якобы преобразую float в *char
write_1(0, chTEMP);  // отображение температуры на первой строке
write_2(0, FLAG);  //так сказать проверочный флаг на второй строке (вроде как работает)

}
 

Значение FLAG отображается на экране, а температура нет. Возможно вся беда в sprintf, а точнее в том что я не шарю в Cи. Подскажите, пожалуйста, как можно решить проблему.


На всякий случай функция отображение информации на ЛСД.

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

void write_1(unsigned char pos, const char *a)
{
lcd_CMD(0x80 + pos);   // 1000 0000
while (*a)
   {
      lcd_write(*a++);
   }
}
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

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

void main(void)
{
lcd_init();
while(1)
{
float chb;
const char *chte;
chb = -44,5;
printf(chte,"TEMP: %.1f ", chb);
write_1(5, chte);
write_2(5, "TEST");
}
}


сделал еще так проверить (везде использовали именно этот метод). так вообще ничего не отобразилось на экране LCD. даже "TEST". если закомментировать все кроме write_2(5, "TEST"); то слово тест отображается. а так вообще пустой экран.. что то даже не знаю что делать
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

Vlad0o писал(а):

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

void main(void)
{
lcd_init();
while(1)
{
float chb;
const char *chte;
chb = -44,5;
printf(chte,"TEMP: %.1f ", chb);
write_1(5, chte);
write_2(5, "TEST");
}
}


сделал еще так проверить (везде использовали именно этот метод). так вообще ничего не отобразилось на экране LCD. даже "TEST". если закомментировать все кроме write_2(5, "TEST"); то слово тест отображается. а так вообще пустой экран.. что то даже не знаю что делать

я, конечно, не все подряд прочел и могу что-то пропустить... но что конкретно в приведенном участке кода вы творите? это же беспредел какой-то! char *chte - это у вас что такое? УКАЗАТЕЛЬ. на что он указывает? а хрен его знает! и именно туда (в_хрен_его_знает_куда) вы пишите функцией (кстати, какой функцией - printf?!)...

короче, надо делать так:
1. объявляете массив символов для хранения промежуточных строк
char str[25]; // размер массива должен быть на 1 символ больше, чем самая длинная строка
2. пишите в этот массив свои значения
sprintf(str,"%i", 123);
3. выводите сформированную строку на дисплей
write_1(1, str);

и никакой самодеятельности! :)))
битва с дураками проиграна, победители торжествуют. слава победителям!
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

Спасибо. попробую без самодеятельности))
только единственное мне, наверно, надо "%i" заменить на "%f" а то температура во float.
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

проверил. получилось вот так:
while(1)
{
char str[25];
sprintf(str,"%i", 56);
write_1(0, str);
T = 1;
Delay(2000);
T = 0;
Delay(2000);
}

Для int если число состоит меньше чем из 3 и больше чем из 4 цифр, то на лсд отображается либо ерунда 5значная либо 0.

Для float sprintf(str,"%f", 50,6); какое бы число не стояло - все равно отображаются три вопросительных знака "???".
Пойду дальше экспериментировать)
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

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

Сообщение Vlad0o »

float temp_po;
const char str[8];
temp_po = 133,5;
sprintf(str,"%.1f C", temp_po);
write_1(0, str);

а вот так вот все сработало шикарно! :))

Кстати, вот тут http://www.sicklinger.com/en/atmel-avr- ... -in-c.html если кому то нужно будет по работе с DS1820
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

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

Сообщение Леонид Иванович »

Vlad0o писал(а):Кстати, вот тут http://www.sicklinger.com/en/atmel-avr- ... -in-c.html если кому то нужно будет по работе с DS1820


Будет глючить. С запретом прерываний там проблема не решена вообще никак.
Ответить

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