delay_ms + прерывания?

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

delay_ms + прерывания?

Сообщение igor-x »

Добрый день

подскажите пож. почему во время серии delay_ms не принимаются данные из УАРТ - который работает по прерываниям.
delay_ms(100) используется для получения меандра для зуммера. кстати подскажите - возможно есть более культурное решение?
Реклама
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: delay_ms + прерывания?

Сообщение ChipKiller »

igor-x писал(а):подскажите пож. почему во время серии delay_ms не принимаются данные из УАРТ - который работает по прерываниям.
... наверное потому, что прерывания запрещены.
igor-x писал(а):кстати подскажите - возможно есть более культурное решение?
.. зависит от типа МК (который Вами не указан)
Реклама
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

ChipKiller писал(а):
igor-x писал(а):подскажите пож. почему во время серии delay_ms не принимаются данные из УАРТ - который работает по прерываниям.
... наверное потому, что прерывания запрещены.
igor-x писал(а):кстати подскажите - возможно есть более культурное решение?
.. зависит от типа МК (который Вами не указан)
прерывания разрешены 1 раз при запуске программы. я хотел уточнить - может delay_ms их запрещает?
МК - mega8.
Аватара пользователя
Yftul
Вымогатель припоя
Сообщения: 540
Зарегистрирован: Пт фев 20, 2009 12:26:26

Re: delay_ms + прерывания?

Сообщение Yftul »

Вероятно запрещает, раз не принимается. А вообще можно посмотреть ассемблерный листинг, codevision его сохраняет в директории с Вашей программой.
Реклама
Эиком - электронные компоненты и радиодетали
Vov123
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Re: delay_ms + прерывания?

Сообщение Vov123 »

Глобально разрешены,а по маске?
Реклама
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

Vov123 писал(а):Глобально разрешены,а по маске?
к сожалению, не знаю точно... в Cjdevision единственная команда управления прерываниями # asm sei
Реклама
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: delay_ms + прерывания?

Сообщение Engineer_Keen »

По маске это установка определенных битов в регистрах периферии, в данном случае биты RXCIE, TXCIE и UDRIE регистра UCSRB. Вы как UART настраивали???
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

Engineer_Keen писал(а):По маске это установка определенных битов в регистрах периферии, в данном случае биты RXCIE, TXCIE и UDRIE регистра UCSRB. Вы как UART настраивали???
Uart настраивал с помощью мастера Codevision - приемник с прерываниями, передатчик без прерываний.
Аватара пользователя
romazan
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Чт май 21, 2009 13:54:07
Откуда: Москва
Контактная информация:

Re: delay_ms + прерывания?

Сообщение romazan »

В регистре SREG седьмой бит в лог. 1 установил?
Медиандр можно с помщью ШИМа, на таймере, сделать и не загружать проц примитивными задержками.
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

igor-x писал(а):
Engineer_Keen писал(а):По маске это установка определенных битов в регистрах периферии, в данном случае биты RXCIE, TXCIE и UDRIE регистра UCSRB. Вы как UART настраивали???
Uart настраивал с помощью мастера Codevision - приемник с прерываниями, передатчик без прерываний.
Ну так какой результат?! Получилось?! У меня такая же проблема.
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

Ну так какой результат?! Получилось?! У меня такая же проблема.
очень давно это было. уже и не помню про какой из моих девайсов все это написано.
если не ошибаюсь - в тот раз не были разрешены прерания вообще asm sei
а возможно и программа была построена неправильно
Последний раз редактировалось igor-x Пн апр 15, 2013 12:31:26, всего редактировалось 1 раз.
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

Ну выше написано, что установлены 1 раз после инициализации как мастер кодевижина создал. У меня так же. Еще в мастеровской функции прерывания есть #asm("cli") и #asm("sei"), т.е. запрещает и потом же разрешает. После компиляции посмотрел сгенерированный ассемблерный код, так там есть в каждой функции прерывания в начале и конце IN R30,SREG и OUT SREG,R30. В ассемблере мало разбираюсь, но предполагаю, что это и есть разреш./запрет прерывания...
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

сейчас не помню - возможно и ошибка программе была
положите сюда ваш исходник , может что припомню - может похожая ошибка
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

Спойлер

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

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 24.10.2012
Author  : 
Company : 
Comments: 


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>
// Alphanumeric LCD functions
#include <lcd.h>

 
#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
   // special case for receiver buffer size=256
   if (++rx_counter == 0) rx_buffer_overflow=1;
#else
   if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      }
#endif
   }
}
            
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
        

// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>

#include <delay.h>
//дисплей
#asm
.equ __lcd_port=0x18
#endasm  

//Запись пароля (1234) в ППЗУ
eeprom unsigned char EEP_PASS[4]={'1','2','3','4'}; 
eeprom unsigned int tm=10;
eeprom unsigned int tp=5;

//typedef unsigned char byte;         
// Declare your global variables here  
//Объявляются переменные           

unsigned int t5,t4,t2,t=0;             
                                   
                                   
 int tmc;

 unsigned char bufer[2];
 unsigned char rx_c[8];  
 unsigned char pass[5]; 
 


                               
void display()          //Функция отображение надписи "ONLINE" на LCD
{
 lcd_clear();           //Очистка дисплея
 lcd_putsf("ONLINE");   //Вывод надписи "ONLINE" на дисплей
 //lcd_gotoxy(0,1);       //Переход курсора на второй ряд и первый разряд досплея
}


//Таймер0 таймаута бездействия
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xFF;
// Place your code here
//while(1){
//delay_ms(1000);
//printf("  ");
//}

--t2;                   



}

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{  
// Reinitialize Timer2 value
TCNT2=0xFF;
// Place your code here

t4++;

if((t4==30) && (t5==0)){

//printf("tmc=%d", tmc);
lcd_gotoxy(0,1);           //перенос курсора
lcd_putsf("                ");    //вывод на дисплей "" 
lcd_gotoxy(0,1);           //перенос курсора
lcd_putsf("REQ");    //вывод на дисплей ""
sprintf(bufer,"%d",tmc);
lcd_gotoxy(4,1);
lcd_putsf("  ");
lcd_gotoxy(4,1);
lcd_puts(bufer);

tmc--;

if(tmc<0){
lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("                ");
lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("PING");    //вывод на дисплей ""
//delay_ms(1000);
//lcd_gotoxy(0,1);           //перенос курсора 
//lcd_putsf("    ");    //вывод на дисплей ""
printf("PING");
delay_ms(1000);

t5=1;
tmc=tp;
 }
t4=0;

}

if((t4==30) && (t5==1))

{

lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("PING");    //вывод на дисплей ""
sprintf(bufer,"%d",tmc);
lcd_gotoxy(5,1);
lcd_puts(bufer);
tmc--;
      
       if(tmc<0){  
                         

         PORTD.6=1;                              //на порте Д.6 установить лог.1   
         lcd_clear();                            //очистить дисплей  
         lcd_putsf("PING REQ ERROR!"); 
         lcd_gotoxy(0,1);               //перенос курсора
         lcd_putsf("RESET");                     //написать на ЖКИ "RESET"
         printf(" RESET ");
         delay_ms(1000);                         //и держать 1сек
         PORTD.6=~PORTD.6; 
         //lcd_clear();                            //очистить дисплей
       tmc=tp; 
       t5=2;      
      
 }


t4=0;
}     
  
}




// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
     
  
              
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=In 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=T 
PORTD=0x00;
DDRD=0xFE;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0=0x05;
TCNT0=0xFF;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0xFF;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x07;
TCNT2=0xFF;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x03;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
//TIMSK=0x00;
//TIMSK=0x01;
TIMSK=0x41;


// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 8

lcd_init(16);          //инициализация дисплея
tmc=tm;
printf("start");     //вывод в УАРТ "terminal= "

display();                //отображение надписи "онлайн"

#asm("sei")

while (1)                //бесконечный цикл (цыклическое выполнение бипа онлайн)
  {   
   if(t==0)              
    {
  
     delay_ms(1000);
    }  
    
   if((rx_counter!=0 && rx_buffer_overflow==0) || (rx_buffer_overflow==1 && rx_counter==0)){ 

     // printf("%s", rx_buffer); 

      
      if((rx_buffer[0]=='t') && (rx_buffer[1]=='m') && (rx_buffer[2]=='S') && (rx_buffer[3]=='=')) {       

       rx_c[0]=rx_buffer[4];
       rx_c[1]=rx_buffer[5];
       tm=atoi(rx_c);
       //printf("atoi-rxc=%d", atoi(rx_c));
       printf("NEW_tm=%d", tm);     
      }
      
      if((rx_buffer[0]=='t') && (rx_buffer[1]=='m') && (rx_buffer[2]=='R')) {
       printf("tm=%d", tm);
       } 
      
      if((rx_buffer[0]=='p') && (rx_buffer[1]=='a') && (rx_buffer[2]=='s') && (rx_buffer[3]=='s') && (rx_buffer[4]=='R')) { 

       pass[0]=EEP_PASS[0]; 
       pass[1]=EEP_PASS[1];
       pass[2]=EEP_PASS[2];
       pass[3]=EEP_PASS[3]; 
       pass[4]=NULL;  
       printf("PASS=%s", pass);    
      } 
      
      if((rx_buffer[0]=='P') && (rx_buffer[1]=='A') && (rx_buffer[2]=='S') && (rx_buffer[3]=='S')) { 
      EEP_PASS[0]=rx_buffer[4]; 
      EEP_PASS[1]=rx_buffer[5];
      EEP_PASS[2]=rx_buffer[6];
      EEP_PASS[3]=rx_buffer[7]; 
      
      pass[0]=EEP_PASS[0]; 
      pass[1]=EEP_PASS[1];
      pass[2]=EEP_PASS[2];
      pass[3]=EEP_PASS[3]; 
      pass[4]=NULL;   
      printf("new_PASS=%s", pass);
      }



      if((rx_buffer[0]=='s') && (rx_buffer[1]=='r') && (rx_buffer[2]=='v') && (rx_buffer[3]=='O') && (rx_buffer[4]=='N')) {
       printf("reciveON"); 
       t5=0;
       t4=0;
       
       tmc=tm;
       }          
                                
      rx_counter=0;  
      for(rx_wr_index=0; rx_wr_index<=sizeof(rx_buffer);){
      rx_buffer[rx_wr_index++]=NULL; 
      } 
      rx_wr_index=0;
      rx_buffer_overflow=0;
   }   
   if(rx_counter!=0 && rx_buffer_overflow!=0){  
   printf("toLong");   
    for(rx_wr_index=0; rx_wr_index<=sizeof(rx_buffer);){
      rx_buffer[rx_wr_index++]=NULL; 
      } 
      rx_wr_index=0;
      rx_buffer_overflow=0;
      rx_counter=0; 
      }  
     
  }                      
}                        
Если данные приходят на приемник усарта во время delay_ms() , то потом уже приемник не принимает ничего...
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

есть небольшое подозрение что это может происходить изза работы с Емпром.

упростите свой пример до минимума - прием байта - переключение светодиода и больше ничего.
и еще подозрение на условие
if(t==0)
{

delay_ms(1000);
}
возможно переменная t остается =0 навсегда
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

Нет, t там не при чем. Я его убрал и еепром тоже. Чтение буфера приемника заменил на getchar().
Такое впечатление, что после приема во время задержки понижается приоритет прерывания атмеги, хотя сказано, что все прерывания у меги8 имеют одинаковый приоритет...
Спойлер

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

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 24.10.2012
Author  : 
Company : 
Comments: 


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>
// Alphanumeric LCD functions
#include <lcd.h>

 
#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
   // special case for receiver buffer size=256
   if (++rx_counter == 0) rx_buffer_overflow=1;
#else
   if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      }
#endif
   }
}
            
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
        

// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>

#include <delay.h>
//дисплей
#asm
.equ __lcd_port=0x18
#endasm  



//typedef unsigned char byte;         
// Declare your global variables here  
//Объявляются переменные           

//eeprom unsigned int tm=10;
//eeprom unsigned int tp=5;
unsigned int tm=10;
unsigned int tp=5;

unsigned int t5,t4,t2;             
                                   
                                   
 int tmc;

 unsigned char bufer[2];
 //unsigned char rx_c[8];  
 //unsigned char pass[5]; 
 


                               
void display()          //Функция отображение надписи "ONLINE" на LCD
{
 lcd_clear();           //Очистка дисплея
 lcd_putsf("ONLINE");   //Вывод надписи "ONLINE" на дисплей
 //lcd_gotoxy(0,1);       //Переход курсора на второй ряд и первый разряд досплея
}


//Таймер0 таймаута бездействия
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xFF;
// Place your code here
//while(1){
//delay_ms(1000);
//printf("  ");
//}

--t2;                   



}

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{  
// Reinitialize Timer2 value
TCNT2=0xFF;
// Place your code here

t4++;

if((t4==30) && (t5==0)){

//printf("tmc=%d", tmc);
lcd_gotoxy(0,1);           //перенос курсора
lcd_putsf("                ");    //вывод на дисплей "" 
lcd_gotoxy(0,1);           //перенос курсора
lcd_putsf("REQ");    //вывод на дисплей ""
sprintf(bufer,"%d",tmc);
lcd_gotoxy(4,1);
lcd_putsf("  ");
lcd_gotoxy(4,1);
lcd_puts(bufer);

tmc--;

if(tmc<0){
lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("                ");
lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("PING");    //вывод на дисплей ""
//delay_ms(1000);
//lcd_gotoxy(0,1);           //перенос курсора 
//lcd_putsf("    ");    //вывод на дисплей ""
printf("PING");
delay_ms(1000);

t5=1;
tmc=tp;
 }
t4=0;

}

if((t4==30) && (t5==1))

{

lcd_gotoxy(0,1);           //перенос курсора 
lcd_putsf("PING");    //вывод на дисплей ""
sprintf(bufer,"%d",tmc);
lcd_gotoxy(5,1);
lcd_puts(bufer);
tmc--;
      
       if(tmc<0){  
                         

         PORTD.6=1;                              //на порте Д.6 установить лог.1   
         lcd_clear();                            //очистить дисплей  
         lcd_putsf("PING REQ ERROR!"); 
         lcd_gotoxy(0,1);               //перенос курсора
         lcd_putsf("RESET");                     //написать на ЖКИ "RESET"
         printf(" RESET ");
         delay_ms(1000);                         //и держать 1сек
         PORTD.6=~PORTD.6; 
         //lcd_clear();                            //очистить дисплей
       tmc=tp; 
       t5=2;      
      
 }


t4=0;
}     
  
}




// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
     
  
              
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=In 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=T 
PORTD=0x00;
DDRD=0xFE;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0=0x05;
TCNT0=0xFF;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0xFF;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x07;
TCNT2=0xFF;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x03;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
//TIMSK=0x00;
//TIMSK=0x01;
TIMSK=0x41;


// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 8

lcd_init(16);          //инициализация дисплея
tmc=tm;
printf("start");     //вывод в УАРТ "terminal= "

display();                //отображение надписи "онлайн"

#asm("sei")

while (1)                //бесконечный цикл (цыклическое выполнение бипа онлайн)
  {   
  // if(t==0)              
   // {
     // printf("t=0");
     delay_ms(1000);
   // }  
     printf("rc=%c", getchar()); 
     
  }                      
}                        
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

хорошо, еще упрощаем пример:

while (1)

{ delay_ms(1000);

if (rx_counter!=0 )
{ читаем принятый байт; // или лучше если на экран то выводим еще и колич принятых байт rx_counter
выводим байт на экран или мелькаем светодиодом;
}

}
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

Немного уточню. Проблема эта возникает в основном, когда срабатывает прерывание по переполнению таймера (в данном случае таймер2), т.е. когда в этом сработавшем таймере доходит до delay_ms(1000), то если в этот момент (в течении 1сек) что-то отправить на контроллер (использую PROTEUS 7.10SP0, программу для приема и передачи данных COMPump, и нуль-модемный кабель (ком-порт--конвертер ком-юсб)), то контроллер будет выполнять программу дальше, но на дальнейший прием не будет реагировать, но на передачу работать будет! Если передавать на МК строго до или после задержки, то всё ОК, также если данные уже поступали в момент начала вып.задержки, то после её ок. продолжит выдавать из буфера то на чём прервался, а также будет реагировать на прием дальше.
А задержка в цикле while () особо не напрягает - пока еще на неё не попадал...

Проверил как меняются регистры UCSRB и SREG в этом случае. С UCSRB ничего не происходит(0х98), а SREG по выходу из прерывания принимает исходное значение (0х82).
Аватара пользователя
igor-x
Мудрый кот
Сообщения: 1817
Зарегистрирован: Пн ноя 29, 2010 15:58:43

Re: delay_ms + прерывания?

Сообщение igor-x »

А задержка в цикле while () особо не напрягает - пока еще на неё не попадал...
в приведенном мной примере, программа основное время(99.9 % времени выполнения.) будет висеть в delay.

ну и еще пожелание - не особо верить результатам в протеусе - попробуйте уже переходить на испытания в железе )
sbvp
Родился
Сообщения: 12
Зарегистрирован: Пт авг 21, 2009 21:00:12
Откуда: Bila Tserkva

Re: delay_ms + прерывания?

Сообщение sbvp »

Я пробовал Ваш пример (он и сейчас в исходнике), работает, как и раньше...
Я понимаю, но до железа пока еще рано - нужно хотя бы что-то написать для начала. Не думаю, что на эту функцию протеус сильно искажает результат...
Ответить

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