реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Где с флагами косяк?, Посмотрите код плс?
Коляй
сообщение Nov 17 2006, 18:51
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



Ребята, где то накосячил с флагами. Подскажите кто знает? Программа простая, только выводами дёргать. В ИАРе 4,12 в симуляторе нормально работает, регистр Р-15 меняется на 0 и 1. Прерывание нормально идет, сначала одна половина, потом другая. В Протеусе не идёт и на железе не идёт, точнее идёт с одного вывода, а хотелось бы по-очереди.
Если просто под "переключатель" отдельно переменную выделить, то идёт. Но хотелось бы один бит пользовать для этой цели.

Код
#include<io2313.h>
#include<avr_macros.h>
#include<iomacro.h>
#include<intrinsics.h>

unsigned int pol;
unsigned char sampl, interval;

__regvar __no_init char flags @15;
#define set_polar     flags|=(1<<0)
#define clr_polar     flags&=~(1<<0)


void pausa (unsigned long int p)
{
  while (p>0)
    p--;
}
#pragma vector=TIMER1_COMP1_vect
__interrupt void MyInterrupt (void)
{
  if(flags & (1 << 0))
  {
  PORTD_Bit2=0;
  pausa(0x10);
  PORTD_Bit0=0;pausa(pol);PORTD_Bit0=1;
  pausa(0x15);
  PORTD_Bit2;
  pausa(interval);
  PORTD_Bit3=0;pausa(sampl);PORTD_Bit3=1;
  clr_polar;
  }
  else
  {
   PORTD_Bit2=0;pausa(0x10);
   PORTD_Bit1=0;pausa(pol);PORTD_Bit1=1;
   pausa(0x15);
   PORTD_Bit2=1;
   pausa(interval);
   PORTD_Bit4=0;pausa(sampl);PORTD_Bit4=1;
   set_polar;
  }
  return;
}
int main( void )
{
  PORTD=0xFF;
  DDRD=0xFF;
  OCR1=0x6420;
  TIMSK=0x40;
  TCCR1B=0x09;
  
  __enable_interrupt();  
  while(1)
  {
    
  }

}


Сообщение отредактировал Коляй - Nov 17 2006, 18:54
Go to the top of the page
 
+Quote Post
viael
сообщение Nov 17 2006, 19:30
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 200
Регистрация: 10-04-06
Из: Украина,Запорожье
Пользователь №: 15 979



а че эти переменные pol,sampl, interval; ничем не инициализируются?
Go to the top of the page
 
+Quote Post
Коляй
сообщение Nov 17 2006, 19:53
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



Цитата(viael @ Nov 17 2006, 22:30) *
а че эти переменные pol,sampl, interval; ничем не инициализируются?

Подбираются при настройке.
Go to the top of the page
 
+Quote Post
Stefan
сообщение Nov 18 2006, 07:26
Сообщение #4


Участник
*

Группа: Новичок
Сообщений: 43
Регистрация: 17-06-06
Пользователь №: 18 139



Цитата(Коляй @ Nov 17 2006, 22:51) *
Ребята, где то накосячил с флагами. Подскажите кто знает? Программа простая, только выводами дёргать. В ИАРе 4,12 в симуляторе нормально работает, регистр Р-15 меняется на 0 и 1. Прерывание нормально идет, сначала одна половина, потом другая. В Протеусе не идёт и на железе не идёт, точнее идёт с одного вывода, а хотелось бы по-очереди.
Если просто под "переключатель" отдельно переменную выделить, то идёт. Но хотелось бы один бит пользовать для этой цели.

Код
#include<io2313.h>
#include<avr_macros.h>                  //Зачем? Все равно в программе не используется
#include<iomacro.h>
#include<intrinsics.h>

unsigned int pol;                               //Почему бы хоть здесь не инициализировать?
unsigned char sampl, interval;

__regvar __no_init char flags @15;
#define set_polar     flags|=(1<<0)    
#define clr_polar     flags&=~(1<<0)


void pausa (unsigned long int p)       //А используется с разными типами аргументов. Компилятор молчит?
{
  while (p>0)
    p--;
}
#pragma vector=TIMER1_COMP1_vect
__interrupt void MyInterrupt (void)
{                                                   //А статус не сохраняете?
  if(flags & (1 << 0))
  {
  PORTD_Bit2=0;
  pausa(0x10);
  PORTD_Bit0=0;pausa(pol);PORTD_Bit0=1;
  pausa(0x15);
  PORTD_Bit2;                                //Я не знал, что так можно. Но для чтения непонятно
  pausa(interval);
  PORTD_Bit3=0;pausa(sampl);PORTD_Bit3=1;
  clr_polar;
  }
  else
  {
   PORTD_Bit2=0;pausa(0x10);
   PORTD_Bit1=0;pausa(pol);PORTD_Bit1=1;
   pausa(0x15);
   PORTD_Bit2=1;
   pausa(interval);
   PORTD_Bit4=0;pausa(sampl);PORTD_Bit4=1;
   set_polar;
  }
  return;                                          //А это зачем?
}
int main( void )
{
  PORTD=0xFF;
  DDRD=0xFF;
  OCR1=0x6420;
  TIMSK=0x40;
  TCCR1B=0x09;
  
  __enable_interrupt();  
  while(1)
  {
    
  }

}
Go to the top of the page
 
+Quote Post
Abell
сообщение Nov 18 2006, 08:18
Сообщение #5


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Период прерывания по таймеру точно больше интервала pausa(pol) и остальных? В обработчики таких прерываний большие задержки ставить нельзя. Объяви в обработчике статический счетчик с интервалом задержки и при каждом вызове прерывания декрементируй, будет ноль - обрабатывай.


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
defunct
сообщение Nov 18 2006, 09:06
Сообщение #6


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



2 Коляй,

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

Плюс, как можно говорить о верном либо неверном поведении программы, если у вас все переменные от кототорых это поведение зависит - непроинициализированы?
Go to the top of the page
 
+Quote Post
Коляй
сообщение Nov 18 2006, 09:39
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



Цитата(Stefan @ Nov 18 2006, 10:26) *
//Я не знал, что так можно. Но для чтения непонятно


Конечно не можно. Вот так надо PORTD_Bit2=1; (На скорую руку порты просто вписал, а так они по другому в pindef.h определены.)

Экономия одного байта конечно не оправдана в такой программе, но кто знает, может надо будет дальше писать. Это пока только управление и никакой обработки.
Теперь уже воще ничего не понимаю. В АВР-студио всё нормально работает, а в протеусе опять один только канал работает.
ПРограмма работает на железе, но только с байтовой переменной в качестве флага.
Go to the top of the page
 
+Quote Post
Коляй
сообщение Nov 18 2006, 16:56
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



Если вот так битовую структуру создать, то всё нормально работает. Вопрос только как сделать что бы он в регистре (R15 например) эту структуру держал? А он её в ОЗУ кладёт. (в свойствах проекта отведён один регистр 15.) ....

Всё, разобрался, вот так нормально стало. Спасибо всем ответившим.

__regvar __no_init

volatile struct {
unsigned char Key :1;
unsigned char Menu :1;
unsigned char Enter :1;
unsigned char LCD :1;
unsigned char Auto :1;
unsigned char ZapretLCD :1;
unsigned char polar :1;
unsigned char Save :1;
} flag @15;

Сообщение отредактировал Коляй - Nov 18 2006, 17:04
Go to the top of the page
 
+Quote Post
prottoss
сообщение Nov 18 2006, 17:00
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Коляй @ Nov 18 2006, 23:56) *
Если вот так битовую структуру создать, то всё нормально работает. Вопрос только как сделать что бы он в регистре (R15 например) эту структуру держал? А он её в ОЗУ кладёт. По-моему верхняя строчка никак к этой структуре не относится... (в свойствах проекта отведён один регистр 15.)



volatile struct {
unsigned char Key :1;
unsigned char Menu :1;
unsigned char Enter :1;
unsigned char LCD :1;
unsigned char Auto :1;
unsigned char ZapretLCD :1;
unsigned char polar :1;
unsigned char Save :1;
}flag_type;



__regvar __no_init flag_type flags @15;


--------------------
Go to the top of the page
 
+Quote Post
Коляй
сообщение Nov 18 2006, 17:54
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



__no_init

volatile struct {
unsigned char Key :1;
unsigned char Menu :1;
unsigned char Enter :1;
unsigned char LCD :1;
unsigned char Auto :1;
unsigned char ZapretLCD :1;
unsigned char polar :1;
unsigned char Save :1;
} flag @15;

Вот так заработало (__reg_var убрал), но теперь и в ОЗУ обращается и R15 изменяется! Если только в ОЗУ, то всё нормально работает, а если только в R15, то работает один цикл и опять по старому, как будто R15 сбивается. (в Протеусе в самом начале наблюдается только один правильный импульс, а дальше неправильно). Специально АСМ посмотрел к R15 всего только три обращения. Да и программа то в "три" строчки. Чему там сбивать?
Go to the top of the page
 
+Quote Post
Коляй
сообщение Nov 21 2006, 00:25
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558



Упростил всё. Устанавливал бит так flag|=(1<<0);
Сбрасывал flag&=~(1<<0);
Регистр объявлял так.
__regvar __no_init unsigned char flag @ 15;
Но компилятор генерит вот такой код ...
clt
bld r15,b0 // очистка.

set
bld r15,b0// установка.

Он что, еб...я? С этим кодом не работает!

Заменил вот таким

ori r16,0x01;
mov r15,r16;

Всё заработало нормально.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 19:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01456 секунд с 7
ELECTRONIX ©2004-2016