?? uart.c
字號:
/* * Copyright (c) 2006-2008 by Roland Riegel <feedback@roland-riegel.de> * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <stdio.h>#include <avr/interrupt.h>#include <avr/io.h>#include <avr/pgmspace.h>#include <avr/sfr_defs.h>#include <avr/sleep.h>#include "uart.h"/* some mcus have multiple uarts */#ifdef UDR0#define UBRRH UBRR0H#define UBRRL UBRR0L#define UDR UDR0#define UCSRA UCSR0A#define UDRE UDRE0#define RXC RXC0#define UCSRB UCSR0B#define RXEN RXEN0#define TXEN TXEN0#define RXCIE RXCIE0#define UCSRC UCSR0C#define URSEL #define UCSZ0 UCSZ00#define UCSZ1 UCSZ01#define UCSRC_SELECT 0#else#define UCSRC_SELECT (1 << URSEL)#endif#ifndef USART_RXC_vect#if defined(UART0_RX_vect)#define USART_RXC_vect UART0_RX_vect#elif defined(UART_RX_vect)#define USART_RXC_vect UART_RX_vect#elif defined(USART0_RX_vect)#define USART_RXC_vect USART0_RX_vect#elif defined(USART_RX_vect)#define USART_RXC_vect USART_RX_vect#elif defined(USART0_RXC_vect)#define USART_RXC_vect USART0_RXC_vect#elif defined(USART_RXC_vect)#define USART_RXC_vect USART_RXC_vect#else#error "Uart receive complete interrupt not defined!"#endif#endif#define BAUD 9600UL#define UBRRVAL (F_CPU/(BAUD*16)-1)#define USE_SLEEP 1void uart_init(){ /* set baud rate */ UBRRH = UBRRVAL >> 8; UBRRL = UBRRVAL & 0xff; /* set frame format: 8 bit, no parity, 1 bit */ UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0); /* enable serial receiver and transmitter */#if !USE_SLEEP UCSRB = (1 << RXEN) | (1 << TXEN);#else UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);#endif}void uart_putc(uint8_t c){ if(c == '\n') uart_putc('\r'); /* wait until transmit buffer is empty */ while(!(UCSRA & (1 << UDRE))); /* send next byte */ UDR = c;}void uart_putc_hex(uint8_t b){ /* upper nibble */ if((b >> 4) < 0x0a) uart_putc((b >> 4) + '0'); else uart_putc((b >> 4) - 0x0a + 'a'); /* lower nibble */ if((b & 0x0f) < 0x0a) uart_putc((b & 0x0f) + '0'); else uart_putc((b & 0x0f) - 0x0a + 'a');}void uart_putw_hex(uint16_t w){ uart_putc_hex((uint8_t) (w >> 8)); uart_putc_hex((uint8_t) (w & 0xff));}void uart_putdw_hex(uint32_t dw){ uart_putw_hex((uint16_t) (dw >> 16)); uart_putw_hex((uint16_t) (dw & 0xffff));}void uart_putw_dec(uint16_t w){ uint16_t num = 10000; uint8_t started = 0; while(num > 0) { uint8_t b = w / num; if(b > 0 || started || num == 1) { uart_putc('0' + b); started = 1; } w -= b * num; num /= 10; }}void uart_putdw_dec(uint32_t dw){ uint32_t num = 1000000000; uint8_t started = 0; while(num > 0) { uint8_t b = dw / num; if(b > 0 || started || num == 1) { uart_putc('0' + b); started = 1; } dw -= b * num; num /= 10; }}void uart_puts(const char* str){ while(*str) uart_putc(*str++);}void uart_puts_p(PGM_P str){ while(1) { uint8_t b = pgm_read_byte_near(str++); if(!b) break; uart_putc(b); }}uint8_t uart_getc(){ /* wait until receive buffer is full */#if USE_SLEEP uint8_t sreg = SREG; sei(); while(!(UCSRA & (1 << RXC))) sleep_mode(); SREG = sreg;#else while(!(UCSRA & (1 << RXC)));#endif uint8_t b = UDR; if(b == '\r') b = '\n'; return b;}EMPTY_INTERRUPT(USART_RXC_vect)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -