Обсуждаем контроллеры компании Atmel.
Ответить

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

Чт апр 20, 2017 21:45:31

блин как это понять. никак не переварю

как бы объяснить.

interrupt [бла бла бла] бла бла бла
{PORTB.0=~PORTB.0;}

void main (void)
бла бла бла
бла бла бла

while (1)
{
PORTB=digits[discharge[1]];
}

вот так присваиваю семисигменту нужную цифру. но нужно не изменять младший бит. он должен изменятся только в прерывании
Последний раз редактировалось mixon46 Чт апр 20, 2017 22:00:29, всего редактировалось 1 раз.

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

Чт апр 20, 2017 22:00:24

Можно скопировать состояние вашего бита, который вы не хотите менять, и включить его в переменную, которую вы хотите в порт вывести. Так же у AVR есть ассемблерные команды работы с каждым битом порта в отдельности, но это будет дольше работать)

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

Чт апр 20, 2017 22:02:40

я понимаю что можно. только не понимаю как. давно не занимался с codevision

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

Чт апр 20, 2017 22:15:14

4 буквы написать, остальное даже сам поисковик за тебя додумывает :
Изображение

Неужели проще сидеть и ждать, пока кто-нибудь догадается, что конкретно Вам нужно ?
Вложения
2017-04-20_23-20-42.png
(25.72 KiB) Скачиваний: 751

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

Чт апр 20, 2017 22:15:27

&= и |= в помощь

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

Чт апр 20, 2017 22:20:28

Аlex писал(а):4 буквы написать, остальное даже сам поисковик за тебя додумывает :

так вот и ищу же как решить эту проблему. только понять не могу
как я понимаю надо взять значение порта и присвоить ему значение но с маской на младший бит. как блин это сделать :(

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

Чт апр 20, 2017 22:29:56

mixon46 писал(а):надо взять значение порта и присвоить ему значение но с маской на младший бит. как блин это сделать
как говорите, так и записываете,
только не на русском языке, а на языке Си:
Код:
#define MASK 0x01
unsigned char data;

PORTB = (PORTB & MASK) | (data & ~MASK);
вот здесь о масках и т.п.: http://arv.radioliga.com/content/category/6/33/49/

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

Чт апр 20, 2017 22:37:56

Вам нужно сделать 2 операции.
1. Сброс всех битов, которые будут модифицироваться, с помощью "&" и маской.
2. Установка необходимых битов с помощью "|", маской будет являться само устанавливаемое значение.

Добавлено after 6 minutes 55 seconds:
ARV писал(а):& ~MASK
Этого можно не делать, если исходные данные не затрут "ненужный" бит.
Получится 2 операции - & с маской и "|" с исходными данными.

PS: Это не для ARV'а, а для ТС'а :)

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

Пт апр 21, 2017 11:42:41

Что-то я совсем потерялся, как получить доступ к глобальной переменной из функции.

пример

Код:
volatile bit s1; //

char function (char a, char b) {
     if (a == b) return 0;
}


Допустим я хочу внутри функции иметь доступ к s1, как ее передать туда и изменить там ума не приложу.
объявления типа bit в теле функций не работает, на char ругается, что это не char.
Создавать промежуточные переменные я не хочу, ибо bit это 1 бит, и в один байт в регистре можно 8 переменных пихнуть, а любая переменная это минимум 8 бит минимум и вся экономия коту под хвост.

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

Пт апр 21, 2017 12:09:54

jeka79 писал(а):Допустим я хочу внутри функции иметь доступ к s1, как ее передать туда и изменить там ума не приложу
глобальные переменные доступны ни же по коду в теле любых функций напрямую:
Код:
volatile bit s1; //

char function (char a, char b) {
     s1 = 1; // вот так
     if (a == b) return 0;
}
однако, проблемы, с которыми вы сталкиваетесь
jeka79 писал(а):объявления типа bit в теле функций не работает, на char ругается, что это не char
уже как бы намекают вам, что bit - это костыль, в стандарте Си нет такого типа. и зря вы им пользуетесь - уже сейчас у вас проблемы, а что потом будет? пользуйтесь только стандартными типами Си - будет вам счастье.

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

Пт апр 21, 2017 12:22:29

Прочитал в факе кодвижн bit это заюз младших регистров, если у меня булевые данные зачем мне использовать для их хранения обычные переменные, с каждой новой переменной код пухнет, а для меня крайне критична минимизация, поэтому в глобальной переменной типа bit удобно хранить такие данные, можно конечно и обычные переменные заюзать и побитно с ними работать, но это не очень удобно, с типом бит проще, с отдельным битом как с обычной переменной.
спс понял, что объявлять не надо, все заработало.

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

Пт апр 21, 2017 12:30:25

jeka79 писал(а):Допустим я хочу внутри функции иметь доступ к s1, как ее передать туда и изменить там ума не приложу
Глобальные переменные на то и глобальные, что их область видимости расширенная. Их не нужно никуда передавать, они видятся везде.

jeka79 писал(а):объявления типа bit в теле функций не работает
Естественно. Под локальные переменные выделяется область в стеке, при входе в функцию, а как компилятору выделить 1 бит ?
По этому, если компиляторы поддерживают битовый тип, то они могут быть только глобальными или статическими, чтобы линкер на этапе компиляции, заранее, выделил под них место.

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

Пт апр 21, 2017 12:34:27

AVR, я подумал и ваше решение подошло. Только я упростил. Так как в data младший бит уже равен 0 то можно проще

PORTB=data|(PORTB&0b00000001)

Решение нашлось. Спасибо))

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

Пт апр 21, 2017 12:35:53

jeka79 писал(а):если у меня булевые данные зачем мне использовать для их хранения обычные переменные, с каждой новой переменной код пухнет, а для меня крайне критична минимизация
А тут не совсем верно. Побитное хранение нескольких (до восьми штук в одном байте) флагов требует большего количества (читай, размера)кода, чем для каждой своей переменной. Хотя ОЗУ экономится, это да.

По крайней мере, для AVR это так.

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

Пт апр 21, 2017 12:40:56

mixon46 писал(а):Только я упростил. Так как в data младший бит уже равен 0 то можно проще
PORTB=data|(PORTB&0b00000001)
Решение нашлось. Спасибо))
Решение давно уже было дано :
Аlex писал(а):
ARV писал(а):& ~MASK
Этого можно не делать, если исходные данные не затрут "ненужный" бит.
Получится 2 операции - & с маской и "|" с исходными данными.
:)

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

Пт апр 21, 2017 12:45:37

WiseLord писал(а):Побитное хранение нескольких (до восьми штук в одном байте) флагов требует большего количества (читай, размера)кода, чем для каждой своей переменной
Набросал и маленький простенький пример.

Это компилируется в 206 байтов:
Спойлер
Код:
#include <avr/io.h>
#include <util/delay.h>

#include "pins.h"

typedef struct
{
    uint8_t a:1;
    uint8_t b:1;
    uint8_t c:1;
    uint8_t d:1;
} MyFlags;

int main(void)
{
    volatile MyFlags flags;

    flags.a = 0;
    flags.b = 1;
    flags.c = 0;
    flags.d = 0;

    while (1) {
        uint8_t x = flags.a;
        flags.a = flags.b;
        flags.b = flags.c;
        flags.c = flags.d;
        flags.d = x;
    }

    return 0;
}
А это - в 154 байта:
Спойлер
Код:
#include <avr/io.h>
#include <util/delay.h>

#include "pins.h"

typedef struct
{
    uint8_t a;
    uint8_t b;
    uint8_t c;
    uint8_t d;
} MyFlags;

int main(void)
{
    volatile MyFlags flags;

    flags.a = 0;
    flags.b = 1;
    flags.c = 0;
    flags.d = 0;

    while (1) {
        uint8_t x = flags.a;
        flags.a = flags.b;
        flags.b = flags.c;
        flags.c = flags.d;
        flags.d = x;
    }

    return 0;
}

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

Пт апр 21, 2017 12:55:20

WiseLord писал(а):А это - в 154 байта:
так там у вас аж целых 4 байта ОЗУ израсходовано!!! :shock:

:))) :beer:

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

Пт апр 21, 2017 13:10:41

На самом деле нет - видимо в таком простом примере компилятор это прямо в РОН крутил.

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

Пт апр 21, 2017 14:32:38

В общем bit рулит, не знаю почему, но только что переписал код на хранение 8 битов в переменной и в типе бит.
разница в 200 байт, при компиляции, для кода из 1 функции и проверки, 6 переменных.

выделил в регистре переменную:

Код:
register unsigned char t_buf = 0x00;


либо просто

Код:
bit flag1 = 0;
bit flag2 = 1;
.........


в функции с флагами делаю все просто
Код:
if (flag) flag = 1;

c переменной:

Код:
if (((t_buf) & (1<<0))) t_buf |= (1<<0);


При чем в асме при работе с bit всегда простые команды SBIS, CBI, а с переменной генерит кучу переходов.

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

Пт апр 21, 2017 14:35:04

Такую фигню :
Код:
if (flag) flag = 1;
даже самый глупый компилятор должен вырезать не глядя.
Ровно как и такую :
Код:
if (((t_buf) & (1<<0))) t_buf |= (1<<0);

:)
Ответить