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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Нет в Си булевских типов и переменных! Есть только ЧИСЛОВЫЕ результаты любых выражений, даже логических! Не фантазируйте понапрасну!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Приходим к выводу, что результат выражения a<b не имеет типа. Чтож, какая-то логика в этом есть.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Я вам уже говорил, что тип результата определяется типом операндов в выражении. Ну простите, наконец, книгу какую-либо по Си!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Вообще-то это я писал, что тип скорее всего определяется типом операндов:
COKPOWEHEU писал(а):Само по себе оно не имеет типа (в ассемблерном виде обрабатывается как блок if с присвоением 1 либо 0), но по логике языка тип тот же, что у аргументов, тем более что по факту операция сравнения - вычисление разности без записи результата.
Но, применительно к AVR (насчет остального Си не знаю), результат выражения не имеет типа, так как является не математическим выражением, а результатом выполнения ветвления, которое, в зависимости от типа результата, может принимать разный вид. Посмотрите ассемблерный код присвоения этого выражения байтовой переменной и отдельному биту в байте. Кстати, во втором случае ассемблерный код выглядит довольно странно.
И определитесь, наконец, что пытаетесь обсуждать: специфику языка или конкретный вопрос.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение sirha »

Обьясните что делает оператор return,посмотрел в книге у Лебедева не понил его суть,
если можете то как можно проще расскажите

к примеру

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

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

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


}
что тут делает return?
правильно ли я понимаю:
выполнится то что до return,после выполнится следующий оператор if?,
или же будет выход из function1 в function2???
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение sirha »

ARV писал(а):после исполнения return никакие нижеидущие операторы в функции не выполняются
Наконец то вы мне помогли :) ,спс,вы меня не ругайте за то что я лезу в сложности,работа у меня такая
приходиться иногда руками собирать сложные вещи,мне самому очень обидно что я иногда чего то не понимаю,но я вам обещаю что я все равно разберусь с простым)). :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

я помогал вам и ранее, просто вы не хотели это признавать :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение 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

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

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



---------------------------------------------------------------------------------------------------------------
Последний раз редактировалось sirha Пт окт 24, 2014 10:54:59, всего редактировалось 1 раз.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

понИл правильно.
Особенно в части
правдо что именно включается еще я не знаю
Fucking static initialization order fiasco
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение sirha »

Pink-Pank писал(а):понИл правильно.
Особенно в части
правдо что именно включается еще я не знаю
обязательно надо подстебнуть))),а если серьезно?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

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

Мой уютный бложик... заходите!
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение 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")
Последний раз редактировалось sirha Пт окт 24, 2014 14:19:57, всего редактировалось 1 раз.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

..ять!!!! (здесь должен быть трехэтажный мат) Вы читать даташиты научитесь когда-нибудь или нет?
Кто разрешать прерывания будет?
Что Вы мечетесь, как .. ?
Fucking static initialization order fiasco
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение 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;
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

Вы там говорили, Лебедева читали?
Тогда прочтите его еще раз со страницы 178 (глава Переменные) и со страницы 200 (глава Типы данных)
Fucking static initialization order fiasco
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение sirha »

Прочел я про глобальные и локальные переменные)))

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

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

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

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

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

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

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

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

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

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

-128 до 127

поидеи правильно было бы написать unsigned char - обьявив беззнаковые переменные
Последний раз редактировалось sirha Сб окт 25, 2014 12:06:28, всего редактировалось 1 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Неужели не лень было писать столько многобукаф, за место одного запроса в поисковике ? :)
И сразу же ссылка по теме - http://230100.msiu.ru/files/14976-quali ... tatic_span
Аватара пользователя
sirha
Вымогатель припоя
Сообщения: 550
Зарегистрирован: Ср авг 17, 2011 23:12:30

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

Сообщение sirha »

что это за функция?

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

unsigned char BtnGet (void)
{
   	....
}
Аватара пользователя
yur4ik
Вымогатель припоя
Сообщения: 613
Зарегистрирован: Сб окт 17, 2009 18:56:05
Откуда: РФ, Башкортостан г.Сибай
Контактная информация:

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

Сообщение 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
В чем я прокололся?
Нельзя всё знать, достаточно понимать.
Ответить

Вернуться в «AVR»