Вот части моего кода:
Функция инициализации:
Код: Выделить всё
void USART_Init(void){
// Baudrate calculation
DATA_BAUDRATE = DATA_BAUDRATE*16;
DATA_UBRR = (_DATA_CLOCK/DATA_BAUDRATE)-1;
/*Set baud rate */
UBRRH = Hi(DATA_UBRR);
UBRRL = Lo(DATA_UBRR);
DATA_TX_INDEX = 0;
DDRD &=~(1<<0); // set PORTD.0 as input for ADM485 (RX)
DDRD |= (1<<1); // set PORTD.1 as output for ADM485 (TX)
DDRD |= (1<<3); // set PORTD.3 as output for ADM485 (transmit-recieve mode)
// Normal BaudRate (if U2X == 1 then x2 BaudRate)
UCSRA &=~ (1 << U2X);
// RXCIE interrupt, RX enable
UCSRB |= (1 << RXCIE)|(1 << RXEN)|(1 << TXEN);
// URSEL -> 8 bit - one word; (1 stop bit)
UCSRC |= (1 << URSEL)|(1 << UCSZ1)|(1 << UCSZ0);
}
Функция по которой принимается байт:
Код: Выделить всё
void interrupt_USART_RXC_vect() org IVT_ADDR_USART__RXC {
DATA_RX = UDR;
}
Функция по которой отправляется массив байт:
Код: Выделить всё
void interrupt_USART_UDRE_vect() org IVT_ADDR_USART__UDRE {
if(DATA_TX_INDEX < (_DATA_TX_COUNT)){
UDR = DATA_TX[DATA_TX_INDEX];
Delay_ms(40);
// next element in array
DATA_TX_INDEX = DATA_TX_INDEX + 1;
}
else{
DATA_TX_INDEX = 0;
// Exit vector
UCSRB &=~ (1 << UDRIE);
// Recive mode ON
UCSRB |= (1 << RXEN);
// Low level control pin
PORTD &=~ (1 << 5);
// delay of changing mode (to recive messages)
Delay_ms(32);
}
}
Собственно использование в главном цикле:
Код: Выделить всё
// ---------- RS485 ----------
if(DATA_RX == _DATA_REQUEST){
DATA_RX = 0;
// Recive mode OFF
UCSRB &=~ (1 << RXEN);
// High level control pin
PORTD |= (1 << 5);
// delay of changing mode (to trancive messages)
Delay_ms(32);
// Calculation CRC-16
DATA_TX_CRC = CRC16(&DATA_TX,8);
DATA_TX[8] = Hi(DATA_TX_CRC);
DATA_TX[9] = Lo(DATA_TX_CRC);
// entrance vector
UCSRB |= (1 << UDRIE);
}
// ----------
asm nop;