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 bme280
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 if (byte > 99)
125 {
126 transmit_byte('0' + (byte / 100)); // Hundreds
127 }
128 if (byte > 9)
129 {
130 transmit_byte('0' + ((byte / 10) % 10)); // Tens
131 }
132 transmit_byte('0' + (byte % 10)); // Ones
133}
134
135
136/*
137 * Prints a byte out as its 1-digit ascii equivalent.
138 * @param byte is the 8 bits of data to be sent, must be unsigned, with a
139 * value of 0-9;
140 */
142{
143 transmit_byte(byte);
144}
145
146
147/*
148 * Prints a byte out as its 1-character ascii equivalent.
149 * @param byte is the character to be sent.
150 */
151void usart_print_char(char byte)
152{
153 transmit_byte(byte);
154}
155
156
157/*
158 * Prints a word (16-bits) out as its 5-digit ascii equivalent.
159 * @param word is the 16 bits of data to be sent, must be unsigned.
160 */
161void usart_print_word(uint16_t word)
162{
163 transmit_byte('0' + (word / 10000)); // Ten-thousands
164 transmit_byte('0' + ((word / 1000) % 10)); // Thousands
165 transmit_byte('0' + ((word / 100) % 10)); // Hundreds
166 transmit_byte('0' + ((word / 10) % 10)); // Tens
167 transmit_byte('0' + (word % 10)); // Ones
168}
169
170
171/*
172 * Prints a byte out in 1s and 0s.
173 * @param byte is the 8 bits of data to be sent, must be unsigned.
174 */
175void usart_print_binary_byte(uint8_t byte)
176{
177 uint8_t bit;
178 for (bit = 7; bit < 255; bit--)
179 {
180 if (bit_is_set(byte, bit))
181 {
182 transmit_byte('1');
183 }
184 else
185 {
186 transmit_byte('0');
187 }
188 }
189}
190
191
192/*
193 * Convert a nibble to a hex character.
194 * @param nibble is the 4 bits of data to be sent, must be unsigned.
195 */
197{
198 if (nibble < 10)
199 {
200 return ('0' + nibble);
201 }
202 else
203 {
204 return ('A' + nibble - 10);
205 }
206}
207
208
209/*
210 * Prints a byte out in hexadecimal format.
211 * @param byte is the 8 bits of data to be sent, must be unsigned.
212 */
213void usart_print_hex_byte(uint8_t byte)
214{
215 uint8_t nibble;
216 nibble = (byte & 0b11110000) >> 4;
217 transmit_byte(usart_nibble_to_hex_character(nibble));
218 nibble = byte & 0b00001111;
219 transmit_byte(usart_nibble_to_hex_character(nibble));
220}
221
222
223/*
224 * Takes in up to three ascii digits, converts them to a byte when press enter.
225 * @returns an unsigned 8 bit integer is returned - this is the data received.
226 */
227uint8_t usart_get_number(void)
228{
229 char hundreds = '0';
230 char tens = '0';
231 char ones = '0';
232 char thisChar = '0';
233 do
234 {
235 hundreds = tens;
236 tens = ones;
237 ones = thisChar;
238 thisChar = receive_byte(); // get a new character
239 transmit_byte(thisChar); // echo
240 }
241 while (thisChar != '\r'); // until type return
242
243 // TODO: Bracketise this further
244 return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0');
245}
246
247
248// ------------------------------------------------------------------------- //
249// ----------------------- Private Helper Functions ------------------------ //
250// ------------------------------------------------------------------------- //
251
252// Blocking data transmit function.
253static void transmit_byte(uint8_t data)
254{
255 // Wait for empty transmit buffer
256 loop_until_bit_is_set(UCSR0A, UDRE0);
257 // Send Data
258 UDR0 = data;
259}
260
261// Blocking data receive function.
262static uint8_t receive_byte(void)
263{
264 // Wait for incoming data
265 loop_until_bit_is_set(UCSR0A, RXC0);
266 //return register value
267 return UDR0;
268}
269
270
271/*** 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.