Страница 3 из 75

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Вс окт 19, 2014 14:48:01
ARV
Нет в Си булевских типов и переменных! Есть только ЧИСЛОВЫЕ результаты любых выражений, даже логических! Не фантазируйте понапрасну!

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Вс окт 19, 2014 16:12:06
COKPOWEHEU
Приходим к выводу, что результат выражения a<b не имеет типа. Чтож, какая-то логика в этом есть.

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Вс окт 19, 2014 20:40:34
ARV
Я вам уже говорил, что тип результата определяется типом операндов в выражении. Ну простите, наконец, книгу какую-либо по Си!

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Вс окт 19, 2014 22:31:52
COKPOWEHEU
Вообще-то это я писал, что тип скорее всего определяется типом операндов:
COKPOWEHEU писал(а):Само по себе оно не имеет типа (в ассемблерном виде обрабатывается как блок if с присвоением 1 либо 0), но по логике языка тип тот же, что у аргументов, тем более что по факту операция сравнения - вычисление разности без записи результата.
Но, применительно к AVR (насчет остального Си не знаю), результат выражения не имеет типа, так как является не математическим выражением, а результатом выполнения ветвления, которое, в зависимости от типа результата, может принимать разный вид. Посмотрите ассемблерный код присвоения этого выражения байтовой переменной и отдельному биту в байте. Кстати, во втором случае ассемблерный код выглядит довольно странно.
И определитесь, наконец, что пытаетесь обсуждать: специфику языка или конкретный вопрос.

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 09:39:48
sirha
Обьясните что делает оператор return,посмотрел в книге у Лебедева не понил его суть,
если можете то как можно проще расскажите

к примеру

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

void function1 (void)
{
if (...)

{..... return;
.....PORTA.1=1;
}
if (...)
{
}
void function2(void)
{}


}
что тут делает return?
правильно ли я понимаю:
выполнится то что до return,после выполнится следующий оператор if?,
или же будет выход из function1 в function2???

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:00:06
ARV
return всегда завершает текущую функцию и осуществляет выход из нее. после исполнения return никакие нижеидущие операторы в функции не выполняются

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:11:13
sirha
ARV писал(а):после исполнения return никакие нижеидущие операторы в функции не выполняются
Наконец то вы мне помогли :) ,спс,вы меня не ругайте за то что я лезу в сложности,работа у меня такая
приходиться иногда руками собирать сложные вещи,мне самому очень обидно что я иногда чего то не понимаю,но я вам обещаю что я все равно разберусь с простым)). :)

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:14:00
ARV
я помогал вам и ранее, просто вы не хотели это признавать :)

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:46:30
sirha
помогите мне с кнопкой ,хочеться разобраться с этой кнопкой,мучиет она меня,помогите мне пожалуйста.
хочеться начать вот с этого куска кода,суть в том что одной кнопкой я хочу выполнить две команды
зажечь и погасить светодиод,при длинном нажатии тоже самое с другим светодиодом
Сам код:

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

#include <mega8.h>
#define BTN_LOCK_TIME 		30					
#define BTN_LONG_TIME		1000
#define BTN_PORT			PORTB				
#define BTN_PIN 			PINB					
#define BTN_LINE		      (1<<0)			   

						
	#define BTN_SHRT		(1<<0)
	#define BTN_LONG		(1<<4)			
	
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    
    static unsigned char LockCoun;                   
    static unsigned char LongCoun;                    
    static unsigned char LastState;                  
    static unsigned char BtnLockBit; 
                
    char mask = 0;
    if (! (BTN_PIN & BTN_LINE))    mask = BTN_SHRT;

    if (mask){                                 
        if (LockCoun < (BTN_LOCK_TIME/10)){      
            LockCoun++;
            return;                               
        }

        LastState = mask;
        BtnLockBit =1;                                        

        if (LongCoun >= (BTN_LONG_TIME/10))									
            return;									

        if (++LongCoun >= (BTN_LONG_TIME/10))	
            BtnFlags |= (LastState<<4);			
    }
    				
    else{										
         if (  LockCoun --;) {
            return;								
        }

        if (! BtnLockBit)						
            return;								

        if (LongCoun < (BTN_LONG_TIME/10))
            BtnFlags |= LastState;				

        BtnLockBit =0;							
        LongCoun = 0;							
    }
}

void BtnInit (void)
{
	BTN_PORT |= BTN_LINE;
}

unsigned char BtnGet (void)
{
    char temp;
	#asm("cli")
	temp = BtnFlags;
	BtnFlags = 0;
	#asm("sei")
	return temp;
}

void main(void)
{
    
    ASSR=0x00;
    TCCR2=0x0F;
    TCNT2=0x00;
    OCR2=0x4e;
    TIMSK=0x80;
    BtnInit ();   
    DDRB = 0x06;

   
    #asm("sei")
    while (1)
    {
    
      button = BtnGet ();
                  
      if (button == BTN_SHRT)   PORTB ^= 0x02; 
      if (button == BTN_LONG)   PORTB ^= 0x04;      
    }
}
это конечно же не мой код ((

вообщем не буду писсиместичным)

итак если я что то не так напишу поправте меня или помогите потомучто я еще новичек:

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

#include <mega8.h>
включаем настройки 8 меги (частота и так далее (правдо что именно включается еще я не знаю)
-------------------------------------------------

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

#define BTN_LOCK_TIME 	30	 
присваеваем к названию BTN_LOCK_TIME число 30

BTN_LOCK_TIME=30
---------------------------------------------------------

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

#define BTN_LONG_TIME		1000
присваеваем к названию BTN_LONG_TIME число 1000

BTN_LONG_TIME=1000
-------------------------------------------------------

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

#define BTN_PORT			PORTB
BTN_PORT =PORTB -РЕГИСТР ВЫХОДА
------------------------------------------------------

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

#define BTN_PIN 			PINB


BTN_PIN = PINB (РЕГИСТР ВХОДА) К ПРИМЕРУ С ПОМОЩЬЮ КНОПОК
---------------------------------------------------

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

#define BTN_LINE		      (1<<0)
(1<<0) -сдвигаем 1 на ноль бит влево

так как это ATMEGA8 то то у нее на выходе PORTD,PORTB 8 бит

(1<<0) = 0x01 -шестнадцатиричный код ; либо 0b00000001 - двоичный код

---------------------------------------------------------

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

#define BTN_SHRT		(1<<0)
BTN_SHRT =0x01;
-----------------------------------------------------

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

	#define BTN_LONG		(1<<4)
BTN_LONG=(1<<4) - сдвигаем 1 влево на 4 бита получаем

BTN_LONG=0x10 ; или 0b00010000

НУ ВОТ ВРОДЕ С ЭТОЙ ЧАСТЬЮ ЗАКОНЧИЛ

ОТПИШИТЕСЬ ПРАВИЛЬНО ЛИ Я ВСЕ ПОНИЛ



---------------------------------------------------------------------------------------------------------------

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:52:26
Pink-Pank
понИл правильно.
Особенно в части
правдо что именно включается еще я не знаю

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 10:56:18
sirha
Pink-Pank писал(а):понИл правильно.
Особенно в части
правдо что именно включается еще я не знаю
обязательно надо подстебнуть))),а если серьезно?

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 11:23:37
ARV
а если серьезно, ответьте на вопрос: вам кнопку обязательно через прерывния или главное, чтобы работало? не первый раз, между прочим, спрашиваю. нельзя хвататься за 50 проблем сразу, решайте их по одной. не знаете, что там "включается" - разберитесь с этим. не знаете, какие там биты ставятся - разберитесь с этим. а когда дойдет до того, что вы все знаете - тогда начинайте думать о кнопке:

1. надо отличить нажатие кнопки от дребезга
2. надо отличить долгое нажатие кнопки от краткого
3. работу с кнопкой лучше всего обернуть в функцию, которая будет возвращать 0, если не нажата кнопка, 1 если нажата кратко и 2, если нажата долго.

и так далее, шаг за шагом, последовательно от общего к нюансам. я уже вам рекомендовал, по-моему, принцип нисходящего программирования

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 11:26:20
sirha
ARV писал(а):а если серьезно, ответьте на вопрос: вам кнопку обязательно через прерывния
хочу через прерывания

1. надо отличить нажатие кнопки от дребезга
2. надо отличить долгое нажатие кнопки от краткого
3. работу с кнопкой лучше всего обернуть в функцию, которая будет возвращать 0, если не нажата кнопка, 1 если нажата кратко и 2, если нажата долго.

буду имметь ввиду спс

помогите плиииз :cry:


Pink-Pank писал(а):понИл правильно.
Особенно в части
правдо что именно включается еще я не знаю
обязательно надо подстебнуть))),а если серьезно?

вообщем вторая часть кода:

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

interrupt [TIM2_COMP] void timer2_comp_isr(void) 

{}

void main(void)

{TCCR2=0x0F;
    OCR2=0x4e;
   TIMSK=0x80;
    BtnInit ();   
    DDRB = 0x06;
  #asm("sei")


}
Выполняется прерывание по совпадению счетчика TCNT2 и OCR2- регистр сравнения

как токо они станут равны то начнется прерывание

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

TCCR2=0x0F;
- регистр управления счетчиком

в двоичной TCCR2=1111 - из таблицы включены cs2 cs1 cs0 - 111 - делитель 1024

кварц у меня 8000 кгц

щитаем период тактовой частоты 1024/8000000=0.128 мс

1 такт таймера это 0.128 мс

мы выбираем частоту 100 гц

отсюда период = 10 мс - 100 гц


за 10 мс

10/0,128 мс =78 тактов

отсюда

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

OCR2=0x4E;
TCCR2=1111

4 бит и 6 бит говорят о режиме счетчика

1 и 0 - выбран режим СТС( сброс при совпадении)

TIMSK=0x80;
TIMSK=0b10000000

включен 7 бит - флаг OCIE2 разрешение прерывания по событию " совпадение" таймера /счетчика Т2

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

BtnInit ();
- вызов этой функции.

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

DDRB = 0x06;
DDRB =110

делаем 1 и 2 бит порта т.е ставим PB.1 и PB.2 на выход

ну и наконец то разрешаем долгожданное прерывание

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

#asm("sei")

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 12:00:35
Pink-Pank
..ять!!!! (здесь должен быть трехэтажный мат) Вы читать даташиты научитесь когда-нибудь или нет?
Кто разрешать прерывания будет?
Что Вы мечетесь, как .. ?

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 14:10:08
sirha
Pink-Pank писал(а):..ять!!!! (здесь должен быть трехэтажный мат)
Кто разрешать прерывания будет?
.?
:shock: :))) :))) :)))успокойтесь, А вам не пришло в голову что я просто не успел это расписать,я был занят,кстати на форуме мат запрещен

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

 static unsigned char LockCoun;                   
    static unsigned char LongCoun;                    
    static unsigned char LastState;                  
    static unsigned char BtnLockBit; 
                
обьясните что такое static unsigned char-- это вроде локальные переменные,но когда их обьявляют и для чего?,я прочитал что это:

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

а чем тогда просто unsigned char отличается не пойму в чем разница?

к примеру


защита от дребезга как я понил:

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

  if (mask){                                    
        if (LockCoun < (BTN_LOCK_TIME/10)){      
            LockCoun++;
            return;                             
        }
если mask истина = 1 то

{
если счетчик lockcoun <3 мс то

каждый раз прибавляем 1

и выходим из функции

}

LockCoun++; к примеру если было бы так:

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

unsigned char LockCoun;
правильно ли я понимаю что при выходе из функции LockCoun не сохранил бы свое значение в

отличии от обьявления:

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

static unsigned char LockCoun;

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 24, 2014 15:59:55
Pink-Pank
Вы там говорили, Лебедева читали?
Тогда прочтите его еще раз со страницы 178 (глава Переменные) и со страницы 200 (глава Типы данных)

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Сб окт 25, 2014 11:49:34
sirha
Прочел я про глобальные и локальные переменные)))

интересно что если я пишу

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

static unsigned char
до функции то в протеусе все равно все работает,а везде у лебедева написано что пишутся в функции

поидее если даже я пишу unsigned char - обьявляю как глобально то тоже все работает- ну это мне

понятно,зачем автор кода тогда замарачивается и пишет static?

я понимаю разницу static от глобальных переменных , что она выполняеется и пишется токо в

функции,сохраняя свое значение в отличии от long ,если я пишу static не в

функции интересно в железе она заработает?,в симуляторе пашет,почему то компилируется без ошибок.

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

 char mask = 0;
зачем тут обьявлена char? это же неграмотно

-128 до 127

поидеи правильно было бы написать unsigned char - обьявив беззнаковые переменные

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Сб окт 25, 2014 12:05:47
Аlex
Неужели не лень было писать столько многобукаф, за место одного запроса в поисковике ? :)
И сразу же ссылка по теме - http://230100.msiu.ru/files/14976-quali ... tatic_span

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Сб окт 25, 2014 12:58:16
sirha
что это за функция?

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

unsigned char BtnGet (void)
{
   	....
}

Re: Нескольно простых вопросов о программировании AVR на Си.

Добавлено: Пт окт 31, 2014 12:24:27
yur4ik
Знатоки, прошу Вашей помощи :) Есть матричная клава, ее обработку сделал все пашет. Так вот с ее помощью задаю число, а потом пишу его в переменную key (unsigned int) . Переменная полностью совпадает с тем что ввел с клавы. Далее это число нужно умножить на регистр IRC1 и разделить на 100, по началу казалось фигней, но когда IRC1 умножаю на любое число походу происходит переполнение и в результате вижу совсем другой конечный результат. Переменная в которую пишу (f) имеет уже тип unsigned long int, но это так и не помогло :(
вот так вот делаю: f=(unsigned int)(ICR1*key/100);
Компилятор ругается мол переполнение: overflow is possible in 16 bit multiplication, casting to 'long' may be required
В чем я прокололся?