Страница 46 из 386

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

Добавлено: Вт окт 18, 2011 22:31:59
urry
delete

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

Добавлено: Вт окт 18, 2011 22:33:26
O-LED
подскажите пожалуйста, должна ли переменная находящаяся в еепром, которой присваивается значение во время определения, после перезагрузки контроллера сохранять свое "старое" значение?

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

кодевижн 2.03
:dont_know:

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

Добавлено: Вт окт 18, 2011 22:47:01
md5sum
По логике как-раз должна! Иначе накой eeprom?

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

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

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

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

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

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

eeprom unsigned char    str;

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

Добавлено: Ср окт 19, 2011 06:40:21
md5sum
O-LED писал(а):

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

eeprom unsigned char    str=0;
Говорит компилятору о необходимости создать *.eep файл и залить его в МК при прошивке.
Если программа в процессе своей работы изменит значение переменной, то при следующем старте значение на 0 не сбросится.

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

Добавлено: Ср окт 19, 2011 10:24:40
O-LED
т.е. строчки

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

eeprom unsigned char    str=0;
и

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

eeprom unsigned char    str;
однозначны?
и присваивать значения можно только в теле программы?

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

Добавлено: Ср окт 19, 2011 16:23:46
Garin
Подскажите пожалуйста как нужно в коде на СИ для вольтметра сделать инвертирование показаний

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

    U_izm = 0;
  }
  else
  {
   U_izm += read_adc(1);  //Вольтметр
   U_izm = 1023 - U_izm ; //инвертирование 
   U_izm =  U_izm ;
  }  
Сделав так получил только полурезультат , то есть выводился результат на экран от 0 до 1023.
С моими измениями стало правильно инвертировано , но диапазон показаний уменьшился от 146 до 0

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

Добавлено: Чт окт 20, 2011 01:23:33
Кислый
А теперь тоже самое и внятно :D

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

Добавлено: Пт окт 21, 2011 23:22:22
AVT-28
Изучаю mikroC чем можно заменить itoa и utoa ? Раньше был другой компилятор

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

Добавлено: Сб окт 22, 2011 08:55:30
Gudd-Head
AVT-28 писал(а):Изучаю mikroC чем можно заменить itoa и utoa ?
sprintf ?

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

Добавлено: Сб окт 22, 2011 10:27:34
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) ? А то я много вариантов перепробовал и пока не очень получилось. Разве что только глобальную переменную использовать.

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

Добавлено: Сб окт 22, 2011 10:46:12
Леонид Иванович

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

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

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);
}

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

Добавлено: Сб окт 22, 2011 12:21:29
Vlad0o
спасибо. разобрался

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

Добавлено: Вт окт 25, 2011 11:04:34
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++);
	}
}

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

Добавлено: Вт окт 25, 2011 15:02:00
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"); то слово тест отображается. а так вообще пустой экран.. что то даже не знаю что делать

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

Добавлено: Вт окт 25, 2011 15:36:51
Мастер Ломастер
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);

и никакой самодеятельности! :)))

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

Добавлено: Вт окт 25, 2011 15:54:37
Vlad0o
Спасибо. попробую без самодеятельности))
только единственное мне, наверно, надо "%i" заменить на "%f" а то температура во float.

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

Добавлено: Ср окт 26, 2011 07:53:22
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); какое бы число не стояло - все равно отображаются три вопросительных знака "???".
Пойду дальше экспериментировать)

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

Добавлено: Ср окт 26, 2011 08:14:35
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

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

Добавлено: Ср окт 26, 2011 09:52:35
Леонид Иванович
Vlad0o писал(а):Кстати, вот тут http://www.sicklinger.com/en/atmel-avr- ... -in-c.html если кому то нужно будет по работе с DS1820
Будет глючить. С запретом прерываний там проблема не решена вообще никак.