Witam
Mam problem z komunikacją między dwoma uC. Dane są odbierane, jednak nie zgadzają się z wysyłanymi.
Atmega32 - pełni funkcję Mastera
Atmega8 - pełni funkcję modułu
Będę dozgonnie wdzięczny za wskazanie błędu, bo nie mam już pomysłów.
Dodam jeszcze, że prędkość F_CPU jest ustawiona w parametrach projektu 1Mhz dla obu procesorów. Używam wewnętrznego oscylatora w układach.
Sprawdziłem jeszcze przed chwilą wartość. Atmega8 otrzymuje ciągle 0x00.
Mam problem z komunikacją między dwoma uC. Dane są odbierane, jednak nie zgadzają się z wysyłanymi.
Atmega32 - pełni funkcję Mastera
#define VUART 38400
#define VUBRR F_CPU/(VUART*16)-1
#define T0_start 1
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/iom32.h>
#include <stdlib.h>
//Definicje zmiennych
volatile unsigned char z;
volatile unsigned int alarm_active=0; //aktywność czujek; 1 - wykryty ruch, 0 - brak ruchu
//void Alarm_Init(int alarm_active);
void TIMER0_Init()
{
TCNT0 = T0_start; // wartość początkowa T/C0
TCCR0 = _BV(CS00)|_BV(CS02); // preskaler 1024
TIMSK = _BV(TOIE0); // włącz obsługę przerwań T/C0
}
SIGNAL (SIG_OVERFLOW0)
{
TCNT0 = T0_start; // przeładuj timer 0
PORTC ^= 0x08; // przełącz stan LED na PC3
}
// **********************Funkcje obsługi USART**************************
void USART_Init(uint8_t baud) //inicjalizacja USART
{
//Set baud rate
UBRRH = (uint8_t)(baud>>8);
UBRRL = (uint8_t)baud;
// Enable Receiver and Transmitter
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
// Set frame format: 8data, 1 stop bit
UCSRC = 0x86; //asynchroniczne, 8-bit, 1-bit stopu
PORTD &=~_BV(4); //RS485 - odbior
_delay_ms(1);
}
void USART_Transmit( unsigned char data ) //wyslanie 8 bit
{
//Ustalenie kierunku transmisji RS485 - nadawanie
PORTD |= _BV(4);
_delay_ms(1);
// Wait for empty transmit buffer
while ( !( UCSRA & (1<<UDRE)) )
;
// Put data into buffer, sends the data
UDR = data;
//Ustalenie kierunku transmisji RS485 - odbiór
PORTD &=~_BV(4);
_delay_ms(1);
}
unsigned char UART_odbierz (void)
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
SIGNAL (SIG_UART_RECV)
{
PORTC ^= 0x10; //sprawdzenie dioda odbioru
z = UART_odbierz();
_delay_ms(100);
PORTC ^= 0x10;
}
void Sprawdz_Moduly() //sprawdzenie modulow
{
USART_Transmit(0x01);
for (int i=0;i<10;i++){
_delay_ms(100);
}
}
//Funkcja glowna
int main(void)
{
//Deklaracja wyjsc i wejsc
DDRB=0x0F; //PB0-3 będą wyjsciami, PB4-7 będą wejsciami
PORTB=0xF0; // PB4-7 z podciagnieciem do VCC;
DDRA=0xFF; //PA będą wyjsciami
DDRC=0xF8; // 1111 1000
DDRD=0x32; // 0011 0010
PORTD=0xC0; //PD7 i PD6 z podciagnieciem
MCUCSR |= (1<<JTD);
MCUCSR |= (1<<JTD); //wylaczenie JTAG
TIMER0_Init();
USART_Init(VUBRR); //inicjalizacja usart
sei(); //wlaczenie przerwan
while(1) //petla glowna programu
{
Sprawdz_Moduly();
}
}
Atmega8 - pełni funkcję modułu
#define VUART 38400
#define VUBRR F_CPU/(VUART*16)-1
#define T0_start 1
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/iom8.h>
#include <stdlib.h>
//Definicje zmiennych
volatile unsigned char z;
volatile unsigned char adres=0x01; //dla modulu 1
volatile unsigned int alarm_active=0; //flaga wlaczenia alarmu
//Definicja funkcji
int sprawdz(void);
void USART_Init(uint8_t baud) //inicjalizacja USART
{
//Set baud rate
UBRRH = (uint8_t)(baud>>8);
UBRRL = (uint8_t)baud;
// Enable Receiver and Transmitter
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
// Set frame format: 8data, 1 stop bit
UCSRC = 0x86;
PORTD &=~_BV(2); //RS485 - odbior
_delay_ms(1);
}
void USART_Transmit( unsigned char data ) //wyslanie 8 bit
{
//Ustalenie kierunku transmisji RS485 - nadawanie
PORTD |= _BV(2);
_delay_ms(1);
// Wait for empty transmit buffer
while ( !( UCSRA & (1<<UDRE)) )
;
// Put data into buffer, sends the data
UDR = data;
//Ustalenie kierunku transmisji RS485 - odbiór
PORTD &=~_BV(2);
_delay_ms(1);
}
unsigned char UART_odbierz (void)
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
void TIMER0_Init()
{
TCNT0 = T0_start; // wartość początkowa T/C0
TCCR0 = _BV(CS00)|_BV(CS02); // preskaler 1024
TIMSK = _BV(TOIE0); // włącz obsługę przerwań T/C0
}
SIGNAL (SIG_UART_RECV)
{
PORTD ^= 0x20; //sprawdzenie ledem transmisji
z = UART_odbierz();
_delay_ms(100);
USART_Transmit(0x20);
if (z == 0x01 || z ==0x02)
{
PORTB ^=0x40; //sprawdzenie ledem poprawnosci transmisji
}
PORTD ^= 0x20;
}
SIGNAL (SIG_OVERFLOW0)
{
TCNT0 = T0_start; // przeładuj timer 0
// PORTB ^=0x40; // przełącz stan LED na PB6
}
int sprawdz(void){
alarm_active=0;
if (PINB & 0x01) alarm_active=1;
if (PINB & 0x02) alarm_active=1;
if (PINB & 0x04) alarm_active=1;
if (PINB & 0x08) alarm_active=1;
if (PINB & 0x10) alarm_active=1;
if (PINB & 0x20) alarm_active=1;
if (PINC & 0x01) alarm_active=1;
if (PINC & 0x02) alarm_active=1;
if (PINC & 0x04) alarm_active=1;
if (PINC & 0x08) alarm_active=1;
if (PINC & 0x10) alarm_active=1;
if (PINC & 0x20) alarm_active=1;
if (PIND & 0x08) alarm_active=1;
if (PIND & 0x10) alarm_active=1;
if (PIND & 0x40) alarm_active=1;
if (PIND & 0x80) alarm_active=1;
return alarm_active;
}
//Program główny
int main(void)
{
/* Zadeklarowanie wyjsc */
DDRD |= (1<<2)|(1<<5); //wyjscie na D2, D5
DDRB |= (1<<6)|(1<<7); //wyjscie na B6, B7
//Zadeklarowanie wejsc
DDRC = 0x00; //wejscia C 0000 0000
PORTC = 0x3F; //z podciagnieciem 0011 1111
DDRD &= 0xE6; //wejscia D3,D4 1110 0110
PORTD |= 0x18; //z podciagnieciem
DDRB &= 0xC0; //wejscia B0-B5 1100 0000
PORTB |= 0x3F; //z podciagnieciem
DDRD &= 0x3F; //wejscia D6,D7 0011 1111
PORTD |= 0xC0; //z podciagnieciem
PORTD ^= _BV(5);
MCUCSR |= (1<<JTD);
MCUCSR |= (1<<JTD); //wylaczenie JTAG
TIMER0_Init();
USART_Init(VUBRR);
sei();
/* Początek nieskończonej pętli */
while(1)
{
alarm_active=sprawdz();
if (alarm_active==0) PORTB |=0x80;
else PORTB &= 0x7F;
}
return 0;
}
Będę dozgonnie wdzięczny za wskazanie błędu, bo nie mam już pomysłów.
Dodam jeszcze, że prędkość F_CPU jest ustawiona w parametrach projektu 1Mhz dla obu procesorów. Używam wewnętrznego oscylatora w układach.
Sprawdziłem jeszcze przed chwilą wartość. Atmega8 otrzymuje ciągle 0x00.
