по поводу большого количества кода в прерывании, вы совершенно правы, спасибо.
atmel studio не находит функцию powerdown. да и не нужно) суть была в невозможности проснуться от прерывания по фронту. Спасибо большое
Вывод UART только для отладки.
вот с таким кодом отлично просыпается в протеус с прерыванием по низкому уровню
Код: Выделить всё
/*
* 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;
volatile bool int0_flag=false;
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);
void blink(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) )
/*
PORTC |= _BV(0); // Set bit 0 only.
PORTC &= ~(_BV(1)); // Clear bit 1 only.
PORTC ^= _BV(7); // Toggle bit 7 only.
*/
//Interrupt Service Routine for INT0
ISR(INT0_vect)
{
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)
{
cnt++;
if (cnt>=freq)
{
enable_timer0(false); // disable timer0
cnt=0;
uart_puts("timer0 interrupt approx 1 sec");
uart_nextline
seconds_counter++;
if (seconds_counter>=30)
do_explode(); //тут всего лишь взвод ноги и не более, так что выносить ее в основной цикл не имеет смысла
cli();
TCNT0 = 0;
sei();
blink();
enable_timer0(true);
}
}
void blink(void)
{
//нагнетаем обстановку)))))))
PORTB ^= _BV(PB0);
}
//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
//сбрасываем все биты ISCxx
//настраиваем на срабатывание INT0 по нмзкому уровню
MCUCR &= ~( (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00) );
}
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)| (_OUT<<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) | (_LOW<<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) | (_IN<<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) | (_PULLUP<<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
//если тумблер сервисного режима не взаеден
//ждем взведения
//потом
//checking system wires
if (check_system())
{
set_check_led();
uart_puts("System check...Ok");
uart_nextline
}
//else
//ждем снятия сервисного режима
//чека должна быть установлена для продолжения выполнения
//засыпаем
//только в целях отладки подождем UART. Кроме него у нас ничего не должно выполняться асинхронно
//таймер0 остановлен
//INT0 инициализирован
_delay_ms(2000);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
//тут мы должны проснуться после сна
sleep_disable();
uart_puts("Waking up");
uart_nextline
while(true)
{
if (check_pull)
{
//working
//проверяем перерезанные провода
//взрываемся, ускоряемся или обезвреживаемся
}
}
}и все же вопрос такой, как в atmel studio отлаживать код, хочется простого step-by-step на уровне си функций. Точки останова не срабатывают у меня нивкакую.
Unable to set requested bp on target. The current selected devise is unable to set bp during runtime.


