Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: STM32F3-Discovery-minimal
Fork of accelerometer_test by
main.c@4:e38891a2d67c, 2019-04-03 (annotated)
- Committer:
- MartinJohnson
- Date:
- Wed Apr 03 22:00:45 2019 +0000
- Revision:
- 4:e38891a2d67c
- Parent:
- 2:742027e49b6f
Tidy up formatting
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| MartinJohnson | 0:ed38888a34c2 | 1 | |
| MartinJohnson | 0:ed38888a34c2 | 2 | #include <stm32f3_discovery.h> |
| MartinJohnson | 1:c92d1851a036 | 3 | #include <stm32f3_discovery_lsm303dlhc.h> |
| MartinJohnson | 2:742027e49b6f | 4 | #include <stdio.h> |
| MartinJohnson | 2:742027e49b6f | 5 | #include <math.h> |
| MartinJohnson | 1:c92d1851a036 | 6 | |
| MartinJohnson | 1:c92d1851a036 | 7 | #define I2C_CR2_CLEAR_MASK ~(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP) |
| MartinJohnson | 0:ed38888a34c2 | 8 | |
| MartinJohnson | 1:c92d1851a036 | 9 | void i2cWrite(int address, int reg, int val) { |
| MartinJohnson | 1:c92d1851a036 | 10 | while(I2C1->ISR & I2C_ISR_BUSY); |
| MartinJohnson | 1:c92d1851a036 | 11 | I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_RELOAD | I2C_CR2_START | (1<<16) | address; |
| MartinJohnson | 1:c92d1851a036 | 12 | while(!(I2C1->ISR & I2C_ISR_TXIS)); |
| MartinJohnson | 4:e38891a2d67c | 13 | I2C1->TXDR = reg; |
| MartinJohnson | 1:c92d1851a036 | 14 | while(!(I2C1->ISR & I2C_ISR_TCR)); |
| MartinJohnson | 1:c92d1851a036 | 15 | I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | (1<<16) | address; |
| MartinJohnson | 1:c92d1851a036 | 16 | while(!(I2C1->ISR & I2C_ISR_TXIS)); |
| MartinJohnson | 4:e38891a2d67c | 17 | I2C1->TXDR = val; |
| MartinJohnson | 1:c92d1851a036 | 18 | while(!(I2C1->ISR & I2C_ISR_STOPF)); |
| MartinJohnson | 1:c92d1851a036 | 19 | I2C1->ICR = I2C_ICR_STOPCF; |
| MartinJohnson | 1:c92d1851a036 | 20 | } |
| MartinJohnson | 0:ed38888a34c2 | 21 | |
| MartinJohnson | 1:c92d1851a036 | 22 | void i2cRead(int address, int reg, uint8_t *data, int nbytes) { |
| MartinJohnson | 1:c92d1851a036 | 23 | while(I2C1->ISR & I2C_ISR_BUSY); |
| MartinJohnson | 1:c92d1851a036 | 24 | I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_START | (1<<16) | address; |
| MartinJohnson | 1:c92d1851a036 | 25 | while(!(I2C1->ISR & I2C_ISR_TXIS)); |
| MartinJohnson | 1:c92d1851a036 | 26 | if(nbytes>1) reg |= 0x80; |
| MartinJohnson | 4:e38891a2d67c | 27 | I2C1->TXDR= reg; |
| MartinJohnson | 1:c92d1851a036 | 28 | while(!(I2C1->ISR & I2C_ISR_TC)); |
| MartinJohnson | 1:c92d1851a036 | 29 | I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_RD_WRN | (nbytes<<16) | address; |
| MartinJohnson | 1:c92d1851a036 | 30 | while(nbytes--) { |
| MartinJohnson | 1:c92d1851a036 | 31 | while(!(I2C1->ISR & I2C_ISR_RXNE)); |
| MartinJohnson | 4:e38891a2d67c | 32 | *data++ = I2C1->RXDR; |
| MartinJohnson | 1:c92d1851a036 | 33 | } |
| MartinJohnson | 1:c92d1851a036 | 34 | while(!(I2C1->ISR & I2C_ISR_STOPF)); |
| MartinJohnson | 1:c92d1851a036 | 35 | I2C1->ICR = I2C_ICR_STOPCF; |
| MartinJohnson | 0:ed38888a34c2 | 36 | } |
| MartinJohnson | 0:ed38888a34c2 | 37 | |
| MartinJohnson | 1:c92d1851a036 | 38 | void i2cInit() { |
| MartinJohnson | 1:c92d1851a036 | 39 | RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; |
| MartinJohnson | 1:c92d1851a036 | 40 | // configure GPIOPB6 and 7 |
| MartinJohnson | 1:c92d1851a036 | 41 | RCC->AHBENR |= RCC_AHBENR_GPIOBEN; |
| MartinJohnson | 2:742027e49b6f | 42 | GPIOB->AFR[0] = (GPIOB->AFR[0] & 0x00ffffff) | 0x44000000; // alt funcs for GPIOB6 and 7 are 4 |
| MartinJohnson | 1:c92d1851a036 | 43 | GPIOB->OSPEEDR |= 0xf000; // speed high |
| MartinJohnson | 1:c92d1851a036 | 44 | GPIOB->OTYPER &= ~0xc0; // output type pp |
| MartinJohnson | 1:c92d1851a036 | 45 | GPIOB->MODER = (GPIOB->MODER & ~0xf000) | 0xa000; // mode af (10) |
| MartinJohnson | 1:c92d1851a036 | 46 | GPIOB->PUPDR = (GPIOB->PUPDR & ~0xf000) | 0xa000; // pull down (10) |
| MartinJohnson | 1:c92d1851a036 | 47 | |
| MartinJohnson | 1:c92d1851a036 | 48 | I2C1->TIMINGR = 0x00902025; |
| MartinJohnson | 1:c92d1851a036 | 49 | I2C1->CR1 |= I2C_CR1_PE; |
| MartinJohnson | 1:c92d1851a036 | 50 | |
| MartinJohnson | 1:c92d1851a036 | 51 | } |
| MartinJohnson | 1:c92d1851a036 | 52 | |
| MartinJohnson | 1:c92d1851a036 | 53 | void MemsConfig(void) |
| MartinJohnson | 0:ed38888a34c2 | 54 | { |
| MartinJohnson | 1:c92d1851a036 | 55 | i2cInit(); |
| MartinJohnson | 4:e38891a2d67c | 56 | i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG1_A, LSM303DLHC_NORMAL_MODE | LSM303DLHC_ODR_50_HZ | LSM303DLHC_AXES_ENABLE); |
| MartinJohnson | 4:e38891a2d67c | 57 | i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, LSM303DLHC_FULLSCALE_2G | LSM303DLHC_BlockUpdate_Continous | LSM303DLHC_BLE_LSB | LSM303DLHC_HR_ENABLE); |
| MartinJohnson | 4:e38891a2d67c | 58 | i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG2_A, LSM303DLHC_HPM_NORMAL_MODE | LSM303DLHC_HPFCF_16 | LSM303DLHC_HPF_AOI1_DISABLE | LSM303DLHC_HPF_AOI2_DISABLE); |
| MartinJohnson | 1:c92d1851a036 | 59 | |
| MartinJohnson | 1:c92d1851a036 | 60 | i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRA_REG_M, LSM303DLHC_TEMPSENSOR_ENABLE | LSM303DLHC_ODR_30_HZ); |
| MartinJohnson | 1:c92d1851a036 | 61 | i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, LSM303DLHC_FS_8_1_GA); |
| MartinJohnson | 4:e38891a2d67c | 62 | i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_MR_REG_M, LSM303DLHC_CONTINUOS_CONVERSION); |
| MartinJohnson | 1:c92d1851a036 | 63 | } |
| MartinJohnson | 1:c92d1851a036 | 64 | |
| MartinJohnson | 1:c92d1851a036 | 65 | void ReadAccelerometer(int16_t * data) { |
| MartinJohnson | 1:c92d1851a036 | 66 | i2cRead(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, (uint8_t *)data, 6); |
| MartinJohnson | 1:c92d1851a036 | 67 | } |
| MartinJohnson | 1:c92d1851a036 | 68 | |
| MartinJohnson | 1:c92d1851a036 | 69 | void ReadMagnetometer(int16_t * data) { |
| MartinJohnson | 2:742027e49b6f | 70 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, (uint8_t *)data, 1); |
| MartinJohnson | 2:742027e49b6f | 71 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, (uint8_t *)data+1, 1); |
| MartinJohnson | 2:742027e49b6f | 72 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, (uint8_t *)data+2, 1); |
| MartinJohnson | 2:742027e49b6f | 73 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, (uint8_t *)data+3, 1); |
| MartinJohnson | 2:742027e49b6f | 74 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, (uint8_t *)data+4, 1); |
| MartinJohnson | 2:742027e49b6f | 75 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, (uint8_t *)data+5, 1); |
| MartinJohnson | 1:c92d1851a036 | 76 | } |
| MartinJohnson | 1:c92d1851a036 | 77 | |
| MartinJohnson | 1:c92d1851a036 | 78 | int ReadTemperature() { |
| MartinJohnson | 1:c92d1851a036 | 79 | int t=0; |
| MartinJohnson | 4:e38891a2d67c | 80 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_L_M, (uint8_t *)&t, 1); |
| MartinJohnson | 4:e38891a2d67c | 81 | i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_H_M, (uint8_t *)&t+1, 1); |
| MartinJohnson | 1:c92d1851a036 | 82 | return t/64; |
| MartinJohnson | 0:ed38888a34c2 | 83 | } |
| MartinJohnson | 0:ed38888a34c2 | 84 | |
| MartinJohnson | 0:ed38888a34c2 | 85 | volatile unsigned sysTiming; |
| MartinJohnson | 0:ed38888a34c2 | 86 | volatile unsigned sysTicks = 0; |
| MartinJohnson | 0:ed38888a34c2 | 87 | |
| MartinJohnson | 4:e38891a2d67c | 88 | __attribute__ ((section ("ccmram"))) void SysTick_Handler(void) { |
| MartinJohnson | 0:ed38888a34c2 | 89 | sysTicks++; |
| MartinJohnson | 0:ed38888a34c2 | 90 | if (sysTiming > 0) --sysTiming; |
| MartinJohnson | 0:ed38888a34c2 | 91 | } |
| MartinJohnson | 0:ed38888a34c2 | 92 | |
| MartinJohnson | 0:ed38888a34c2 | 93 | void sysDelayMs(unsigned dly) { |
| MartinJohnson | 0:ed38888a34c2 | 94 | sysTiming = dly; |
| MartinJohnson | 0:ed38888a34c2 | 95 | while (sysTiming > 0) __wfi(); |
| MartinJohnson | 0:ed38888a34c2 | 96 | |
| MartinJohnson | 0:ed38888a34c2 | 97 | } |
| MartinJohnson | 0:ed38888a34c2 | 98 | |
| MartinJohnson | 0:ed38888a34c2 | 99 | int main(void) { |
| MartinJohnson | 0:ed38888a34c2 | 100 | SysTick_Config((SystemCoreClock / 1000)); |
| MartinJohnson | 1:c92d1851a036 | 101 | RCC->AHBENR |= RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOAEN; |
| MartinJohnson | 0:ed38888a34c2 | 102 | GPIOE->MODER = (GPIOE->MODER&0xffff) | 0x55550000; // output mode for PE8-15 |
| MartinJohnson | 0:ed38888a34c2 | 103 | GPIOA->MODER = (GPIOA->MODER&0xfffffffc) ; // input mode for PA0 |
| MartinJohnson | 0:ed38888a34c2 | 104 | |
| MartinJohnson | 1:c92d1851a036 | 105 | MemsConfig(); |
| MartinJohnson | 1:c92d1851a036 | 106 | int16_t acc[3],mag[3],temp; |
| MartinJohnson | 4:e38891a2d67c | 107 | int b = 0; |
| MartinJohnson | 4:e38891a2d67c | 108 | int TH = 200*16; |
| MartinJohnson | 0:ed38888a34c2 | 109 | while(1) { |
| MartinJohnson | 0:ed38888a34c2 | 110 | ReadAccelerometer(acc); |
| MartinJohnson | 1:c92d1851a036 | 111 | ReadMagnetometer(mag); |
| MartinJohnson | 2:742027e49b6f | 112 | float heading = atan2(mag[1], mag[0]); |
| MartinJohnson | 4:e38891a2d67c | 113 | heading = heading * 180 / 3.14159265359f; |
| MartinJohnson | 4:e38891a2d67c | 114 | if (heading < 0) heading += 360; |
| MartinJohnson | 1:c92d1851a036 | 115 | temp=ReadTemperature(); |
| MartinJohnson | 4:e38891a2d67c | 116 | printf("Acc: %d %d %d\n", acc[0]/16, acc[1]/16, acc[2]/16); |
| MartinJohnson | 4:e38891a2d67c | 117 | printf("Mag: %d %d %d %d %f\n", mag[0], mag[1], mag[2], temp, heading); |
| MartinJohnson | 4:e38891a2d67c | 118 | GPIOE->BSRR = b<<(8+16); |
| MartinJohnson | 4:e38891a2d67c | 119 | b = 0; |
| MartinJohnson | 4:e38891a2d67c | 120 | if(acc[1] < -TH) { |
| MartinJohnson | 4:e38891a2d67c | 121 | if(acc[0] < -TH) b = 1<<4; |
| MartinJohnson | 4:e38891a2d67c | 122 | else if(acc[0] > TH) b = 1<<2; |
| MartinJohnson | 4:e38891a2d67c | 123 | else b = 1<<3; |
| MartinJohnson | 0:ed38888a34c2 | 124 | } else { |
| MartinJohnson | 4:e38891a2d67c | 125 | if(acc[1] > TH) { |
| MartinJohnson | 4:e38891a2d67c | 126 | if(acc[0] < -TH) b = 1<<6; |
| MartinJohnson | 4:e38891a2d67c | 127 | else if(acc[0] > TH) b = 1<<0; |
| MartinJohnson | 4:e38891a2d67c | 128 | else b = 1<<7; |
| MartinJohnson | 0:ed38888a34c2 | 129 | } else { |
| MartinJohnson | 4:e38891a2d67c | 130 | if(acc[0] < -TH) b = 1<<5; |
| MartinJohnson | 4:e38891a2d67c | 131 | else if(acc[0] > TH) b = 1<<1; |
| MartinJohnson | 0:ed38888a34c2 | 132 | } |
| MartinJohnson | 0:ed38888a34c2 | 133 | } |
| MartinJohnson | 4:e38891a2d67c | 134 | GPIOE->BSRR = b<<8; |
| MartinJohnson | 0:ed38888a34c2 | 135 | while(GPIOA->IDR&1); |
| MartinJohnson | 0:ed38888a34c2 | 136 | sysDelayMs(100); |
| MartinJohnson | 0:ed38888a34c2 | 137 | } |
| MartinJohnson | 0:ed38888a34c2 | 138 | } |
| MartinJohnson | 0:ed38888a34c2 | 139 |
