uart.c
上传用户:wybzxr
上传日期:2020-02-23
资源大小:263k
文件大小:4k
源码类别:

单片机开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 2006-2008 by Roland Riegel <feedback@roland-riegel.de>
  3.  *
  4.  * This file is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License version 2 as
  6.  * published by the Free Software Foundation.
  7.  */
  8. #include <stdio.h>
  9. #include <avr/interrupt.h>
  10. #include <avr/io.h>
  11. #include <avr/pgmspace.h>
  12. #include <avr/sfr_defs.h>
  13. #include <avr/sleep.h>
  14. #include "uart.h"
  15. /* some mcus have multiple uarts */
  16. #ifdef UDR0
  17. #define UBRRH UBRR0H
  18. #define UBRRL UBRR0L
  19. #define UDR UDR0
  20. #define UCSRA UCSR0A
  21. #define UDRE UDRE0
  22. #define RXC RXC0
  23. #define UCSRB UCSR0B
  24. #define RXEN RXEN0
  25. #define TXEN TXEN0
  26. #define RXCIE RXCIE0
  27. #define UCSRC UCSR0C
  28. #define URSEL 
  29. #define UCSZ0 UCSZ00
  30. #define UCSZ1 UCSZ01
  31. #define UCSRC_SELECT 0
  32. #else
  33. #define UCSRC_SELECT (1 << URSEL)
  34. #endif
  35. #ifndef USART_RXC_vect
  36. #if defined(UART0_RX_vect)
  37. #define USART_RXC_vect UART0_RX_vect
  38. #elif defined(UART_RX_vect)
  39. #define USART_RXC_vect UART_RX_vect
  40. #elif defined(USART0_RX_vect)
  41. #define USART_RXC_vect USART0_RX_vect
  42. #elif defined(USART_RX_vect)
  43. #define USART_RXC_vect USART_RX_vect
  44. #elif defined(USART0_RXC_vect)
  45. #define USART_RXC_vect USART0_RXC_vect
  46. #elif defined(USART_RXC_vect)
  47. #define USART_RXC_vect USART_RXC_vect
  48. #else
  49. #error "Uart receive complete interrupt not defined!"
  50. #endif
  51. #endif
  52. #define BAUD 9600UL
  53. #define UBRRVAL (F_CPU/(BAUD*16)-1)
  54. #define USE_SLEEP 1
  55. void uart_init()
  56. {
  57.     /* set baud rate */
  58.     UBRRH = UBRRVAL >> 8;
  59.     UBRRL = UBRRVAL & 0xff;
  60.     /* set frame format: 8 bit, no parity, 1 bit */
  61.     UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
  62.     /* enable serial receiver and transmitter */
  63. #if !USE_SLEEP
  64.     UCSRB = (1 << RXEN) | (1 << TXEN);
  65. #else
  66.     UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
  67. #endif
  68. }
  69. void uart_putc(uint8_t c)
  70. {
  71.     if(c == 'n')
  72.         uart_putc('r');
  73.     /* wait until transmit buffer is empty */
  74.     while(!(UCSRA & (1 << UDRE)));
  75.     /* send next byte */
  76.     UDR = c;
  77. }
  78. void uart_putc_hex(uint8_t b)
  79. {
  80.     /* upper nibble */
  81.     if((b >> 4) < 0x0a)
  82.         uart_putc((b >> 4) + '0');
  83.     else
  84.         uart_putc((b >> 4) - 0x0a + 'a');
  85.     /* lower nibble */
  86.     if((b & 0x0f) < 0x0a)
  87.         uart_putc((b & 0x0f) + '0');
  88.     else
  89.         uart_putc((b & 0x0f) - 0x0a + 'a');
  90. }
  91. void uart_putw_hex(uint16_t w)
  92. {
  93.     uart_putc_hex((uint8_t) (w >> 8));
  94.     uart_putc_hex((uint8_t) (w & 0xff));
  95. }
  96. void uart_putdw_hex(uint32_t dw)
  97. {
  98.     uart_putw_hex((uint16_t) (dw >> 16));
  99.     uart_putw_hex((uint16_t) (dw & 0xffff));
  100. }
  101. void uart_putw_dec(uint16_t w)
  102. {
  103.     uint16_t num = 10000;
  104.     uint8_t started = 0;
  105.     while(num > 0)
  106.     {
  107.         uint8_t b = w / num;
  108.         if(b > 0 || started || num == 1)
  109.         {
  110.             uart_putc('0' + b);
  111.             started = 1;
  112.         }
  113.         w -= b * num;
  114.         num /= 10;
  115.     }
  116. }
  117. void uart_putdw_dec(uint32_t dw)
  118. {
  119.     uint32_t num = 1000000000;
  120.     uint8_t started = 0;
  121.     while(num > 0)
  122.     {
  123.         uint8_t b = dw / num;
  124.         if(b > 0 || started || num == 1)
  125.         {
  126.             uart_putc('0' + b);
  127.             started = 1;
  128.         }
  129.         dw -= b * num;
  130.         num /= 10;
  131.     }
  132. }
  133. void uart_puts(const char* str)
  134. {
  135.     while(*str)
  136.         uart_putc(*str++);
  137. }
  138. void uart_puts_p(PGM_P str)
  139. {
  140.     while(1)
  141.     {
  142.         uint8_t b = pgm_read_byte_near(str++);
  143.         if(!b)
  144.             break;
  145.         uart_putc(b);
  146.     }
  147. }
  148. uint8_t uart_getc()
  149. {
  150.     /* wait until receive buffer is full */
  151. #if USE_SLEEP
  152.     uint8_t sreg = SREG;
  153.     sei();
  154.     while(!(UCSRA & (1 << RXC)))
  155.         sleep_mode();
  156.     SREG = sreg;
  157. #else
  158.     while(!(UCSRA & (1 << RXC)));
  159. #endif
  160.     uint8_t b = UDR;
  161.     if(b == 'r')
  162.         b = 'n';
  163.     return b;
  164. }
  165. EMPTY_INTERRUPT(USART_RXC_vect)