IniSat Modèle 1 Version 2 TP 5 : Station Sol Exo 1 : Enregistrement GPS sur carte SD Exo 2 : Mise en place d'un protocole de communication avec la station sol
Dependencies: mbed
Soft_UART/soft_uart.cpp@0:798c7207505d, 2022-05-31 (annotated)
- Committer:
- Giamarchi
- Date:
- Tue May 31 13:40:28 2022 +0000
- Revision:
- 0:798c7207505d
MAJ
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Giamarchi | 0:798c7207505d | 1 | // Software UART |
Giamarchi | 0:798c7207505d | 2 | // |
Giamarchi | 0:798c7207505d | 3 | // Generic software uart written in C, requiring a timer set to 3 times |
Giamarchi | 0:798c7207505d | 4 | // the baud rate, and two software read/write pins for the receive and |
Giamarchi | 0:798c7207505d | 5 | // transmit functions. |
Giamarchi | 0:798c7207505d | 6 | // |
Giamarchi | 0:798c7207505d | 7 | // * Received characters are buffered |
Giamarchi | 0:798c7207505d | 8 | // * putchar(), getchar(), kbhit() and flush_input_buffer() are available |
Giamarchi | 0:798c7207505d | 9 | // * There is a facility for background processing while waiting for input |
Giamarchi | 0:798c7207505d | 10 | // |
Giamarchi | 0:798c7207505d | 11 | // Colin Gittins, Software Engineer, Halliburton Energy Services |
Giamarchi | 0:798c7207505d | 12 | // |
Giamarchi | 0:798c7207505d | 13 | // The baud rate can be configured by changing the BAUD_RATE macro as |
Giamarchi | 0:798c7207505d | 14 | // follows: |
Giamarchi | 0:798c7207505d | 15 | // |
Giamarchi | 0:798c7207505d | 16 | // #define BAUD_RATE 19200.0 |
Giamarchi | 0:798c7207505d | 17 | // |
Giamarchi | 0:798c7207505d | 18 | // The function init_uart() must be called before any comms can take place |
Giamarchi | 0:798c7207505d | 19 | // |
Giamarchi | 0:798c7207505d | 20 | // Interface routines required: |
Giamarchi | 0:798c7207505d | 21 | // 1. get_rx_pin_status() |
Giamarchi | 0:798c7207505d | 22 | // Returns 0 or 1 dependent on whether the receive pin is high or low. |
Giamarchi | 0:798c7207505d | 23 | // 2. set_tx_pin_high() |
Giamarchi | 0:798c7207505d | 24 | // Sets the transmit pin to the high state. |
Giamarchi | 0:798c7207505d | 25 | // 3. set_tx_pin_low() |
Giamarchi | 0:798c7207505d | 26 | // Sets the transmit pin to the low state. |
Giamarchi | 0:798c7207505d | 27 | // 4. idle() |
Giamarchi | 0:798c7207505d | 28 | // Background functions to execute while waiting for input. |
Giamarchi | 0:798c7207505d | 29 | // 5. timer_set( BAUD_RATE ) |
Giamarchi | 0:798c7207505d | 30 | // Sets the timer to 3 times the baud rate. |
Giamarchi | 0:798c7207505d | 31 | // 6. set_timer_interrupt( timer_isr ) |
Giamarchi | 0:798c7207505d | 32 | // Enables the timer interrupt. |
Giamarchi | 0:798c7207505d | 33 | // |
Giamarchi | 0:798c7207505d | 34 | // Functions provided: |
Giamarchi | 0:798c7207505d | 35 | // 1. void flush_input_buffer( void ) |
Giamarchi | 0:798c7207505d | 36 | // Clears the contents of the input buffer. |
Giamarchi | 0:798c7207505d | 37 | // 2. char kbhit( void ) |
Giamarchi | 0:798c7207505d | 38 | // Tests whether an input character has been received. |
Giamarchi | 0:798c7207505d | 39 | // 3. char getchar( void ) |
Giamarchi | 0:798c7207505d | 40 | // Reads a character from the input buffer, waiting if necessary. |
Giamarchi | 0:798c7207505d | 41 | // 4. void turn_rx_on( void ) |
Giamarchi | 0:798c7207505d | 42 | // Turns on the receive function. |
Giamarchi | 0:798c7207505d | 43 | // 5. void turn_rx_off( void ) |
Giamarchi | 0:798c7207505d | 44 | // Turns off the receive function. |
Giamarchi | 0:798c7207505d | 45 | // 6. void putchar( char ) |
Giamarchi | 0:798c7207505d | 46 | // Writes a character to the serial port. |
Giamarchi | 0:798c7207505d | 47 | #include "mbed.h" |
Giamarchi | 0:798c7207505d | 48 | #include <stdio.h> |
Giamarchi | 0:798c7207505d | 49 | |
Giamarchi | 0:798c7207505d | 50 | #define BAUD_RATE 9600 |
Giamarchi | 0:798c7207505d | 51 | #define IN_BUF_SIZE 256 |
Giamarchi | 0:798c7207505d | 52 | |
Giamarchi | 0:798c7207505d | 53 | #define TRUE 1 |
Giamarchi | 0:798c7207505d | 54 | #define FALSE 0 |
Giamarchi | 0:798c7207505d | 55 | |
Giamarchi | 0:798c7207505d | 56 | static unsigned char inbuf[IN_BUF_SIZE]; |
Giamarchi | 0:798c7207505d | 57 | static unsigned char qin = 0; |
Giamarchi | 0:798c7207505d | 58 | static unsigned char qout = 0; |
Giamarchi | 0:798c7207505d | 59 | |
Giamarchi | 0:798c7207505d | 60 | static char flag_rx_waiting_for_stop_bit; |
Giamarchi | 0:798c7207505d | 61 | static char flag_rx_off; |
Giamarchi | 0:798c7207505d | 62 | static char rx_mask; |
Giamarchi | 0:798c7207505d | 63 | static char flag_rx_ready; |
Giamarchi | 0:798c7207505d | 64 | static char flag_tx_ready; |
Giamarchi | 0:798c7207505d | 65 | static char timer_rx_ctr; |
Giamarchi | 0:798c7207505d | 66 | static char timer_tx_ctr; |
Giamarchi | 0:798c7207505d | 67 | static char bits_left_in_rx; |
Giamarchi | 0:798c7207505d | 68 | static char bits_left_in_tx; |
Giamarchi | 0:798c7207505d | 69 | static char rx_num_of_bits; |
Giamarchi | 0:798c7207505d | 70 | static char tx_num_of_bits; |
Giamarchi | 0:798c7207505d | 71 | static int internal_rx_buffer; |
Giamarchi | 0:798c7207505d | 72 | static int internal_tx_buffer; |
Giamarchi | 0:798c7207505d | 73 | static int user_tx_buffer; |
Giamarchi | 0:798c7207505d | 74 | |
Giamarchi | 0:798c7207505d | 75 | DigitalOut TX(PA_4); |
Giamarchi | 0:798c7207505d | 76 | DigitalIn RX(PA_3); |
Giamarchi | 0:798c7207505d | 77 | Ticker ticker; |
Giamarchi | 0:798c7207505d | 78 | |
Giamarchi | 0:798c7207505d | 79 | //Background functions to execute while waiting for input. |
Giamarchi | 0:798c7207505d | 80 | void idle(){ |
Giamarchi | 0:798c7207505d | 81 | wait_us(0.2); |
Giamarchi | 0:798c7207505d | 82 | } |
Giamarchi | 0:798c7207505d | 83 | |
Giamarchi | 0:798c7207505d | 84 | //Sets the transmit pin to the high state. |
Giamarchi | 0:798c7207505d | 85 | void set_tx_pin_high() { |
Giamarchi | 0:798c7207505d | 86 | TX = 1; |
Giamarchi | 0:798c7207505d | 87 | } |
Giamarchi | 0:798c7207505d | 88 | |
Giamarchi | 0:798c7207505d | 89 | //Sets the transmit pin to the low state. |
Giamarchi | 0:798c7207505d | 90 | void set_tx_pin_low() { |
Giamarchi | 0:798c7207505d | 91 | TX = 0; |
Giamarchi | 0:798c7207505d | 92 | } |
Giamarchi | 0:798c7207505d | 93 | |
Giamarchi | 0:798c7207505d | 94 | //Returns 0 or 1 dependent on whether the receive pin is high or low |
Giamarchi | 0:798c7207505d | 95 | int get_rx_pin_status() { |
Giamarchi | 0:798c7207505d | 96 | return RX.read(); |
Giamarchi | 0:798c7207505d | 97 | } |
Giamarchi | 0:798c7207505d | 98 | |
Giamarchi | 0:798c7207505d | 99 | void timer_isr(void) { |
Giamarchi | 0:798c7207505d | 100 | |
Giamarchi | 0:798c7207505d | 101 | char mask, start_bit, flag_in; |
Giamarchi | 0:798c7207505d | 102 | |
Giamarchi | 0:798c7207505d | 103 | // Transmitter Section |
Giamarchi | 0:798c7207505d | 104 | if ( flag_tx_ready ) |
Giamarchi | 0:798c7207505d | 105 | { |
Giamarchi | 0:798c7207505d | 106 | |
Giamarchi | 0:798c7207505d | 107 | if ( --timer_tx_ctr <= 0 ) |
Giamarchi | 0:798c7207505d | 108 | { |
Giamarchi | 0:798c7207505d | 109 | mask = internal_tx_buffer&1; |
Giamarchi | 0:798c7207505d | 110 | internal_tx_buffer >>= 1; |
Giamarchi | 0:798c7207505d | 111 | if ( mask ) |
Giamarchi | 0:798c7207505d | 112 | { |
Giamarchi | 0:798c7207505d | 113 | set_tx_pin_high(); |
Giamarchi | 0:798c7207505d | 114 | } |
Giamarchi | 0:798c7207505d | 115 | else |
Giamarchi | 0:798c7207505d | 116 | { |
Giamarchi | 0:798c7207505d | 117 | set_tx_pin_low(); |
Giamarchi | 0:798c7207505d | 118 | } |
Giamarchi | 0:798c7207505d | 119 | timer_tx_ctr = 3; |
Giamarchi | 0:798c7207505d | 120 | if ( --bits_left_in_tx <= 0 ) |
Giamarchi | 0:798c7207505d | 121 | { |
Giamarchi | 0:798c7207505d | 122 | flag_tx_ready = FALSE; |
Giamarchi | 0:798c7207505d | 123 | } |
Giamarchi | 0:798c7207505d | 124 | } |
Giamarchi | 0:798c7207505d | 125 | } |
Giamarchi | 0:798c7207505d | 126 | // Receiver Section |
Giamarchi | 0:798c7207505d | 127 | if ( flag_rx_off == FALSE ) |
Giamarchi | 0:798c7207505d | 128 | { |
Giamarchi | 0:798c7207505d | 129 | if ( flag_rx_waiting_for_stop_bit ) |
Giamarchi | 0:798c7207505d | 130 | { |
Giamarchi | 0:798c7207505d | 131 | if ( --timer_rx_ctr <= 0 ) |
Giamarchi | 0:798c7207505d | 132 | { |
Giamarchi | 0:798c7207505d | 133 | flag_rx_waiting_for_stop_bit = FALSE; |
Giamarchi | 0:798c7207505d | 134 | flag_rx_ready = FALSE; |
Giamarchi | 0:798c7207505d | 135 | internal_rx_buffer &= 0xFF; |
Giamarchi | 0:798c7207505d | 136 | if ( internal_rx_buffer != 0xC2 ) |
Giamarchi | 0:798c7207505d | 137 | { |
Giamarchi | 0:798c7207505d | 138 | inbuf[qin] = internal_rx_buffer; |
Giamarchi | 0:798c7207505d | 139 | if ( ++qin >= IN_BUF_SIZE ) |
Giamarchi | 0:798c7207505d | 140 | { |
Giamarchi | 0:798c7207505d | 141 | qin = 0; |
Giamarchi | 0:798c7207505d | 142 | } |
Giamarchi | 0:798c7207505d | 143 | } |
Giamarchi | 0:798c7207505d | 144 | } |
Giamarchi | 0:798c7207505d | 145 | } |
Giamarchi | 0:798c7207505d | 146 | else // rx_test_busy |
Giamarchi | 0:798c7207505d | 147 | { |
Giamarchi | 0:798c7207505d | 148 | if ( flag_rx_ready==FALSE ) |
Giamarchi | 0:798c7207505d | 149 | { |
Giamarchi | 0:798c7207505d | 150 | start_bit = get_rx_pin_status(); |
Giamarchi | 0:798c7207505d | 151 | // Test for Start Bit |
Giamarchi | 0:798c7207505d | 152 | if ( start_bit == 0 ) |
Giamarchi | 0:798c7207505d | 153 | { |
Giamarchi | 0:798c7207505d | 154 | flag_rx_ready = TRUE; |
Giamarchi | 0:798c7207505d | 155 | internal_rx_buffer = 0; |
Giamarchi | 0:798c7207505d | 156 | timer_rx_ctr = 4; |
Giamarchi | 0:798c7207505d | 157 | bits_left_in_rx = rx_num_of_bits; |
Giamarchi | 0:798c7207505d | 158 | rx_mask = 1; |
Giamarchi | 0:798c7207505d | 159 | } |
Giamarchi | 0:798c7207505d | 160 | } |
Giamarchi | 0:798c7207505d | 161 | else // rx_busy |
Giamarchi | 0:798c7207505d | 162 | { |
Giamarchi | 0:798c7207505d | 163 | if ( --timer_rx_ctr<=0 ) |
Giamarchi | 0:798c7207505d | 164 | { // rcv |
Giamarchi | 0:798c7207505d | 165 | timer_rx_ctr = 3; |
Giamarchi | 0:798c7207505d | 166 | flag_in = get_rx_pin_status(); |
Giamarchi | 0:798c7207505d | 167 | if ( flag_in ) |
Giamarchi | 0:798c7207505d | 168 | { |
Giamarchi | 0:798c7207505d | 169 | internal_rx_buffer |= rx_mask; |
Giamarchi | 0:798c7207505d | 170 | } |
Giamarchi | 0:798c7207505d | 171 | rx_mask <<= 1; |
Giamarchi | 0:798c7207505d | 172 | if ( --bits_left_in_rx<=0 ) |
Giamarchi | 0:798c7207505d | 173 | { |
Giamarchi | 0:798c7207505d | 174 | flag_rx_waiting_for_stop_bit = TRUE; |
Giamarchi | 0:798c7207505d | 175 | } |
Giamarchi | 0:798c7207505d | 176 | } |
Giamarchi | 0:798c7207505d | 177 | } |
Giamarchi | 0:798c7207505d | 178 | } |
Giamarchi | 0:798c7207505d | 179 | } |
Giamarchi | 0:798c7207505d | 180 | } |
Giamarchi | 0:798c7207505d | 181 | |
Giamarchi | 0:798c7207505d | 182 | void Init_Soft_UART(void) { |
Giamarchi | 0:798c7207505d | 183 | flag_tx_ready = FALSE; |
Giamarchi | 0:798c7207505d | 184 | flag_rx_ready = FALSE; |
Giamarchi | 0:798c7207505d | 185 | flag_rx_waiting_for_stop_bit = FALSE; |
Giamarchi | 0:798c7207505d | 186 | flag_rx_off = FALSE; |
Giamarchi | 0:798c7207505d | 187 | rx_num_of_bits = 8; //10 |
Giamarchi | 0:798c7207505d | 188 | tx_num_of_bits = 10; //10 |
Giamarchi | 0:798c7207505d | 189 | |
Giamarchi | 0:798c7207505d | 190 | set_tx_pin_high(); |
Giamarchi | 0:798c7207505d | 191 | ticker.attach_us(&timer_isr, 1000000.0 / (BAUD_RATE * 3.0)); |
Giamarchi | 0:798c7207505d | 192 | } |
Giamarchi | 0:798c7207505d | 193 | |
Giamarchi | 0:798c7207505d | 194 | char _getchar(void) { |
Giamarchi | 0:798c7207505d | 195 | char ch; |
Giamarchi | 0:798c7207505d | 196 | do |
Giamarchi | 0:798c7207505d | 197 | { |
Giamarchi | 0:798c7207505d | 198 | while (qout == qin) |
Giamarchi | 0:798c7207505d | 199 | { |
Giamarchi | 0:798c7207505d | 200 | idle(); |
Giamarchi | 0:798c7207505d | 201 | } |
Giamarchi | 0:798c7207505d | 202 | ch = inbuf[qout] & 0xFF; |
Giamarchi | 0:798c7207505d | 203 | if (++qout >= IN_BUF_SIZE) |
Giamarchi | 0:798c7207505d | 204 | { |
Giamarchi | 0:798c7207505d | 205 | qout = 0; |
Giamarchi | 0:798c7207505d | 206 | } |
Giamarchi | 0:798c7207505d | 207 | } |
Giamarchi | 0:798c7207505d | 208 | while (ch == 0x0A || ch == 0xC2); |
Giamarchi | 0:798c7207505d | 209 | return(ch); |
Giamarchi | 0:798c7207505d | 210 | } |
Giamarchi | 0:798c7207505d | 211 | |
Giamarchi | 0:798c7207505d | 212 | void _putchar(char ch) { |
Giamarchi | 0:798c7207505d | 213 | while ( flag_tx_ready ); |
Giamarchi | 0:798c7207505d | 214 | user_tx_buffer = ch; |
Giamarchi | 0:798c7207505d | 215 | |
Giamarchi | 0:798c7207505d | 216 | // invoke_UART_transmit |
Giamarchi | 0:798c7207505d | 217 | timer_tx_ctr = 3; |
Giamarchi | 0:798c7207505d | 218 | bits_left_in_tx = tx_num_of_bits; |
Giamarchi | 0:798c7207505d | 219 | internal_tx_buffer = (user_tx_buffer<<1) | 0x200;; |
Giamarchi | 0:798c7207505d | 220 | flag_tx_ready = TRUE; |
Giamarchi | 0:798c7207505d | 221 | } |
Giamarchi | 0:798c7207505d | 222 | |
Giamarchi | 0:798c7207505d | 223 | void flush_input_buffer(void) { |
Giamarchi | 0:798c7207505d | 224 | qin = 0; |
Giamarchi | 0:798c7207505d | 225 | qout = 0; |
Giamarchi | 0:798c7207505d | 226 | } |
Giamarchi | 0:798c7207505d | 227 | |
Giamarchi | 0:798c7207505d | 228 | char kbhit(void) { |
Giamarchi | 0:798c7207505d | 229 | return( qin!=qout ); |
Giamarchi | 0:798c7207505d | 230 | } |
Giamarchi | 0:798c7207505d | 231 | |
Giamarchi | 0:798c7207505d | 232 | void turn_rx_on(void) { |
Giamarchi | 0:798c7207505d | 233 | flag_rx_off = FALSE; |
Giamarchi | 0:798c7207505d | 234 | } |
Giamarchi | 0:798c7207505d | 235 | |
Giamarchi | 0:798c7207505d | 236 | void turn_rx_off(void) { |
Giamarchi | 0:798c7207505d | 237 | flag_rx_off = TRUE; |
Giamarchi | 0:798c7207505d | 238 | } |
Giamarchi | 0:798c7207505d | 239 | |
Giamarchi | 0:798c7207505d | 240 | void printStr(char* str) { |
Giamarchi | 0:798c7207505d | 241 | int i = 0; |
Giamarchi | 0:798c7207505d | 242 | int len = strlen(str); |
Giamarchi | 0:798c7207505d | 243 | for(i = 0; i<len; i++){ |
Giamarchi | 0:798c7207505d | 244 | wait(0.01); |
Giamarchi | 0:798c7207505d | 245 | _putchar(str[i]); |
Giamarchi | 0:798c7207505d | 246 | } |
Giamarchi | 0:798c7207505d | 247 | } |
Giamarchi | 0:798c7207505d | 248 |