Mam problem z uruchomieniem prostego programu na ATMEGA8.
Mega jest podpięta z SN75176 (odpowiednik MAX485) i mam podłączone dwie takie płytki.
Każda płytka ma przycisk i element wykonawczy (triak). Program ma za zadanie zbierać informacje z sieci (gdy wciśniemy przycisk na płytce B, powinien się załączyć triak na płytce A i odwrotnie) i w razie potrzeby samemu wysyłać informacje.
Wszystko działa ślicznie do momentu gdy w jednym programie nie używam jednocześnie (w różnych momentach) polecenia nadawania i odbioru (w przerwaniu) informacji z sieci. Proba nadania czegokolwiek albo odebrania kończy się resetem ATMEGI (na początku programu zapalam sobie dwie diody - stąd wiem że następuje reset).
Co robie nie tak?
Mega jest podpięta z SN75176 (odpowiednik MAX485) i mam podłączone dwie takie płytki.
Każda płytka ma przycisk i element wykonawczy (triak). Program ma za zadanie zbierać informacje z sieci (gdy wciśniemy przycisk na płytce B, powinien się załączyć triak na płytce A i odwrotnie) i w razie potrzeby samemu wysyłać informacje.
Wszystko działa ślicznie do momentu gdy w jednym programie nie używam jednocześnie (w różnych momentach) polecenia nadawania i odbioru (w przerwaniu) informacji z sieci. Proba nadania czegokolwiek albo odebrania kończy się resetem ATMEGI (na początku programu zapalam sobie dwie diody - stąd wiem że następuje reset).
Co robie nie tak?
define F_CPU 8000000 // 8MHz zegar procesora
#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
/*
Struktura ramki danych
Bajt 1 Familly code
Bajt 2 Adres
Bajt 3 Funkcja
Bajt 4 Dane
Bajt 5 Dane
Bajt 6 Dane
Bajt 7 Dane
Bajt 8 CRC16
*/
/* */
//Definicje i markodeklaracje
const int FAMILLY_CODE = 51;
const int ADRES = 52;
volatile int j;
volatile int FLAGA_komunikat_OK=0;
volatile int iRX;
volatile int QQ=0;
volatile unsigned char RS232_RX[16];
volatile unsigned char RS232_RXd[8];
volatile unsigned char RS232_TX[10];
volatile int FLAGA;
volatile int VALUE;
volatile int stan=0;
volatile int wartosc=250;
volatile int i=0;
volatile int ip;
volatile uint16_t LICZNIK;
volatile uint8_t data[96];
volatile uint16_t wtg_transmision=0;//zabezpieczenie transmisji (w razie zgubienia jednego bajtu)
int dataDS[2];
//DIODY LED------------------------------
#define LEDP1ON sbi(PORTB,PB0) //dioda LED1
#define LEDP2ON sbi(PORTD,PD7) //dioda LED2
#define LEDP1OFF cbi(PORTB,PB0)
#define LEDP2OFF cbi(PORTD,PD7)
#define LEDP1 PB0
#define LEDP2 PD7
#define DIMMON sbi(PORTD,PD5) //sterowanie triakiem
#define DIMMOFF cbi(PORTD,PD5)
#define DIMM PD5
#define TRANON sbi(PORTD,PD4) //sterowanie transmisją RS485
#define TRANOFF cbi(PORTD,PD4)
#define TRAN PD4
//------------------------------
//RS232----------------------------------------------------------------------------------------
const unsigned char Wea[]=" "; //stala dla wyswietlacza
void InitUSART( unsigned long int baud ) // baud - czyli bitrate portu COM
{
UBRRH = (unsigned char)(((F_CPU/(16UL*baud))-1)>>8);
UBRRL = (unsigned char)((F_CPU/(16UL*baud))-1);
// Otwarty kanal odbioru i nadawania + przerwania
UCSRB |= (1<<RXEN)|(1<<TXEN)| (1 << RXCIE)| (1 << TXCIE);;
// 8bitów, 1bity stopu */
UCSRC |= (1<<URSEL)|(1<<UCSZ1) | (1<<UCSZ0);
}
unsigned char ReceiveUSART( void ) // funkcja odbioru bajtu z RS232
{
while ( !(UCSRA & (1<<RXC)) );
return UDR;
}
void TransmitUSART( unsigned char data ) // funkcja wysłania bajtu po RS232
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = data;
}
//RS232----------------------------------------------------------------------------------------
void odebral()
{
for(i=0;i<8;i++)
{
RS232_RXd[i]=RS232_RX[i];
RS232_RX[i]=0;
}
if(RS232_RXd[3]==1) LEDP1ON;
else LEDP1OFF;
wartosc=RS232_RXd[2];
stan=RS232_RXd[3];
OCR1AH=0;
if(stan==1) OCR1AL=wartosc;
else OCR1AL=0;
}
//odbior bajtu z uarta
SIGNAL (SIG_UART_RECV)
{
wtg_transmision=0;
if(QQ==2)
{
RS232_RX[iRX]=UDR;
iRX++;
if(iRX>5)
{
QQ=0;
odebral();
wtg_transmision=500;
}
}
if(QQ==1)
{
if(UDR==ADRES) QQ=2;
else QQ=0;
}
if(UDR==FAMILLY_CODE && QQ==0) {QQ=1;}
}
//STEROWANIE TRIAKIEM----------------------------------
SIGNAL (SIG_INTERRUPT0)
{
TCNT1=0; //wyzeruj licznik
}
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
if(stan==1)
{
DIMMON;
_delay_us(10);
}
DIMMOFF;
}
//STEROWANIE TRIAKIEM----------------------------------
int main()
{
//Deklaracja zmiennych i stalych
GIMSK |=_BV(INT0); //włącz obsługę przerwań Int0
MCUCR |=_BV(ISC01); // włącz generowanie przerwań przez
// opadające zbocze na Int0
//--------------- TIMER1 ----------------------
TCCR1A=0xC;
TCCR1B = 0x04; //preskaler ustawiony na 256
TCNT1H = 0; //wartość początkowa
TCNT1L = 0;
OCR1AH = 0x00; //7A12 = 31250 -> 1s
OCR1AL = 0xF2;
TIMSK = 0x10; //przerwanie gry osagnięta wartosc = OCR1A
//---------------------------------------------
int pomstan=0;
int staraw=0;
int starystan=0;
int kierunek=2;
DDRB|=_BV(PB0);
DDRC|=_BV(PC0)|_BV(PC1)|_BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5);
DDRD|=_BV(DIMM)|_BV(PD7)|_BV(PD4);
InitUSART(9600);
TRANOFF;
LEDP1ON;
LEDP2ON;
_delay_ms(100);
LEDP1OFF;
LEDP2OFF;
//ustawienia poczatkowe
RS232_TX[0]=51;
RS232_TX[1]=52;
RS232_TX[2]=53;
RS232_TX[3]=54;
RS232_TX[4]=250; //Jasnosc
RS232_TX[5]=0; // 0 wylacz / 1 wlacz
RS232_TX[6]=60;
RS232_TX[7]=61;
RS232_TX[8]=62;
staraw=wartosc;
starystan=stan;
sei();
do
{
//Obsluga przycisku
if(bit_is_clear(PINB,PB2))
{
pomstan++;
if(pomstan>400)//&&stan==1)
{
if(kierunek==1 ) {wartosc=wartosc+1;}
if(kierunek==2 ) {wartosc=wartosc-1;}
}
_delay_ms(1);
}
else
{
if(pomstan<=400&&pomstan>20)
{
stan=((stan+1)%2);
if(stan==0) LEDP1ON;
else LEDP1OFF;
_delay_ms(10);
}
pomstan=0;
_delay_ms(1);
}
//Obsluga sytuacji brzegowych
if(pomstan>1000) pomstan=1000;
if(wartosc<20) kierunek=1;
if(wartosc>255) kierunek=2;
/* Zmiana stanu
Jesli zmienimuy stan albo wartosc - wysylamy nowe wartosci
*/
if(staraw!=wartosc||starystan!=stan)
{
cli();
RS232_TX[4]=wartosc;
RS232_TX[5]=stan;
OCR1AH=0;
if(stan==1) OCR1AL=wartosc;
else OCR1AL=0;
TRANON; //przelacz MAX-a w tryb nadawania
_delay_us(100);
for(i=0;i<8;i++)
{
TransmitUSART(RS232_TX[i]);
}
_delay_ms(1);
TRANOFF; //przelacz MAX-a w tryb odbioru
sei();
staraw=wartosc;
starystan=stan;
}
/* Kontrola transmisji
Resetujemy bufor gdy trzeba zbyt dlugo czekac na nastepny bajt
*/
wtg_transmision++;
_delay_us(1000);
if(wtg_transmision>50)
{
iRX=0;
wtg_transmision=0;
LEDP2ON;
_delay_ms(5);
LEDP2OFF;
//dolozyc resetowanie bufora uarta !!!!
}
}
while(1);
return 0;
}