Målet er å lage ett gaussmeter basert på en hall effekt sensor. Verdien skal vises på en LCD skjerm.
Utstyr
- STM32F303K8 (Mikrokontroller)
- SS495A (Hall effekt sensor)
- EA DOGM164 (Skjerm)
- EA LED40x33-A (Bakgrunnsbelysning)
- 2 stk. 1uF kondensator
- 2 stk. 1,2K ohm motstand
- 20 ohm motstand

Oppsett
Forklaring hall effekt sensor
Vi kjører 5V spenning over hall effekt sensoren. Utgangen på denne vil bli 2.5V så lenge målt gauss er 0. Siden dette betyr at spenningen ut kan bli over 3.3V som er maks spenning inn på mikrokontrolleren så deler vi denne i to før vi måler den analoge verdien på mikrokontrolleren.
For hver 3.125mV endring så er den målte verdien +/- 1 gauss. Siden den blir delt på to så vil 1 gauss endring på inngangen til mikrokontrolleren være 1.562mV.

Forklaring oppsett skjerm
Skjermen er koblet til mikrokontrolleren med SPI. SPI modusen til skjermen må være modus 3. Det vil si at den trigger på endring fra lav til høy og at polariteten er høy. Maks frekvens er 400Khz, men er i dette tilfellet satt til ca. 32Khz.

Forklaring oppsett bakgrunnsbelysning
Bakgrunnsbelysningen er koblet i paralell med en 20 ohms i serie med bakgrunnsbelysningen. Motstanden er for å regulere strømmen. Verdien av denne er satt basert på informasjon i den tekniske beskrivelsen av bakgrunnsbelysningen.
Gauss verdi
ADC verdi | Spenning | Gauss |
222 | 0.179 | -640 Gauss |
300 | 0.2415 | -600 Gauss |
494 | 0.39775 | -500 Gauss |
688 | 0.554 | -400 Gauss |
882 | 0.71025 | -300 Gauss |
1076 | 0.8665 | -200 Gauss |
1269 | 1.02275 | -100 Gauss |
1463 | 1.179 | 0 Gauss |
1657 | 1.33525 | 100 Gauss |
1851 | 1.4915 | 200 Gauss |
2045 | 1.64775 | 300 Gauss |
2239 | 1.804 | 400 Gauss |
2433 | 1.96025 | 500 Gauss |
2627 | 2.1165 | 600 Gauss |
2705 | 2.179 | 640 Gauss |
Dette er omtrent verdier beregnet siden jeg ikke har noe å teste verdiene mot.
Bilder
Kode
Koden for å initalisere analog til digital konvertering. Den er konfigurert til 12bit og kjører en ekstra kalibrering på slutten.
ADC_MultiModeTypeDef multimode = { 0 }; ADC_ChannelConfTypeDef sConfig = { 0 }; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1.Init.LowPowerAutoWait = DISABLE; hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } multimode.Mode = ADC_MODE_INDEPENDENT; if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.SamplingTime = ADC_SAMPLETIME_181CYCLES_5; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } while(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK);
Her konfigureres oppkoblingen til skjermen. Det viktige her at den må være 8bit, polariteten må være høy og fasen til andre kant.
hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_1LINE; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; hspi1.Init.FirstBit = SPI_FIRSTBIT_LSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 7; hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); }
Her konfigureres SPI koblingen for SCLK, MOSI og MISO.
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Her konfigureres pin 11 som resett på skjermen.
GPIO_InitStruct.Pin = GPIO_PIN_11; //Konfigurer Pin 11 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Utgang push-pull. GPIO_InitStruct.Pull = GPIO_PULLDOWN; // Utgang trekt ned. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //Høy hastighet på utgang HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Skjermen initaliseres.
void InitDisplay(void) { HAL_Delay(500); ResetDisplay(); HAL_Delay(20); TransmitSpi(RS_INS, 0x08); //Slå av skjermen, hvis på. TransmitSpi(RS_INS, 0x3A); //Slå på skjermen. TransmitSpi(RS_INS, 0x09); //Utvidet funksjonskall. 5 piksel font, //BW invertering slått av, //4 linje skjerm slått på. TransmitSpi(RS_INS, 0x06); //Topp/Bunn satt til bunn. TransmitSpi(RS_INS, 0x1E); //Setter BIAS TransmitSpi(RS_INS, 0x39); //Funksjon satt. TransmitSpi(RS_INS, 0x1B); //Setter den interne oscillering til bias=1/6. TransmitSpi(RS_INS, 0x6C); //Setter intern motstand for spenningsdeling. TransmitSpi(RS_INS, 0x54); //Booster på og setter de to høyeste //bitene av konstrasten. TransmitSpi(RS_INS, 0x70); //Setter de fire siste bitene av konstrasten. TransmitSpi(RS_INS, 0x38); //Setter funksjon. TransmitSpi(RS_INS, 0x0C); //Skjerm på. }
Sender data over spi til skjermdriveren. RS parameteren foreller om det er data som skal vises på skjermen eller om det er en instruksjon. Hvert kall består av tre byte.
Den første består av 5 byte som er høy som brukes til synkronisering, deretter les/skriv bit, deretter en bit som forteller om det er instruksjon eller data og til slutt en lav bit.
Hver data sendes en byte som sendes i to byte.
Skal sendes: 11001010 | |||
Byte 1 (4 første bit) | Byte 1 (4 siste bit) | 2 byte (4 siste bit) | 2 byte (4 siste bit) |
0101 | 0000 | 0011 | 0000 |
void TransmitSpi(uint8_t rs, uint8_t data) { HAL_Delay(5); uint8_t msb = (data & 0xF0) >> 4; uint8_t lsb = (data & 0x0F); uint8_t cmd[SPI_COMMAND_SIZE] = { 0x1F | rs, lsb, msb }; HAL_SPI_Transmit(&hspi1, cmd, SPI_COMMAND_SIZE, 100); HAL_Delay(5); }
Posisjon som skal skrives til er for 4 linjers skjerm satt til 0x80 på linje 1, 0x80+0x20 for linje 2, 0x80+0x40 for linje 3.
void SetCursor(uint8_t y, uint8_t x) { TransmitSpi(RS_INS, (uint8_t)0x80 + (0x20*y) + x); }
Sletter all informasjon på skjermen.
void ClearScreen() { TransmitSpi(RS_INS, 0x01); }
Skriver ut en karakter til skjermen om gangen. For hvert kall så flyttes markøren i minnet en plass så vi trenger ikke sette markøren for hvert kall.
void PrintString(char* str, int len) { for (int i = 0;i < len;i++) { TransmitSpi(RS_DATA, str[i]); } }
Prosjekt koden kan finnes her.
Du må være logget inn for å legge inn en kommentar.