AVRly - AVR Development Resources
usart.c
Go to the documentation of this file.
1/******************************************************************************
2 @copyright Copyright © 2022 by Jason Duffy.
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21******************************************************************************/
22
23/**
24 * @file usart.c
25 * @ingroup log_system
26 * @author Jason Duffy
27 * @date 15th March 2022
28 * @brief Driver file providing core USART communication between the target MCU
29 * and your PC. This file was adapted from Elliot Williams' Github repo
30 * hexagon5un. (link in the see also section below).
31 * @bug No known bugs.
32 * @see https://github.com/hexagon5un/AVR-Programming
33 */
34
35
36#include <util/setbaud.h>
37#include <avr/io.h>
38
39#include "usart.h"
40
41// Forward declarations for private helper functions.
42static void transmit_byte(uint8_t data);
43static uint8_t receive_byte(void);
44
45
46/*
47 * Takes the defined BAUD and F_CPU, calculates the bit-clock multiplier,
48 * configures the hardware USART ready for use.
49 */
50void init_usart(void)
51{
52 // defined in setbaud.h
53 UBRR0H = UBRRH_VALUE;
54 UBRR0L = UBRRL_VALUE;
55
56#if USE_2X
57 UCSR0A |= (1 << U2X0);
58#else
59 UCSR0A &= ~(1 << U2X0);
60#endif
61
62 // Enable USART transmitter/receiver
63 UCSR0B = (1 << TXEN0) | (1 << RXEN0);
64 // 8 data bits, 1 stop bit
65 UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
66}
67
68
69/*
70 * Utility function to transmit a string.
71 * @param my_string is the string constant youd like to print, and should be
72 * enclosed in "" quotation marks.
73 */
74void usart_print_string(const char myString[])
75{
76 uint8_t i = 0;
77 while (myString[i])
78 {
79 transmit_byte(myString[i]);
80 i++;
81 }
82}
83
84
85/*
86 * Define a string variable, pass it to this function. The string will contain.
87 * whatever you typed over serial.
88 * @param my_string is a pointer to the first element in the character array
89 * you'd like to store the received message in.
90 * @param max_length is the maximum number of characters expected.
91 */
92void usart_read_string(char myString[], uint8_t maxLength)
93{
94 char response;
95 uint8_t count = 0;
96
97 while (count < (maxLength - 1))
98 {
99 response = receive_byte();
100 transmit_byte(response); // echo
101
102 if (response == '\r') // enter marks the end
103 {
104 break;
105 }
106
107 else
108 {
109 myString[count] = response; // add in a letter
110 ++count;
111 }
112 }
113 myString[count] = 0; // terminal NULL character */
114}
115
116
117/*
118 * Prints a byte out as its 3-digit ascii equivalent.
119 * @param byte is the 8 bits of data to be sent, must be unsigned.
120 */
121void usart_print_byte(uint8_t byte)
122{
123 // Converts a byte to a string of decimal text, sends it
124 transmit_byte('0' + (byte / 100)); // Hundreds
125 transmit_byte('0' + ((byte / 10) % 10)); // Tens
126 transmit_byte('0' + (byte % 10)); // Ones
127}
128
129
130/*
131 * Prints a byte out as its 1-digit ascii equivalent.
132 * @param byte is the 8 bits of data to be sent, must be unsigned, with a
133 * value of 0-9;
134 */
136{
137 transmit_byte(byte);
138}
139
140
141/*
142 * Prints a byte out as its 1-character ascii equivalent.
143 * @param byte is the character to be sent.
144 */
145void usart_print_char(char byte)
146{
147 transmit_byte(byte);
148}
149
150
151/*
152 * Prints a word (16-bits) out as its 5-digit ascii equivalent.
153 * @param word is the 16 bits of data to be sent, must be unsigned.
154 */
155void usart_print_word(uint16_t word)
156{
157 transmit_byte('0' + (word / 10000)); // Ten-thousands
158 transmit_byte('0' + ((word / 1000) % 10)); // Thousands
159 transmit_byte('0' + ((word / 100) % 10)); // Hundreds
160 transmit_byte('0' + ((word / 10) % 10)); // Tens
161 transmit_byte('0' + (word % 10)); // Ones
162}
163
164
165/*
166 * Prints a byte out in 1s and 0s.
167 * @param byte is the 8 bits of data to be sent, must be unsigned.
168 */
169void usart_print_binary_byte(uint8_t byte)
170{
171 uint8_t bit;
172 for (bit = 7; bit < 255; bit--)
173 {
174 if (bit_is_set(byte, bit))
175 {
176 transmit_byte('1');
177 }
178 else
179 {
180 transmit_byte('0');
181 }
182 }
183}
184
185
186/*
187 * Convert a nibble to a hex character.
188 * @param nibble is the 4 bits of data to be sent, must be unsigned.
189 */
191{
192 if (nibble < 10)
193 {
194 return ('0' + nibble);
195 }
196 else
197 {
198 return ('A' + nibble - 10);
199 }
200}
201
202
203/*
204 * Prints a byte out in hexadecimal format.
205 * @param byte is the 8 bits of data to be sent, must be unsigned.
206 */
207void usart_print_hex_byte(uint8_t byte)
208{
209 uint8_t nibble;
210 nibble = (byte & 0b11110000) >> 4;
211 transmit_byte(usart_nibble_to_hex_character(nibble));
212 nibble = byte & 0b00001111;
213 transmit_byte(usart_nibble_to_hex_character(nibble));
214}
215
216
217/*
218 * Takes in up to three ascii digits, converts them to a byte when press enter.
219 * @returns an unsigned 8 bit integer is returned - this is the data received.
220 */
221uint8_t usart_get_number(void)
222{
223 char hundreds = '0';
224 char tens = '0';
225 char ones = '0';
226 char thisChar = '0';
227 do
228 {
229 hundreds = tens;
230 tens = ones;
231 ones = thisChar;
232 thisChar = receive_byte(); // get a new character
233 transmit_byte(thisChar); // echo
234 }
235 while (thisChar != '\r'); // until type return
236
237 // TODO: Bracketise this further
238 return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0');
239}
240
241
242// ------------------------------------------------------------------------- //
243// ----------------------- Private Helper Functions ------------------------ //
244// ------------------------------------------------------------------------- //
245
246// Blocking data transmit function.
247static void transmit_byte(uint8_t data)
248{
249 // Wait for empty transmit buffer
250 loop_until_bit_is_set(UCSR0A, UDRE0);
251 // Send Data
252 UDR0 = data;
253}
254
255// Blocking data receive function.
256static uint8_t receive_byte(void)
257{
258 // Wait for incoming data
259 loop_until_bit_is_set(UCSR0A, RXC0);
260 //return register value
261 return UDR0;
262}
263
264
265/*** end of file ***/
void usart_print_decimal_digit(uint8_t byte)
Prints a byte out as its 1-digit ascii equivalent.
Definition: usart.c:135
void usart_print_string(const char myString[])
Utility function to transmit a string.
Definition: usart.c:74
void usart_print_byte(uint8_t byte)
Prints a byte out as its 3-digit ascii equivalent.
Definition: usart.c:121
void usart_read_string(char myString[], uint8_t maxLength)
Define a string variable, pass it to this function.
Definition: usart.c:92
void usart_print_binary_byte(uint8_t byte)
Prints a byte out in 1s and 0s.
Definition: usart.c:169
void usart_print_word(uint16_t word)
Prints a word (16-bits) out as its 5-digit ascii equivalent.
Definition: usart.c:155
char usart_nibble_to_hex_character(uint8_t nibble)
Convert a nibble to a hex character.
Definition: usart.c:190
uint8_t usart_get_number(void)
Takes in up to three ascii digits, converts them to a byte when press enter.
Definition: usart.c:221
void usart_print_char(char byte)
Prints a byte out as its 1-character ascii equivalent.
Definition: usart.c:145
void init_usart(void)
Takes the defined BAUD and F_CPU, calculates the bit-clock multiplier, configures the hardware USART ...
Definition: usart.c:50
void usart_print_hex_byte(uint8_t byte)
Prints a byte out in hexadecimal format.
Definition: usart.c:207
Driver file providing core USART communication between the target MCU and your PC.