/* Title: Interrupt driven serial example(RS-485).
* Author: Daidai Hu
* Date: 06/2003
* Purpose: Template for RS-485 slave communICation program.
* Needed
* SOFtware: AVR-GCC 3.3 to compile
* Needed
* Hardware: ATMega103 board with serial 0 connected to RS-485 bus. */
#include
#include
#include
#include
#include
#include
#include
#include
#define F_CPU 6000000 /* 6MHz. */
#define MAX_RCV_LEN 128 /* Maximal receive message length. */
#define MAX_SND_LEN 128 /* Maximal send message length. */
#define UART_BAUD_SELECT(bps) (F_CPU/((bps)*16L)-1)
#define TICK 2 /* System tick(ms). */
#define SRL_TOUT 20 /* Idle time between serial frames(ms). */
/* D7-D2: Reserved(0).
* D1-D0: Baud rate select, 0=19200, 1=9600..., 3=2400. */
uint8_t ucBaud_g;
/* Const table for baud rate register. */
prog_char aucBdTbl_c[]=
{
UART_BAUD_SELECT(19200),
UART_BAUD_SELECT(9600),
UART_BAUD_SELECT(4800),
UART_BAUD_SELECT(2400),
};
/* Global flag. */
volatile uint8_t ucFlag_g;
#define RECV_ERR 0x01
#define RECV_FRM 0x02
#define SEND_MSG 0x04
#define RS485_TX_ON sbi(PORTC, 0)
#define RS485_TX_OFF cbi(PORTC, 0)
/* Serial buffer. */
uint8_t aucRcvBuf_g[MAX_RCV_LEN], aucSndBuf_g[MAX_SND_LEN];
/* Receive length, send length and now send position. */
volatile uint8_t ucRcvLen_g, ucSndLen_g, ucSndPos_g;
volatile uint8_t ucSrlTout_g; /* Frame time out counter. */
static void Deal_Recv_Msg(void);
int main(void)
{
volatile uint16_t unDelay;
/* Power on delay. */
for (ucBaud_g=0; ucBaud_g<10; ucBaud_g )
{
for (unDelay=0; unDelay<60000; unDelay )
continue;
}
/* Set timer 1 capture interrupt as system tick. */
TCCR1A=0x00;
TCCR1B=0x09;
OCR1AH=((F_CPU*TICK/1000) & 0xFF00)>>8;
OCR1AL=(F_CPU*TICK/1000) & 0xFF;
sbi(TIMSK, OCIE1A); /* Enable interrupt. */
ucBaud_g=eeprom_rb(0x10);
/* Default baud rate=9600. */
if (ucBaud_g>3)
ucBaud_g=1;
/* Set baud rate. */
UBRR=PRG_RDB(&aucBdTbl_c[ucBaud_g]);
/* Enable RxD/TxD and ints. */
UCR=(1<
sei(); /* Enable interrupts. */
while (1)
{
if (ucFlag_g & RECV_FRM)
{
Deal_Recv_Msg();
cli();
ucRcvLen_g=0;
ucFlag_g &= ~(RECV_FRM | RECV_ERR);
sei();
}
}
}
/* Signal handler for receive complete interrupt. */
SIGNAL(SIG_UART_RECV)
{
uint8_t ucFromUart;
ucFromUart=UDR; /* Read the Rx data first. */
/* Check if last command not deaLED over. */
if ((ucFlag_g & RECV_FRM) || ucRcvLen_g>=MAX_RCV_LEN)
ucFlag_g |= RECV_ERR;
else if (!(ucFlag_g & SEND_MSG))
aucRcvBuf_g[ucRcvLen_g ]=ucFromUart;
ucFromUart=USR;
if (ucFromUart & ((0x01<
ucSrlTout_g=SRL_TOUT/TICK; /* Reset the timeout counter. */
}
/* Signal handler for uart data buffer empty interrupt. */
SIGNAL(SIG_UART_DATA)
{
/* Write byte to data buffer. */
UDR=aucSndBuf_g[ucSndPos_g ];
if (ucSndPos_g>=ucSndLen_g) /* If buffer is empty: */
{
cbi(UCR, UDRIE); /* DISAble UDRIE interrupt. */
sbi(UCR, TXCIE);
}
}
SIGNAL(SIG_UART_TRANS)
{
cbi(UCR, TXCIE);
RS485_TX_OFF;
ucFlag_g &= ~SEND_MSG; /* Last message was dealed. */
}
SIGNAL(SIG_OUTPUT_COMPARE1A) /* Timer 1 output compare. */
{
if (ucSrlTout_g && !(--ucSrlTout_g))
ucFlag_g |= RECV_FRM;
}
static void Deal_Recv_Msg(void)
{
/* TODO: deal with receive message here. */
if (ucFlag_g & RECV_ERR)
return;
mEMCpy(aucSndBuf_g, aucRcvBuf_g, ucRcvLen_g);
ucSndLen_g=ucRcvLen_g;
if (ucSndLen_g>=5)
{
ucSndPos_g=0;
cli();
ucRcvLen_g=0;
ucFlag_g &= ~(RECV_FRM | RECV_ERR);
ucFlag_g |= SEND_MSG;
RS485_TX_ON;
sbi(UCR, UDRIE);
sei();
}
}
Previous article:SD card interface program (AVR)
Next article:Application of AVR serial port multi-machine communication mode
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- PMOS is turned on
- Download: In-depth analysis of the impact of the Internet of Things
- Intelligent toilet constant temperature circuit
- CCS compiles and generates binary files
- Mobile phone calculators are all dead: What is 10% + 10%? [Have you ever calculated it?]
- 【TI recommended course】# TINA-TI training course#
- Review of "My Life With You 2019"
- Qinhengwei CH549L-Air touch sensitivity debugging
- When the serial port is connected, if the host receives wrong data, it will return to the initial state.
- How to set the temperature of the battery temperature detection pin TS of BQ24650 to -10℃-50℃