当前位置:网站首页>Reading sensor data with GPIO analog SPI interface

Reading sensor data with GPIO analog SPI interface

2022-06-25 07:13:00 Python's path to becoming a God

This article is based on Flathead development board RVB2601, This paper briefly introduces the use of GPIO simulation SPI Sequential logic , Realization SPI agreement , According to the timing of a specific temperature sensor , Read its data , And sample program

One 、 summary

SPI(Serial Peripheral Interface, Serial peripheral interface ) It is a full duplex synchronous serial communication interface , It is used for MCU Communicate with various peripheral devices in serial mode to exchange information , The communication speed can reach up to 25MHz above ,SPI The interface is mainly used in EEPROM、FLASH、 Real time clock 、 Network controller 、OLED Display drive 、AD converter , Digital signal processor 、 Digital signal decoder , Between temperature sensors and other equipment .

Here's the picture ,RVB2601 Two on board SPI Interface ,SPI0 Connect to W800, Transmit network information ,SPI1 Connect to OLED, For data display , In theory , One SPI Multiple devices can be attached to the bus , But if the timing logic of each device 、 The clock frequency is inconsistent , It will lead to low data transmission efficiency 、 Read write error 、 Even crashes , So I learned from Arduino Software simulation on the development board SPI The way , Based on Flathead RVB2601 Development board , adopt GPIO Connecting peripherals , Realize the connection of a SPI Interface temperature sensor , And read the data .

Two 、SPI  Sequential logic ( Reference resources STM32 Software simulation SPI Reading and writing Flash Memory

SPI It usually consists of four lines , A master output and a slave input (Master Output Slave Input,MOSI), A master input and a slave output (Master Input Slave Output,MISO), A clock signal (Serial Clock,SCLK), A slave device enables selection (Chip Select,CS). And I²C similar , The agreements are simple , You can also use GPIO simulation SPI sequential .

SPI One master can connect one or more slaves , Each slave uses a pin for chip selection , The physical connection diagram is shown in Figure 21.1.1  and   chart  21.1.2  Shown .

Data exchange

stay SCK Driven by the clock cycle ,MOSI and MISO At the same time , Pictured  21.1.3  Shown , It can be regarded as a virtual ring topology .

Both master and slave have a shift register , The host shift register data passes through MOSI Write data to the shift register of the slave , At this time, the data of the slave shift register also passes through MISO To the host , The data exchange between two shift registers is realized . Whether master or slave , Both sending and receiving are done at the same time , Like a “ Ring ”.

If the master only writes to the slave , The host only needs to ignore the received slave data . If the master wants to read the slave data , The master needs to send an empty data to trigger the slave to send data .

transmission mode

SPI There are four transmission modes , As shown in the table  21.1.2  Shown , The main difference is CPOL and CPHA Different .

CPOL(Clock Polarity, Clock polarity ) Express SCK High level or low level when idle . When CPOL=0,SCK Low level when idle , When CPOL=1,SCK High level when idle .

CPHA(Clock Phase, Clock phase ) Express SCK Sample data at the edge of the clock . When CPHA=0, stay SCK The first edge samples data , When CPHA=1, stay SCK The second edge samples data .

Pictured  21.1.4  Shown ,CPHA=0 when , Indicates that data is sampled at the first clock edge of the clock . When CPOL=1, That is, high level when idle , Change from high level to low level , First clock edge ( Falling edge ) I.e. sampling . When CPOL=0, That is, it is low when idle , From low level to high level , First clock edge ( Rising edge ) I.e. sampling .

Pictured  21.1.5  Shown ,CPHA=1 when , Indicates that data is sampled at the second clock edge of the clock . When CPOL=1, That is, high level when idle , Change from high level to low level and then to high level , Second clock edge ( Rising edge ) I.e. sampling . When CPOL=0, That is, it is low when idle , Change from low level to high level and then to low level , Second clock edge ( Falling edge ) I.e. sampling .

3、 ... and 、 Sensor timing ( Reference resources MAX6675 Use notes

MAX6675 Is a precise thermocouple digital converter , built-in 12 Bit ADC (ADC). MAX6675 It also includes cold end compensation detection and correction , Digital controller ,SPI Compatible interface and related control logic .MAX6675 Designed to operate at constant temperature , Use with external microcontrollers or other intelligent devices in process control or monitoring applications .

1. Temperature conversion

MAX6675 Including signal conditioning hardware , The signal of the thermocouple can be converted into and ADC Input channel compatible voltage .T + and T- The input is connected to the internal circuit , The noise error introduced by the thermocouple wire can be reduced .

Before converting the thermoelectric voltage to an equivalent temperature value , The cold end of the thermocouple must be compensated (MAX6675 ambient temperature ) And 0°C Differences between virtual benchmarks . about K Type thermocouple , The voltage changes to 41µV /°C, It can be approximated by the following linear equation

Thermocouple characteristics :

VOUT Is the thermocouple output voltage (µV).TR Is the temperature of the remote thermocouple junction (°C).TAMB It's the ambient temperature (°C).

2. Cold end compensation

The function of the thermocouple is to sense the temperature difference between the two ends of the thermocouple wire .  The hot end of the thermocouple can be read 0°C to + 1023.75°C Temperature of . Cold end ( install MAX6675 The ambient temperature of the circuit board ) Only in -20°C to + 85°C Change within the scope of . When the cold end temperature fluctuates ,MAX6675 Continue to accurately sense the temperature difference at the other end .

MAX6675 Cold junction compensation is used to detect and correct the change of ambient temperature . The device uses a temperature sensing diode to convert the ambient temperature reading into a voltage . For actual thermocouple temperature measurement ,MAX6675 Measure the voltage from thermocouple output and detection diode . The internal circuit of the device changes the voltage of the diode ( Sense the ambient temperature ) And thermocouple voltage ( Sense the remote temperature minus the ambient temperature ) Pass on to ADC Conversion functions stored in , To calculate the hot end temperature of the thermocouple . When the cold end of the thermocouple and MAX6675 At the same temperature , Can be realized MAX6675 Best performance of . To avoid the MAX6675 Place heating equipment or components nearby , Because this may cause errors related to the cold end .

3. Digitization

ADC Add the measured value of the cold junction diode to the amplified thermocouple voltage , And will 12 Bit results are read to SO On the pin , An all zero sequence indicates that the thermocouple reads 0°C. All for 1 The order of indicates that the thermocouple reading is + 1023.75°C.

4. serial interface

MAX6675 A typical circuit that interfaces with a microcontroller .

Transmit data through serial interface , mandatory CS A low level will immediately stop any switching process , And in SCK Apply a clock signal to read SO The results at ,  By force CS High level to start a new conversion process .

Complete serial interface reading requires 16 Clock cycles , Read on the falling edge of the clock 16 Output bits , first place D15 Is a pseudo sign bit , Always be 0,D14–D3 Bit contains from MSB To LSB Conversion temperature of , When the thermocouple input is disconnected ,D2 The bit is usually low , And change to high level , D1 Low level , by MAX6675 Provide devices ID,D0 The three state , chart 1a Is a serial interface protocol ,2 yes SO Output .

Four 、 Programming

be based on LED Demo New projects , In project folder app\include New header file in “soft_spi.h”, Definition SPI Data variables involved in transmission , Such as big end MSBFIRST, Clock level delay SOFTSPI_CLOCK_DIV2( In this example 1us Benchmarking , Carry out delay , The corresponding pulse width is obtained , Its minimum value has exceeded MAX6675 Required 100ns, It is used in the case of low transmission rate , But if it is used for the display , A slow refresh may occur , The phenomenon of Caton , If it's too demanding , Hardware is recommended SPI), Using transmission mode SOFTSPI_MODE2,SPI Interface pins PA7、PA25、PA4, among MISO(PA7) For input pins , The others are all output pins .

Initialization function spi_pinmux_init(), Working mode setDataMode(uint8_t), Transfer function transfer16(uint16_t data), Read temperature value read_temp(uint16_t data).

#ifndef __SOFTSPI_H_
#define __SOFTSPI_H_

//#include "stdint.h"
#include <stdio.h>
#include <string.h>
#include "drv/gpio_pin.h"
#include <drv/pin.h>
 
#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif

#define SOFTSPI_MODE0 0x00
#define SOFTSPI_MODE1 0x04
#define SOFTSPI_MODE2 0x08
#define SOFTSPI_MODE3 0x0C

#define SOFTSPI_MISO PA7
#define SOFTSPI_MOSI PA25
#define SOFTSPI_SCK PA4

void wait(uint32_t del);
void spi_pinmux_init();
void setBitOrder(uint8_t);
void setDataMode(uint8_t);
uint8_t transfer(uint8_t);
uint16_t transfer16(uint16_t data);
uint16_t  read_temp(uint16_t data);
#endif

In project folder app\src New source file in “soft_spi.c”

#include "app_config.h"
#include "soft_spi.h"
#ifdef CONFIG_SOFT_SPI_MODE
csi_gpio_pin_t _miso;
csi_gpio_pin_t _mosi;
csi_gpio_pin_t _sck;
uint8_t _CPOL; //CPOL Clock Polarity, Clock polarity 
uint8_t _CPHA; //CPHA Clock Phase, Clock phase 
uint8_t _delay;
uint8_t _order;
void spi_pinmux_init()
{
	// according to SOFTSOFTSPI_MODE2  To initialize 
    csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
    csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
    csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
    csi_gpio_pin_init(&_miso, PA7);
    csi_gpio_pin_dir(&_miso, GPIO_DIRECTION_INPUT);
    csi_gpio_pin_init(&_mosi, PA25);
    csi_gpio_pin_dir(&_mosi, GPIO_DIRECTION_OUTPUT);
    csi_gpio_pin_init(&_sck, PA4);
    csi_gpio_pin_dir(&_sck, GPIO_DIRECTION_OUTPUT);
	_CPHA = 0;
    _CPOL = 1; 
	_delay = 2;
    _order = MSBFIRST;
}
void  setBitOrder(uint8_t order) {
    _order = order & 1;
}
void  setDataMode(uint8_t mode) {
	//CPOL(Clock Polarity, Clock polarity ) Express SCK High level or low level when idle . When CPOL=0,SCK Low level when idle , When CPOL=1,SCK High level when idle .
	//CPHA(Clock Phase, Clock phase ) Express SCK Sample data at the edge of the clock . When CPHA=0, stay SCK The first edge samples data , When CPHA=1, stay SCK The second edge samples data .
    switch (mode) {
        case SOFTSPI_MODE0:
            _CPOL = 0; //CPOL
            _CPHA = 0; //CPHA
            break;
        case SOFTSPI_MODE1:
            _CPOL = 0;
            _CPHA = 1;
            break;
        case SOFTSPI_MODE2:
            _CPOL = 1;
            _CPHA = 0;
            break;
        case SOFTSPI_MODE3:
            _CPOL = 1;
            _CPHA = 1;
            break;
    }
    csi_gpio_pin_write(&_sck, _CPOL ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
}
void  wait(uint32_t dl) {
    for (uint32_t i = 0; i < dl; i++) {
        udelay(dl);
    }
}
uint8_t  transfer(uint8_t val) {
    uint8_t out = 0;
    if (_order == MSBFIRST) {
        uint8_t v2 = 
            ((val & 0x01) << 7) |
            ((val & 0x02) << 5) |
            ((val & 0x04) << 3) |
            ((val & 0x08) << 1) |
            ((val & 0x10) >> 1) |
            ((val & 0x20) >> 3) |
            ((val & 0x40) >> 5) |
            ((val & 0x80) >> 7);
        val = v2;
    }
    uint8_t del = _delay >> 1;
    uint8_t bval = 0;
    //
    //  CPOL := 0, CPHA := 0 => INIT = 0, PRE = Z|0, MID = 1, POST =  0
    //  CPOL := 1, CPHA := 0 => INIT = 1, PRE = Z|1, MID = 0, POST =  1
    //  CPOL := 0, CPHA := 1 => INIT = 0, PRE =  1 , MID = 0, POST = Z|0
    //  CPOL := 1, CPHA := 1 => INIT = 1, PRE =  0 , MID = 1, POST = Z|1
    // 
    csi_gpio_pin_state_t sck = (_CPOL) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
    for (uint8_t bit = 0u; bit < 8u; bit++)
    {
        if (_CPHA) {
            sck ^= GPIO_PIN_HIGH;
            csi_gpio_pin_write(&_sck, sck);            
            wait(del);
        }
        // ... Write bit 
        csi_gpio_pin_write(&_mosi, ((val & (1<<bit)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW));
        wait(del);
        sck ^= 1u; 
		csi_gpio_pin_write(&_sck, sck);
        // ... Read bit 
        {
            bval = csi_gpio_pin_read(&_miso);

            if (_order == MSBFIRST) {
                out <<= 1;
                out |= bval;
            } else {
                out >>= 1;
                out |= bval << 7;
            }
        }
        wait(del);
        if (!_CPHA) {
            sck ^= 1u;
            csi_gpio_pin_write(&_sck, sck);
        }
    }
    return out;
}
uint16_t  transfer16(uint16_t data)
{
	union {
		uint16_t val;
		struct {
			uint8_t lsb;
			uint8_t msb;
		};
	} in, out;
  	in.val = data;
	if ( _order == MSBFIRST ) {
		out.msb = transfer(in.msb);
		out.lsb = transfer(in.lsb);
	} else {
		out.lsb = transfer(in.lsb);
		out.msb = transfer(in.msb);
	}
	return out.val;
}

uint16_t  read_temp(uint16_t data)
{
	uint16_t temp,temp0;
	temp0 = transfer16(data);
	temp0 = temp0 >> 3;
	temp =temp0 *0.25;
	return temp;
}

#endif

5、 ... and 、 The test program

stay main Add test code to the function , Short circuit on the development board J3:3、5 Pin ,

		#include "soft_spi.h"
    spi_pinmux_init();
		uint32_t t0;
		while (1)
    {
		t0 = transfer16(0xffff);
		printf("transfer16 test:%d\n\r",t0);
		printf("temprature:%d\n\r",read_temp(0x7fff));
    }

Test renderings :

原网站

版权声明
本文为[Python's path to becoming a God]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202201234082789.html