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

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

Добавлено: Пн авг 20, 2012 20:01:10
Аlex
FreshMan писал(а):

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

sfrb TWBR=0;
Это откуда ?

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

Добавлено: Пн авг 20, 2012 20:13:30
FreshMan
это из папки inc......., CodeVision

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

Добавлено: Пн авг 20, 2012 20:35:45
U235
Компилятор использует ключевые слова sfrb and sfrw для доступа к регистрам ввода/вывода, размещённых в диапазоне адресов 0..3Fh, и использования для этого инструкций IN и OUT.
Пример:

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

/* Объявление SFRs */
sfrb PINA=0x19;  /* 8 битный доступ SFR */
sfrw TCNT1=0x2c; /* 16 битный доступ SFR */


void main(void)
{
unsigned char a;


a=PINA;       /* Чтение PORTA */
TCNT1=0x1111; /* Запись в регистры TCNT1L и TCNT1H */
}
Из справки CVAVR.CHM

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

Добавлено: Вт авг 21, 2012 21:59:48
skader
Подскажите как на C (picc) перезагрузить МК?

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

Добавлено: Вт авг 21, 2012 22:33:08
Аlex
А причём тут Си ?
Ищите в доке на МК возможность его программного ресета. Если программно невозможно, то - ключ на ногу МК, сбрасывающий его аппаратно.

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

Добавлено: Ср авг 22, 2012 18:34:57
TICLIR
Доброе время суток. Вопрос такой, подскажите пожалуйста. В книгах по СИ пишут что функция может возвращать не массив,а
указатель на массив, а примеров нет. Вот отрывок программы

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

void ust_raz(int rr,char znac){ //разложения числа в массив 
  char prom,prom1;
    if((!((rr%1000)/100))&&(!(rr/1000))){ //проверяем не значищий 0 в старш разрядах
  if(znac) prom1=0x0b; //если есть незнач 0 и отрицательная темп на его место "-"
   else prom1=0x0a;// или просто пусто
   }
  else prom1=(rr%1000)/100;// или просто вычисляем
  
  if(!(rr/1000)){ // проверяем в старшем разряде не значищий 0
   if((znac)&&(prom1!=0x0b)) prom=0x0b;//если есть незнач 0 и отрицательная темп 
                                //и нет знака "-" на пред старшем месте  на его место "-" 
   else prom=0x0a;  // или просто пусто                
   }
  else prom=rr/1000;// или просто вычисляем 
  cifir[0]=prom;
  cifir[1]=prom1;
  cifir[2]=((rr%1000)%100)/10;
  cifir[3]=((rr%1000)%100)%10;
  }
Как сделать так что бы массив cifir,верней указатель на массив можно было возвратить.

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

Добавлено: Ср авг 22, 2012 18:38:48
Аlex

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

char* ust_raz(int rr,char znac){

................
................

return cifir;
}
Это если cifir - массив чаров.

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

Добавлено: Ср авг 22, 2012 18:50:49
Аlex
Но лучше передавать в ф-ию указатель на массив и его обрабатывать.
void ust_raz(int rr,char znac, char *pArr){

......
Тут, за место cifir обращаемся к pArr
......

}
Вызов:

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

ust_raz(1234, 0, cifir);
Тогда функция не будет привязана к конкретному массиву.

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

Добавлено: Ср авг 22, 2012 18:53:40
TICLIR
Аlex писал(а): Это если cifir - массив чаров.
Спасибо,буду пробовать, только что это за слово "чаров"?

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

Добавлено: Ср авг 22, 2012 18:55:28
Аlex
что это за слово "чаров"?
Извините, думал Вы поймёте.
char - чар :)
Т.б. если :

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

char cifri[...];

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

Добавлено: Ср авг 22, 2012 19:03:24
TICLIR
Спасибо ещё раз, теперь всё понятно.

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

Добавлено: Ср авг 22, 2012 22:41:47
shads
Аlex писал(а):

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

void DspMessageShow (char *TxtDflt){
  while(*TxtDflt){
    DspSimbShow (*TxtDflt, mPos);
    TxtDflt++;
  }
}
Как то так...
Все ОК, но опять предупреждения.....
Вот код. Компилится, работает, но постоянно когда использую DispMessageShow, предупреждение выскакивает:
"warning: pointer targets in passing argument 1 of 'DispMessageShow' differ in signedness"
Гляньте своим зорким взглядом, что поправить.....
Спойлер

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

//#######################################################################################################################
//#######################################################################################################################
//ВКЛЮЧАЕМЫЕ ФАЙЛЫ
#include <avr/io.h>
#include <avr/interrupt.h>

//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
unsigned char DispData [] =     {0,0,0,0};        /*БУФЕР ВЫВОДА ДАННЫХ НА ДИСПЛЕЙ*/
unsigned char SimbMass [] =                        /*символьный массив (не используются K,M,V,W,X,Z)*/
        {0xf5,0x05,0x73,0x57,0x87,                /*01234*/
        0xd6,0xf6,0x45,0xf7,0xd7,                /*56789*/
        0x00,0xe7,0xb6,0xf0,0x37,                /* ABCD*/
        0xf2,0xe2,0xf4,0xa7,0x05,                /*EFGHI*/
        0x35,0x00,0xb0,0x00,0x26,                /*JKLMN*/
        0x36,0xe3,0xc7,0x22,0xd6,                /*OPQRS*/
        0xb2,0x34,0x00,0x00,0x00,                /*TUVWX*/
        0x97,0x00,0xa0,0x23,0x05,                /*YZ[/]*/
        0x02,0x10};                                /*-_   */    

unsigned char TxtSure [] = {"sure"};            /*МАССИВ СООБЩЕНИЙ ДЛЯ ВЫВОДА НА ДИСПЛЕЙ*/
unsigned char TxtDone [] = {"done"};
unsigned char TxtStup [] = {"stup"};
unsigned char TxtDflt [] = {"dflt"};
unsigned char TxtRet  [] = {" ret"};
unsigned char TxtSpace[] = {"    "};

//прототипы функций    
void DispSimbShow (unsigned char, unsigned char);
void DispMessageShow (char*);

//Главная функция
int main (void)
{
    DispMessageShow (TxtSure);

    while(1)                                    //бесконечный цикл
    {    
    }
}

//-----------------------------------------------------------------------------------------------------------------------
//функция вывода сообщения на дисплей
void DispMessageShow  (char *pAdrTxt)
{
    for (unsigned char position =0; position<4; position++)
        DispSimbShow (*pAdrTxt++,position);
}

//-----------------------------------------------------------------------------------------------------------------------
//функция вывода символа на дисплей
//@1 - символ "0-9,A-Z"
//@2 - знакоместо (0-3)
void DispSimbShow (unsigned char simbol, unsigned char position)
{
    unsigned char pnt =10;

    if (simbol >= 96)
        simbol -= 32;                            //преобразуем знаки a-z в знаки A-Z
    
    if (simbol < 10)                        
        pnt = simbol;                            //значения 0-9
    
    if ((simbol >= 48)&&(simbol < 58))
        pnt = (simbol -48);                        //символы 0-9
    
    if ((simbol >= 64)&&(simbol < 96))
        pnt = (simbol -64 +10);                    //символы A-Z

    DispData[position] = SimbMass[pnt];
}
 

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

Добавлено: Ср авг 22, 2012 22:54:38
U235
shads писал(а):...когда использую DispMessageShow, предупреждение выскакивает:
"warning: pointer targets in passing argument 1 of 'DispMessageShow' differ in signedness"
Вы указатель на unsigned char передаёте функции, а ей надо указатель на char. Можно переделать так.

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

void DispMessageShow (unsigned char*);


//функция вывода сообщения на дисплей
void DispMessageShow  (unsigned char *pAdrTxt)
{
    for (unsigned char position =0; position<4; position++)
        DispSimbShow (*pAdrTxt++,position);
}

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

Добавлено: Ср авг 22, 2012 23:18:58
shads
Эге.....
Помогло! Оказ-ся там или везде надо поставить unsigned, или везде убрать, чтобы просто char было, а я чет в перемешку.....

Пипа..... (как говорит моя дочурка.)

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

Добавлено: Чт авг 23, 2012 11:04:21
shads
Так..... это опять я.
Соображаю процедуру вывода числа на дисплей, и чет компилятор моросит (а может и я мороСю.....)
Спойлер

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

//функция вывода на дисплей числа 0-9999
void DispIntShow (unsigned int integer)
{
    unsigned char position = 0;                    //позиция печати на дисплее

    if (integer < 1000)
        DispData [position ++] = 0;                //очистить тысячи
    if (integer < 100)
        DispData [position ++] = 0;                //очистить сотни
    if (integer < 10)
        DispData [position ++] = 0;                //очистить десятки

    switch (position)
    {
        case 0: DispData [position ++] = div (&integer, 1000); 
        case 1: DispData [position ++] = div (&integer, 100); 
        case 2: DispData [position ++] = div (&integer, 10); 
        case 3: DispData [position] = integer;
    }
}

//ф-ция деления возвращает результат деления 
//аргументы: делимое (указатель), делитель
unsigned char div (unsigned int *pDivident, unsigned int divisor)
{
    unsigned char result =0;
    while (*pDivident >= divisor)
    {
        *pDivident /= divisor;
        result ++;
    }
    return result;
}
 
Не работает нормально. Когда в отладчике смотрю, там после первой if программа сразу переходит к switch..... а вроде должна по всем if пройтись..... это кто моросит, я или оно (компилятор).

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

Добавлено: Чт авг 23, 2012 11:28:37
a_skr
если integer >= 1000 , то оно не может быть меньше 100 и 10 :))

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

Добавлено: Чт авг 23, 2012 11:34:48
a_skr
и еще подсказка: оптимизацию отключите

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

Добавлено: Чт авг 23, 2012 11:39:01
shads
Парррррдон..... разобрался. Оказ-ся компиль очень умный, и таким образом съэкономил лишние шаги программы, т.к. я ему пихал число больше 1000. (просто я думал что он мою логику примет, и даже если число больше 1000, будет остальные проверки делать, а он во какой оказ-ся.....)
Ну и еще кое какие косяки устранил, теперь все нормально работает, выводит на дисплей число от 0 до 9999.
Спойлер

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

//функция вывода на дисплей числа 0-9999
void DispIntShow (unsigned int integer)
{
    unsigned char position = 0;                    //позиция печати на дисплее

    if (integer < 1000)
        DispData [position ++] = 0;                //очистить тысячи
    if (integer < 100)
        DispData [position ++] = 0;                //очистить сотни
    if (integer < 10)
        DispData [position ++] = 0;                //очистить десятки

    switch (position)
    {
        case 0: DispSimbShow (div (&integer, 1000), position ++); 
        case 1: DispSimbShow (div (&integer, 100), position ++);
        case 2: DispSimbShow (div (&integer, 10), position ++); 
        case 3: DispSimbShow (integer, position);
    }
}

//ф-ция деления возвращает результат деления 
//аргументы: делимое (указатель), делитель
unsigned char div (unsigned int *pDivident, unsigned int divisor)
{
    unsigned char result =0;
    while (*pDivident >= divisor)
    {
        *pDivident -= divisor;
        result ++;
    }
    return result;
} 

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

Добавлено: Пт авг 24, 2012 13:08:28
shads
Радовался тому что теперь намного быстрее пойдет написание программ (используя С вместо асма) да не тут то было.....
Теперь вместо того чтобы тратить время на написание кода, я его трачу на отладку.....
Например тут не мог понять почему не работает

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

    while(1)                                    //бесконечный цикл
    {
        if    (BtnPressWait1Sec() & ShortUp)
        {
            MenuBtnPressWait (TxtSure, TxtDone);
            DispMessageShow (TxtSpace);
        }
    }
 
оказ-ся программа только один раз проходит проверку if а потом напрочь зацикливается на пустом цикле. Пришлось туда пихнуть volatile переменную

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

    volatile unsigned char volatilei;

    while(1)                                    //бесконечный цикл
    {
        if    (BtnPressWait1Sec() & ShortUp)
        {
            MenuBtnPressWait (TxtSure, TxtDone);
            DispMessageShow (TxtSpace);
        }
        volatilei++;
    }
 
И такая же проблема и в других местах, приходится там таким изворотом делать..... А как еще завставить компилятор не тупить так, оптимизацию чет тоже неохота отключать.....

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

Добавлено: Пт авг 24, 2012 13:46:16
ibiza11
приведите весь код.