Markus Grönholm
/
GMR-sensor-example
Example for TLE5012B GMR sensor
Diff: main.cpp
- Revision:
- 0:1f873630ed4f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Feb 07 12:18:49 2019 +0000 @@ -0,0 +1,98 @@ +#include "mbed.h" + +Serial pc(SERIAL_TX, SERIAL_RX); + + +/* This example uses pins A0, A1 and A2 as SSC interface pins */ +DigitalOut SCK( A0 ); +DigitalInOut DATA( A2 ); +DigitalOut CSQ( A1 ); + + + +/*Functions for bit level access to SSC bus */ + +inline void ssc_write_bit( int value ){ + SCK = 0; + wait_us(1); + SCK = 1; + wait_us(1); + if( value != 0 ){ DATA = 1; } else { DATA = 0; } + wait_us(1); + SCK = 0; + } + +inline int ssc_read_bit(){ + int out = 0; + SCK = 0; + wait_us(1); + SCK = 1; + + wait_us(1); + SCK = 0; + if( DATA.read() != 0 ){ out = 1; } + + + return out; + } + +/* Functions to read & write 16bit words via SSC */ + +void ssc_write_word( uint16_t word ){ + DATA.output(); + wait_us(1); + for( int i = 0; i < 16 ; ++i ){ + ssc_write_bit( word & 0x8000 ); + word <<= 1; + } + } + +uint16_t ssc_read_word(){ + uint16_t word = 0; + DATA.input(); + wait_us(1); + for( int i = 0; i < 16; ++i ){ + word <<= 1; + word |= ssc_read_bit(); + } + + return word; + } + +/* And function to read angle from GMR sensor */ +float encoder_read_angle(){ + uint16_t data[2] = {10,10}; + uint16_t cmd = 0x8000 | (2<<4) | 1; + float angle; + + /* Request new measurement */ + SCK = 0; + CSQ = 0; + wait_us(2); + CSQ = 1; + wait_us(2); + + /* Read angle register */ + SCK = 0; + CSQ = 0; + ssc_write_word( cmd ); + wait_us(2); + data[0] = ssc_read_word(); /* angle */ + data[1] = ssc_read_word(); /* checksum */ + CSQ = 1; + + /* compute angle from measurement */ + angle = (0x7fff & data[0]) * 360.0f/(32768.0f); + + return angle; + } + +int main() { + pc.baud( 115200 ); + + while(1) { + float angle = encoder_read_angle(); + pc.printf( "Angle: %.2f deg\r\n", angle ); + wait( 0.25 ); + } + }