📄 usart.c
字号:
/* ****ROBOCON 2009 | BUPT TEAM*******
* ------------------------------------------------------------------------
* FileName : usart.c
* Version : 1.01
* Biref : USART Driver(use queue, Half Mode)
* Code by : Leaf
* Date : Dec.08 2008
* Dependence : Queue
* Note : modify basic transfer function into a Object Method
* Usart Object Contains Information for Uart Port
* Half Mode Communication
*
* ------------------------------------------------------------------------
*/
#include "config.h"
#include <stdlib.h>
#ifdef USART_H_INCLUDED
static Queue usart_send0, usart_recv0;
const Usart USART0 = {
&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, &usart_send0, &usart_recv0
};
static Queue usart_send1, usart_recv1;
const Usart USART1 = {
&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, &usart_send1, &usart_recv1
};
/*+ Usart Mode Control */
/* Switch Usart Mode(Recv/Send) */
void usart_mode_switch(const Usart *usart, UsartMode mode){
switch(mode){
case usart_mode_send:
*usart->ucsrb = (_BV(TXEN)|_BV(TXCIE));
break;
case usart_mode_recv:
*usart->ucsrb = (_BV(RXEN)|_BV(RXCIE));
break;
case usart_mode_stop:
*usart->ucsrb = 0;
break;
}
}
/* Detect Usart Mode(From Hardware)*/
UsartMode get_usart_mode(const Usart *usart){
if(bit_is_set(*usart->ucsrb, TXEN)){
loop_until_bit_is_set(*usart->ucsra, UDRE);
return usart_mode_send;
}
else if(bit_is_set(*usart->ucsrb, RXEN)){
return usart_mode_recv;
}
else{
return usart_mode_stop;
}
}
/*- Usart Mode Control */
/* Usart Initialization
* Enter Usart (Recv) Mode
* Setup Buffering Queue */
void usart_init(const Usart* usart, UINT16 ubrr){
*usart->ucsrb = 0x00;
*usart->ucsra = 0x00;
*usart->ucsrc = 0x06;
*usart->ubrrl = ubrr & 0x00ff;
*usart->ubrrh = ubrr >> 8;
usart_mode_switch(usart, usart_mode_recv);
q_init( usart->send_buf,
(Q_DATA_TYPE*)malloc(sizeof(Q_DATA_TYPE)*UART_SENDBUF_SIZE),
UART_SENDBUF_SIZE
);
q_init( usart->recv_buf,
(Q_DATA_TYPE*)malloc(sizeof(Q_DATA_TYPE)*UART_RECVBUF_SIZE),
UART_SENDBUF_SIZE
);
}
/*+ Usart Transfer Methods */
void usart_tx_isr(const Usart* usart){
if(!q_empty(usart->send_buf))
*usart->udr = q_popfront(usart->send_buf);
else{
usart_mode_switch(usart, usart_mode_recv);
}
}
void inline usart_tx_start(const Usart *usart)
{
if(get_usart_mode(usart) == usart_mode_recv){
usart_mode_switch(usart, usart_mode_send);
*usart->udr = q_popfront(usart->send_buf);
}
else if((*usart->ucsra&(1<<UDRE)) && !q_empty(usart->send_buf)){
*usart->udr = q_popfront(usart->send_buf);
}
}
void usart_putc(const Usart* usart, char c)
{
while(q_full(usart->send_buf));
q_pushback(usart->send_buf, c);
usart_tx_start(usart);
}
void usart_puts(const Usart *usart, const char *buf)
{
if(*buf == '\0')
return;
usart_putc(usart, *buf);
++buf;
while(*buf)
{
while(q_full(usart->send_buf));
q_pushback(usart->send_buf, *buf);
++ buf;
}
usart_putc(usart, 0x0d);
}
/*- Usart Transfer Methods */
/*+ Usart Recieve Methods */
/*
* Called in usart_rx_interrupt
* If Buffer Overflowed, Will corrupt previous data
*/
void usart_rx_isr(const Usart* usart){
q_pushback(usart->recv_buf, *usart->udr);
}
/*
* Get Char from usart
* If Buffer is empty, Will wait
*/
char usart_getc(const Usart* usart)
{
while(q_empty(usart->recv_buf));
return( q_popfront(usart->recv_buf) );
}
/* Simply Wait \0 to end input*/
int usart_gets(const Usart *usart, char *buf)
{
char recv;
int i = 0;
recv = usart_getc(usart);
while(recv != '#'){
buf[i] = recv;
recv = usart_getc(usart);
++ i;
}
buf[i] = '\0';
return i;
}
/* Clear all Usart Buffer Data */
int usart_flush(const Usart *usart, char *buf){
return q_flush(usart->recv_buf, buf);
}
/*- Usart Recieve Methods */
/*+ Usart File */
#ifdef _STDIO_H_
static int
usart_putchar(char c, FILE* file){
usart_putc(file->udata, c);
return 0;
}
static int
usart_getchar(FILE* file){
return usart_getc(file->udata);
}
FILE*
usart_get_stream(const Usart *usart){
FILE *stream;
stream = fdevopen(usart_putchar, usart_getchar);
stream->udata = (void*)usart;
return stream;
}
void inline
usart_setup_stream(const Usart *usart, FILE* stream){
fdev_setup_stream(stream, usart_putchar, usart_getchar, 3);
stream->udata = (void *)usart;
}
#endif
/*- Usart File */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -