Страница 78 из 421

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 13:18:47
Upgrader
ValBag писал(а):
Upgrader писал(а):как можно временно выключить генерацию аппаратного ШИМа МК таким образом, чтобы он как-бы работал (изменял свое состояние если это требуется), но напряжения на выходной ножке не было?
Еще вариант: обнулить биты СОМхх регистра TCCRxx нужного таймера.
А не подскажите что я делаю не так?
МК ATmega8, таймер 2:
Выключение:
TCCR2 &= (~(1<<COM21));
Включение:
TCCR2|=(1<<COM21);

Когда выключаю - вроде и выключается, но все-равно как будто в случайном порядке импульсы ШИМа проскакивают часто... :dont_know: Явно что-то не то.
Выключил:
Изображение
А так было до выключения (нормальная работа):
Изображение

На других МК (Tiny44, Tiny2313) все было нормально, выход полностью пропадал.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 13:39:24
ValBag
neon-f
Установка флага у вас переместилась в [TIM1_COMPA]. Для каких целей он теперь?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 13:57:31
ValBag
Upgrader
Если вы изменяете значения OCR2A, то не присутствуют ли там нулевое или максимальное его значения?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:04:04
neon-f
она не переместилась, она там и была, просто для вопроса указал первое попавшееся что пришло в голову.
TIM0_OVF - обслуживает динамическую индикацию
TIM1_COMPA - отсчет времени раз в секунду. опрос ds18b20 произвожу не внутри прерывания, а через "флаг" потому что на время чтения перестанет срабатывать TIM0_OVF и индикация прекратится.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:08:26
Upgrader
ValBag писал(а):Upgrader
Если вы изменяете значения OCR2A, то не присутствуют ли там нулевое или максимальное его значения?
Нет. Нулевое возможно, но в конкретном случае это не так. До максимального не доходит. А это имеет значение?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:15:31
ValBag
neon-f
Просто, как подметил ув. ARV, если у вас время чтения тайм-слота минимально (микросекунды), то флаг наверное не нужен.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:23:37
neon-f
флаг для того чтоб читать не тупо в цикле, а раз в секунду, тем более что это "раз в секунду" уже имеется.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:37:06
ValBag
Upgrader писал(а):Нет. Нулевое возможно, но в конкретном случае это не так. До максимального не доходит. А это имеет значение?
Возможны следующие "казусы": Если OCR2A=0x00; // то на выходе OC2A могут присутствовать короткие выбросы с маскимальным периодом таймера. Если же в OCR2A - максимум, то выход переключится в устойчивое состояние, определяемое битами регистра СОМхх, в вашем случае в 1. Такие режимы возможны по функционалу МК, при включенном выводе OCnA. А почему в случае отключения беспорядки - пока не соображу. Попробуйте, кроме отключения вывода сравнения, одновременно переключить выход порта на вход.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:43:23
Upgrader
ValBag писал(а):Попробуйте, кроме отключения вывода сравнения, одновременно переключить выход порта на вход.
При этом на ШИМ выходе оказывается постоянно напряжение (только на нем)... вместо того чтобы пропасть.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 10, 2010 14:52:41
ValBag
Upgrader писал(а):При этом на ШИМ выходе оказывается постоянно напряжение (только на нем)... вместо того чтобы пропасть.
Да, помню, ...мы (то есть вы) это уже проходили. :) Может у вас компилятор немного "прибабахнутый". Если не секрет, давайте я на своем попробую скомпилировать. Почту в личку сброшу.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Вт июн 15, 2010 14:22:35
ВитГо
Есть меню описанное массивом элеметов следующей структуры

typedef struct {
unsigned char *stritem;
unsigned char next;
unsigned char prev;
} MENU_STRUCT;

собственно меню это константа в программной памяти
__flash const menu:array[] of MENU_STRUCT= {
{"пункт 1", 1,0},
{"пункт 2", 0,1} }

как добавить в описатель меню ссылку на процедуру для выполнения того или иного действия ?
и как потом эту процедуру вызвать.. ?

p.s. я новичек в СИ.. ткните пальцем что почитать а то уже голову сломал над этой задачей

в структуру чтото типа void * proced добавить наверное..
а как присвоить значение указателю и как вызвать потом по нему процедуру ?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Вт июн 15, 2010 17:28:25
avreal
В языке C это делается так:

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

/* Пусть функция обработки позиции меню возвращает статус типа unsigned char
   и принимает какой-то аргумент типа int, в котором заданы некие нюансы выполнения
   Если этого нет - заменить всё на void
*/
typedef unsigned char (*menu_handler_t)(int);

typedef struct {
    unsigned char *stritem;
    unsigned char next;
    unsigned char prev;
    menu_handler_t handler;
} menu_item_t;

/* функции обработки */
unsigned char item_1_handler(int type)
{
    return 0;
}

unsigned char item_2_handler(int type)
{
    return 0;
}

const menu_item_t menu_array[] =
{
    {"пункт 1", 1, 0, item_1_handler},
    {"пункт 2", 0, 1, item_2_handler}
};

...

    // Вызов обработчика
    // Сюда записали какую-то дополнительную информацию, скажем, номер пункта меню,
    // если для нескольких позиций годится один обработчик, к примеру, это позиции редактироания
    // нескольких параметров одного типа -- тогда функци одна, принимает номер позиции меню и
    // вычисляет номер параметра.
    int type;

    status = menu_array[index].handler(type);
Дальше в процессе приготовлния меню в зависимости от компилятора/целевого контроллера это нужно посыпать специями вида __flash/__code/..., подставить функции обращения к флешу (если это gcc) или внешнему i2c eeprom (если всё меню и текстовые строки сидят там для экономии флеша), но это уже детали реализаци.
Общий ход для С такой.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 09:54:33
ВитГо
Наверное все таки без чужой помощи я не разберусь с указателями и хранением данных в памяти программ avr...

Имею структуру меню:

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

typedef struct {
    unsigned char   numitem;  // номер пункта меню (УНК)
    unsigned char    *itemstr;  // текст пункта меню
    unsigned char  nextitem;  // следующий пункт
    unsigned char  previtem;  // предыдущий пункт
    unsigned char    upitem;  // вышестоящий пункт меню
    unsigned char  downitem;  // нижестоящий пункт меню
    void             * pvar; // указатель на параметр
    unsigned char   partype; // тип параметра:
} MENU_STRUCT;
меню строиться по Уникальным Номерам numitem пунктов и ссылкам на них nextitem, previtem, upitem, downitem
nextitem и previtem - это ссылки на следующий/предыдущий пункты в пределах одного уровня меню
upitem - вышестоящий пункт downitem - нижестоящий пункт

все down up next prev itemы ссылаются на numitem соответстующего пункта (чтобы не задумываться о количестве элементов меню и о их номере в массиве)

параметр *pvar это по задумке указатель на переменную соответствующую параметру пункта меню (например имя модели, количество каналов управления и так далее) параметр соответственно в RAM
структура записи переменных такова:

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

#define CH_COUNT 8 // Количество физически передаваемых каналов
#define UCH_COUNT 14 // Количество пользовательских каналов

// Описание кривой канала
typedef struct {
        signed char point[9];   // ордината точки
                        // по оси абцисс -100%  -75%  -50%  -25%  0  25%  50%  75%  100%
} CURVE_STRUCT;

// Описание записи о микшере канала
typedef struct {
  unsigned char MIX_TYPE; // тип микширования bit0=0 - фиксированное микширование 
                          //                  bit0=1 - регулируемое микширование
                          // выключатель микшера bit7654 - UCH выключатель
                          // инверсия выключателя bit3=1, без инверсии bit3=0
  unsigned char CH_NUM;   // номера каналов для микширования bit7654 - получатель
                          //                                 bit3210 - источник
  unsigned char MIX_VOL;  // при MIX_TYPE.0=0 процент микширования(-128..+127)
                          // при MIX_TYPE.0=1 bit3210 - источник коэффициента микширования (UCH канал)
                          //                  bit4 - знак микширования UCH канала
} MIXER_STRUCT;

// Описание записи о полетных режимах
typedef struct {
   unsigned char FMODE_NAME;           // Номер имени полетного режима (выбор из стандартных)
   unsigned char CH_TRIMMER[CH_COUNT]; // Триммеры каналов
   CURVE_STRUCT CURVE[CH_COUNT];       // кривые каналов полетного режима
   MIXER_STRUCT MIXER[CH_COUNT*5];     // MIXER - микшеры полетного режима, по 5 на канал
} FMODE_STRUCT;

// Описание записи о пользовательских каналах управления используемых в модели
typedef struct {
   signed char UCH_LEFT;  // Крайнее левое значение пользовательского канала, значение в % -128.. +127 
   signed char UCH_RIGHT; // Крайнее правое значение пользовательского канала, значение в % -128.. +127
} UCH_STRUCT;

// Описание записи о модели
typedef struct {
    unsigned char       MODEL_TYPE;       // Тип модели: 01- самолет, 02- вертолет
    unsigned char       MODEL_NAME[8];    // Имя модели
    unsigned char       FMODE_COUNT;      // Количество заданных полетных режимов
    unsigned int        MODEL_FLYTIMER;   // Значение обратного таймера на полет модели
    unsigned int        MODEL_LIVETIMER;  // Общее время полета модели
    unsigned char       MODEL_CH_COUNT;   // количество используемых физических каналов моделью
    unsigned int        CH_EPL[CH_COUNT]; // левые крайние точки физических каналов
    unsigned int        CH_EPR[CH_COUNT]; // правые крайние точки физических каналов
    unsigned char       UCH_COL;          // количество используемых UCH каналов в модели
    UCH_STRUCT          UCH[UCH_COUNT];   // информация о каждом из 14 каналов UCH    
    FMODE_STRUCT        FMODE[3];         // Информация о полетных режимах    
} MODEL_INFO_STRUCT;


MODEL_INFO_STRUCT rmodel;


далее описываю массив меню:

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

flash const MENU_STRUCT menu[43]={
//numitem, itemstr           , nextitem, previtem, upitem, downitem,  *pvar                   , partype
{    0,   "MAIN MENU      >" ,     0   ,     0   ,    0  ,     10  ,  0                       ,     0    },
{   10,   "MODEL          >" ,    20   ,     0   ,    0  ,     11  ,  0                       ,     0    },
{   20,   "SYSTEM         >" ,     0   ,    10   ,    0  ,     21  ,  0                       ,     0    },
    // подменю MODEL
{   11,   "NEW            >" ,    12   ,     0   ,   10  ,      0  ,  0                       ,     0    },
{   12,   "SELECT         >" ,    13   ,    11   ,   10  ,      0  ,  0                       ,     0    },
{   13,   "EDIT           >" ,    14   ,    12   ,   10  ,     31  ,  &rmodel.MODEL_NAME      ,    10    },
{   14,   "COPY           >" ,    15   ,    13   ,   10  ,      0  ,  0                       ,     0    },
{   15,   "RESET          >" ,    16   ,    14   ,   10  ,      0  ,  0                       ,     0    },
{   16,   "DELETE         >" ,     0   ,    15   ,   10  ,      0  ,  0                       ,     0    },
    // подменю SYSTEM
{   21,   "ALARM          >" ,    22   ,     0   ,   20  ,      0  ,  0                       ,     0    },
{   22,   "TIMERS         >" ,    23   ,    21   ,   20  ,      0  ,  0                       ,     0    },
{   23,   "DISPLAY        >" ,    24   ,    22   ,   20  ,      0  ,  0                       ,     0    },
{   24,   "CALIBRATION    >" ,    25   ,    23   ,   20  ,      0  ,  0                       ,     0    }, 
{   25,   "TX-RX TEST     >" ,    26   ,    24   ,   20  ,      0  ,  0                       ,     0    },
{   26,   "VERSION        >" ,     0   ,    25   ,   20  ,      0  ,  0                       ,     0    },
    // подменю MODEL - EDIT                                                                                  
{   31,   "TYPE           =" ,    32   ,     0   ,   13  ,      0  ,  &rmodel.MODEL_TYPE      ,     0    },
{   32,   "NAME           =" ,    33   ,    31   ,   13  ,      0  ,  &rmodel.MODEL_NAME      ,    10    },
{   33,   "TIMERS         >" ,    34   ,    32   ,   13  ,     41  ,  &rmodel.MODEL_LIVETIMER ,     9    },
{   34,   "CHANNELS       >" ,   36   ,    33   ,   13  ,     51  ,  &rmodel.MODEL_CH_COUNT  ,     1    },
{   36,   "FLY MODES      >" ,     0   ,    34   ,   13  ,     71  ,  &rmodel.FMODE_COUNT     ,     1    },
    // подменю MODEL - EDIT - TIMERS
{   41,   "FLY TIMER      =" ,    42   ,     0   ,   33  ,      0  ,  &rmodel.MODEL_FLYTIMER  ,     9    },
{   42,   "LIVETIMER      =" ,    43   ,    41   ,   33  ,      0  ,  &rmodel.MODEL_LIVETIMER ,     9    },
{   43,   "RESET FLY TIMER " ,     0   ,    42   ,   33  ,      0  ,  0                       ,     0    },
    // подменю MODEL - EDIT - CHANNELS                             
{   51,   "CH COUNT       =" ,    52   ,     0   ,   34  ,      0  ,  &rmodel.MODEL_CH_COUNT  ,     1    },
{   52,   "END POINTS     >" ,     0   ,    51   ,   34  ,     81  ,  0                       ,     0    },
    // подменю MODEL - EDIT - FLY MODES                          
{   71,   "FLY MODE COUNT =" ,    72   ,     0   ,   36  ,      0  ,  &rmodel.FMODE_COUNT     ,     1    },
{   72,   "FLY MODE EDIT  >" ,     0   ,    71   ,   36  ,      0  ,  0                       ,     0    },
    // подменю MODEL - EDIT - CHANNELS - END POINTS
{   81,   "CH1 LEFT       =" ,     82  ,     0   ,   52  ,      0  ,  &(rmodel.CH_EPL[0])       ,     4    },
{   82,   "CH1 RIGHT      =" ,     83  ,    81   ,   52  ,      0  ,  &rmodel.CH_EPR[0]       ,     4    },
{   83,   "CH2 LEFT       =" ,     84  ,    82   ,   52  ,      0  ,  &rmodel.CH_EPL[1]       ,     4    },
{   84,   "CH2 RIGHT      =" ,     85  ,    83   ,   52  ,      0  ,  &rmodel.CH_EPR[1]       ,     4    },
{   85,   "CH3 LEFT       =" ,     86  ,    84   ,   52  ,      0  ,  &rmodel.CH_EPL[2]       ,     4    },
{   86,   "CH3 RIGHT      =" ,     87  ,    85   ,   52  ,      0  ,  &rmodel.CH_EPR[2]       ,     4    },
{   87,   "CH4 LEFT       =" ,     88  ,    86   ,   52  ,      0  ,  &rmodel.CH_EPL[3]       ,     4    },
{   88,   "CH4 RIGHT      =" ,     89  ,    87   ,   52  ,      0  ,  &rmodel.CH_EPR[3]       ,     4    },
{   89,   "CH5 LEFT       =" ,     90  ,    88   ,   52  ,      0  ,  &rmodel.CH_EPL[4]       ,     4    },
{   90,   "CH5 RIGHT      =" ,     91  ,    89   ,   52  ,      0  ,  &rmodel.CH_EPR[4]       ,     4    },
{   91,   "CH6 LEFT       =" ,     92  ,    90   ,   52  ,      0  ,  &rmodel.CH_EPL[5]       ,     4    },
{   92,   "CH6 RIGHT      =" ,     93  ,    91   ,   52  ,      0  ,  &rmodel.CH_EPR[5]       ,     4    },
{   93,   "CH7 LEFT       =" ,     94  ,    92   ,   52  ,      0  ,  &rmodel.CH_EPL[6]       ,     4    },
{   94,   "CH7 RIGHT      =" ,     95  ,    93   ,   52  ,      0  ,  &rmodel.CH_EPR[6]       ,     4    },
{   95,   "CH8 LEFT       =" ,     96  ,    94   ,   52  ,      0  ,  &rmodel.CH_EPL[7]       ,     4    },
{   96,   "CH8 RIGHT      =" ,      0  ,    95   ,   52  ,      0  ,  &rmodel.CH_EPR[7]       ,     4    },
// 100
};
И при компиляции у меня не понятки !
почему то меню которое я объявил flash const - то есть константа которую нужно хранить в памяти программ - помещается в RAM !!
соответственно сжирает от него хороший кусочек !!

Странно ! переменная rmodel объявлена в RAM адреса у нее не меняются (структура постоянна в размерах)...

я чтото упустил в объявлении массива меню ?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 11:00:10
The Borg
The correct declaration must be:

flash MENU_STRUCT menu[43]={...

Also enable the "Store Global Constants in FLASH Memory" option in Project|Configure|C Compiler|Code generation.
Otherwise const will always be located in RAM.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 13:54:37
ВитГо
The Borg писал(а):The correct declaration must be:

flash MENU_STRUCT menu[43]={...

Also enable the "Store Global Constants in FLASH Memory" option in Project|Configure|C Compiler|Code generation.
Otherwise const will always be located in RAM.
Первое помоему не совсем правильно.. но попробовал - эффекта нет :-(
Второе проверил первым делом.. галочка стоит...

версия кодевижн 2.03.4 Стандарт

что еще может быть ?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 14:18:00
ВитГо
галочку "Хранить константы во Flash" ставлю\снимаю - на размер кода вообще не влияет :-(

Кто нить может откомпилить мой проект у себя и посмотреть сколько памяти в RAM съедается ?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 14:39:54
ВитГо
Поменял объявление itemstr c unsigned char *itemstr на unsigned char itemstr[]; и массив меню сразу оказался во Flash памяти !!
там где ему и нужно было быть..
нужно бы отметить этот момент где нить в ЧАВО..

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 16:41:23
ValBag
avreal писал(а):typedef struct {
unsigned cnt0 : 4,
cnt1 : 3,
mode : 1; // в одном байте 4-битная переменная, 3-битная переменная и однобитный флаг
} cnt_t;

cnt_t c;

unsigned foo()
{
if(c.mode) {
++c.cnt0;
} else {
c.cnt1 += 3;
}
return c.cnt0;
}
Существует ли стандартный метод доступа к отдельному биту в битовом поле? (длина поля больше 1, например: cnt0, cnt1)

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 17:40:03
ARV
я так понимаю, битовое поле представляется как обычное число "укороченного" размера, т.е. достать его биты можно так же, как и с обычным числом:

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

if(c.cnt0 & 2){
// если второй бит равен 1 - что-то делаем
} 

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 17, 2010 17:49:48
ValBag
ARV писал(а):if(c.cnt0 & 2){
// если второй бит равен 1 - что-то делаем
}
Т. е. "ручной" метод. ...И, если нужно записать бит в битовое поле, то анализируем записываемый бит и в зависимости от этого формируем соответствующую маску с записью в нужное место?