инициализируемся()
засыпаем()
просыпаемся по INT0()
включаем таймер ноль на отсчет секунд()
начинаем контроллировать выведенные провода на разрыв()
//один на обезвреживание, один на взрыв, пустышка 2 штука и ускорение в два раза таймера тоже 2 штука
и соответствено по окончанию таймера - взрываемся и ,соответственно, если перерезаются провода, тоже выполняем необходимое.
Все питается от аккумулятора. Играть люди могут долго. Вот зачем мне слип. Да и контроллер простаивает в это время, почему бы не спать..
Так вот в чем проблема, после засыпания мы уже не просыпаемся ни в какую. Таймеры со внешними прерываниями тоже тормозятся. Недосланyый асинхронный UART остается недосланным. -_-
Вообщем прошу помощи.
Пишу на AVR-GCC в Atmel studio. Из средств отладки на руках, что знаю, только proteus и uart-terminal в нем. Железо на мега8 тоже не собрано, да и в отладке это не особо и поможет. Студия отказывается отлаживать в симуляторе(свою неопытность не отрицаю), но она мне намекнула, что точки останова на этом контроллере не поддерживаются.
(еще были проблемы в proteus с прерываниями по возрастающему фронту с подтяжкой ноги к питанию и соединением ее через разрывной тумблер с корпусом. Просто подтянул к земле в протеусе, убрал подтяжку в порте, настроил на ниспадающий фронт-_-)
вот схема из протеуса и код, проект протеуса тоже.
приведу весь код
Код: Выделить всё
/*
* theBomb.c
*
* Created: 12.03.2015 20:37:09
* Author: andre
*/
/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#define _IN 0
#define _OUT 1
#define _PULLUP 1
#define _LOW 0
#define _HIGH 1
/* 9600 baud */
#define UART_BAUD_RATE 9600
#define uart_nextline uart_putc(13);
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "uart/uart.h"
volatile unsigned int cnt = 0;
volatile unsigned int seconds_counter =0;
volatile bool check_pull = false;
volatile unsigned int freq = 30;
void enable_timer0(bool enable);
void enable_int0(void);
void disable_int0(void);
void init_timer0(void);
void init_ports(void);
void set_check_led(void);
void do_explode(void);
void read_ports_work(void);
bool is_in_service_mode(void);
//названия портов в/в
//#define loop_until_bit_is_clear(port,bit) \ __asm__ __volatile__ ( \ "L_%=: " "sbic %0, %1" "\n\t" \ "rjmp L_%=" \ : /* no outputs */ : "I" (_SFR_IO_ADDR(port)), "I" (bit) )
//#define loop_until_bit_is_clear(port,bit) __asm__ __volatile__ ( "1: " "sbic %0, %1" "\n\t" "rjmp 1b" : /* no outputs */ : "I" (_SFR_IO_ADDR(port)), "I" (bit) )
//Interrupt Service Routine for INT0
ISR(INT0_vect)
{
//check service mode
//if (is_in_service_mode())
//return;
uart_puts("in INT0 ISR");
uart_nextline
disable_int0();
enable_timer0(true); // enable timer0
check_pull=true;
}
// Timer 0 overflow interrupt service routine
ISR(TIMER0_OVF_vect)
{
enable_timer0(false); // disable timer0
cnt++;
if (cnt>=freq)
{
cnt=0;
uart_puts("timer0 interrupt approx 1 sec");
uart_nextline
seconds_counter++;
if (seconds_counter>=30)
do_explode();
else
read_ports_work();
cli();
TCNT0 = 0;
sei();
}
enable_timer0(true);
}
//check all wires to be connected
bool check_system(void)
{
return true;
}
void enable_timer0(bool enable)
{
if (enable)
TIMSK |= ( 1 << TOIE0); // enable timer0;
else
TIMSK &= ~( 1 << TOIE0); // disable timer0
}
void enable_int0(void)
{
//initialize interrupts
GICR = (1<<INT0); // Enable INT0
MCUCR =( 1<<ISC01) | (0<<ISC00); // Trigger INT0 on falling edge
}
void disable_int0(void)
{
GICR&= ~(1<<INT0);
}
void init_timer0(void)
{
//initialize timers
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz (/255/30 to approx 1 sec) (tim0 ovf even 30 interrupt)
TCCR0=(1<<CS02) | (0<<CS01) | (1<<CS00);
// initialize counter
TCNT0 = 0;
}
void init_ports(void)
{
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(_IN<<DDB7) | (_IN<<DDB6) | (_IN<<DDB5) | (_IN<<DDB4) | (_IN<<DDB3) | (_IN<<DDB2) | (_IN<<DDB1)| (_IN<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=P Bit1=P Bit0=P
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (_PULLUP<<PORTB0);
// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out
DDRC=(_IN<<DDC6) | (_IN<<DDC5) | (_IN<<DDC4) | (_IN<<DDC3) | (_IN<<DDC2) | (_IN<<DDC1) | (_OUT<<DDC0);
// State: Bit6=T Bit5=P Bit4=P Bit3=P Bit2=P Bit1=P Bit0=0
PORTC=(0<<PORTC6) | (_PULLUP<<PORTC5) | (_PULLUP<<PORTC4) | (_PULLUP<<PORTC3) | (_PULLUP<<PORTC2) | (_PULLUP<<PORTC1) | (_HIGH<<PORTC0);
// Port D initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(_IN<<DDD7) | (_IN<<DDD6) | (_IN<<DDD5) | (_IN<<DDD4) | (_IN<<DDD3) | (_IN<<DDD2) | (_IN<<DDD1) | (_IN<<DDD0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
}
void set_check_led(void)
{
}
bool is_in_service_mode(void)
{
return false;
}
void do_explode(void)
{
//check service mode
if (is_in_service_mode())
return;
}
void read_ports_work(void)
{
}
int main(void)
{
init_ports();
enable_int0();
init_timer0();
//initialize UART on 9600
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
//enable interrupts
sei();
uart_puts("Initializing...");
uart_puts("Ok.");
uart_nextline
// sleep_mode() has a possible race condition
//checking system wires
if (check_system())
{
set_check_led();
uart_puts("System check...Ok");
uart_nextline
}
//только в целях отладки подождем UART. Кроме него у нас ничего не должно выполняться асинхронно
//таймер0 остановлен
//INT0 инициализирован
_delay_ms(2000);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
/*
slee_mode=
sleep_enable(); \
sleep_cpu(); \
sleep_disable();
sleep_cpu =
__asm__ __volatile__ ( "sleep" "\n\t" :: );
*/
//тут мы должны проснуться после сна
sleep_disable();
uart_puts("Waking up");
uart_nextline
while(true)
{
}
}

