IniSat Modèle 1 Version 2 TP 4 : Etude d'un capteur Exo 1 : Lecture température Exo 2 : GPS, décodage données GGA
Soft_UART/soft_uart.cpp
- Committer:
- Giamarchi
- Date:
- 2021-06-30
- Revision:
- 1:ec64d7748431
- Parent:
- 0:8b4bad2aad3f
File content as of revision 1:ec64d7748431:
// Software UART // // Generic software uart written in C, requiring a timer set to 3 times // the baud rate, and two software read/write pins for the receive and // transmit functions. // // * Received characters are buffered // * putchar(), getchar(), kbhit() and flush_input_buffer() are available // * There is a facility for background processing while waiting for input // // Colin Gittins, Software Engineer, Halliburton Energy Services // // The baud rate can be configured by changing the BAUD_RATE macro as // follows: // // #define BAUD_RATE 19200.0 // // The function init_uart() must be called before any comms can take place // // Interface routines required: // 1. get_rx_pin_status() // Returns 0 or 1 dependent on whether the receive pin is high or low. // 2. set_tx_pin_high() // Sets the transmit pin to the high state. // 3. set_tx_pin_low() // Sets the transmit pin to the low state. // 4. idle() // Background functions to execute while waiting for input. // 5. timer_set( BAUD_RATE ) // Sets the timer to 3 times the baud rate. // 6. set_timer_interrupt( timer_isr ) // Enables the timer interrupt. // // Functions provided: // 1. void flush_input_buffer( void ) // Clears the contents of the input buffer. // 2. char kbhit( void ) // Tests whether an input character has been received. // 3. char getchar( void ) // Reads a character from the input buffer, waiting if necessary. // 4. void turn_rx_on( void ) // Turns on the receive function. // 5. void turn_rx_off( void ) // Turns off the receive function. // 6. void putchar( char ) // Writes a character to the serial port. #include "mbed.h" #include <stdio.h> #define BAUD_RATE 9600 #define IN_BUF_SIZE 256 #define TRUE 1 #define FALSE 0 static unsigned char inbuf[IN_BUF_SIZE]; static unsigned char qin = 0; static unsigned char qout = 0; static char flag_rx_waiting_for_stop_bit; static char flag_rx_off; static char rx_mask; static char flag_rx_ready; static char flag_tx_ready; static char timer_rx_ctr; static char timer_tx_ctr; static char bits_left_in_rx; static char bits_left_in_tx; static char rx_num_of_bits; static char tx_num_of_bits; static int internal_rx_buffer; static int internal_tx_buffer; static int user_tx_buffer; DigitalOut TX(PA_4); DigitalIn RX(PA_3); Ticker ticker; //Background functions to execute while waiting for input. void idle(){ wait_us(0.2); } //Sets the transmit pin to the high state. void set_tx_pin_high() { TX = 1; } //Sets the transmit pin to the low state. void set_tx_pin_low() { TX = 0; } //Returns 0 or 1 dependent on whether the receive pin is high or low int get_rx_pin_status() { return RX.read(); } void timer_isr(void) { char mask, start_bit, flag_in; // Transmitter Section if ( flag_tx_ready ) { if ( --timer_tx_ctr <= 0 ) { mask = internal_tx_buffer&1; internal_tx_buffer >>= 1; if ( mask ) { set_tx_pin_high(); } else { set_tx_pin_low(); } timer_tx_ctr = 3; if ( --bits_left_in_tx <= 0 ) { flag_tx_ready = FALSE; } } } // Receiver Section if ( flag_rx_off == FALSE ) { if ( flag_rx_waiting_for_stop_bit ) { if ( --timer_rx_ctr <= 0 ) { flag_rx_waiting_for_stop_bit = FALSE; flag_rx_ready = FALSE; internal_rx_buffer &= 0xFF; if ( internal_rx_buffer != 0xC2 ) { inbuf[qin] = internal_rx_buffer; if ( ++qin >= IN_BUF_SIZE ) { qin = 0; } } } } else // rx_test_busy { if ( flag_rx_ready==FALSE ) { start_bit = get_rx_pin_status(); // Test for Start Bit if ( start_bit == 0 ) { flag_rx_ready = TRUE; internal_rx_buffer = 0; timer_rx_ctr = 4; bits_left_in_rx = rx_num_of_bits; rx_mask = 1; } } else // rx_busy { if ( --timer_rx_ctr<=0 ) { // rcv timer_rx_ctr = 3; flag_in = get_rx_pin_status(); if ( flag_in ) { internal_rx_buffer |= rx_mask; } rx_mask <<= 1; if ( --bits_left_in_rx<=0 ) { flag_rx_waiting_for_stop_bit = TRUE; } } } } } } void Init_Soft_UART(void) { flag_tx_ready = FALSE; flag_rx_ready = FALSE; flag_rx_waiting_for_stop_bit = FALSE; flag_rx_off = FALSE; rx_num_of_bits = 8; //10 tx_num_of_bits = 10; //10 set_tx_pin_high(); ticker.attach_us(&timer_isr, 1000000.0 / (BAUD_RATE * 3.0)); } char _getchar(void) { char ch; do { while (qout == qin) { idle(); } ch = inbuf[qout] & 0xFF; if (++qout >= IN_BUF_SIZE) { qout = 0; } } while (ch == 0x0A || ch == 0xC2); return(ch); } void _putchar(char ch) { while ( flag_tx_ready ); user_tx_buffer = ch; // invoke_UART_transmit timer_tx_ctr = 3; bits_left_in_tx = tx_num_of_bits; internal_tx_buffer = (user_tx_buffer<<1) | 0x200;; flag_tx_ready = TRUE; } void flush_input_buffer(void) { qin = 0; qout = 0; } char kbhit(void) { return( qin!=qout ); } void turn_rx_on(void) { flag_rx_off = FALSE; } void turn_rx_off(void) { flag_rx_off = TRUE; } void printStr(char* str) { int i = 0; int len = strlen(str); for(i = 0; i<len; i++){ wait(0.01); _putchar(str[i]); } }