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
main.c
- Committer:
- MartinJohnson
- Date:
- 2018-05-02
- Revision:
- 1:c92d1851a036
- Parent:
- 0:ed38888a34c2
- Child:
- 2:742027e49b6f
File content as of revision 1:c92d1851a036:
#include <stm32f3_discovery.h>
#include <stm32f3_discovery_lsm303dlhc.h>
#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)
void i2cWrite(int address, int reg, int val) {
while(I2C1->ISR & I2C_ISR_BUSY);
I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_RELOAD | I2C_CR2_START | (1<<16) | address;
while(!(I2C1->ISR & I2C_ISR_TXIS));
I2C1->TXDR=reg;
while(!(I2C1->ISR & I2C_ISR_TCR));
I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | (1<<16) | address;
while(!(I2C1->ISR & I2C_ISR_TXIS));
I2C1->TXDR=val;
while(!(I2C1->ISR & I2C_ISR_STOPF));
I2C1->ICR = I2C_ICR_STOPCF;
}
void i2cRead(int address, int reg, uint8_t *data, int nbytes) {
while(I2C1->ISR & I2C_ISR_BUSY);
I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_START | (1<<16) | address;
while(!(I2C1->ISR & I2C_ISR_TXIS));
if(nbytes>1) reg |= 0x80;
I2C1->TXDR=reg;
while(!(I2C1->ISR & I2C_ISR_TC));
I2C1->CR2 = (I2C1->CR2 & I2C_CR2_CLEAR_MASK) | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_RD_WRN | (nbytes<<16) | address;
while(nbytes--) {
while(!(I2C1->ISR & I2C_ISR_RXNE));
*data++=I2C1->RXDR;
}
while(!(I2C1->ISR & I2C_ISR_STOPF));
I2C1->ICR = I2C_ICR_STOPCF;
}
void i2cInit() {
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
// configure GPIOPB6 and 7
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->AFR[0] = (GPIOC->AFR[0] & 0x00ffffff) | 0x44000000; // alt funcs for GPIOB6 and 7 are 4
GPIOB->OSPEEDR |= 0xf000; // speed high
GPIOB->OTYPER &= ~0xc0; // output type pp
GPIOB->MODER = (GPIOB->MODER & ~0xf000) | 0xa000; // mode af (10)
GPIOB->PUPDR = (GPIOB->PUPDR & ~0xf000) | 0xa000; // pull down (10)
I2C1->TIMINGR = 0x00902025;
I2C1->CR1 |= I2C_CR1_PE;
}
void MemsConfig(void)
{
i2cInit();
i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG1_A,LSM303DLHC_NORMAL_MODE | LSM303DLHC_ODR_50_HZ | LSM303DLHC_AXES_ENABLE);
i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A,LSM303DLHC_FULLSCALE_2G | LSM303DLHC_BlockUpdate_Continous | LSM303DLHC_BLE_LSB | LSM303DLHC_HR_ENABLE);
i2cWrite(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG2_A,LSM303DLHC_HPM_NORMAL_MODE | LSM303DLHC_HPFCF_16 | LSM303DLHC_HPF_AOI1_DISABLE | LSM303DLHC_HPF_AOI2_DISABLE);
i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRA_REG_M, LSM303DLHC_TEMPSENSOR_ENABLE | LSM303DLHC_ODR_30_HZ);
i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, LSM303DLHC_FS_8_1_GA);
i2cWrite(MAG_I2C_ADDRESS, LSM303DLHC_MR_REG_M,LSM303DLHC_CONTINUOS_CONVERSION);
}
void ReadAccelerometer(int16_t * data) {
i2cRead(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, (uint8_t *)data, 6);
}
void ReadMagnetometer(int16_t * data) {
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, (uint8_t *)data, 6);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, (uint8_t *)data+1, 6);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, (uint8_t *)data+2, 6);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, (uint8_t *)data+3, 6);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, (uint8_t *)data+4, 6);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, (uint8_t *)data+5, 6);
}
int ReadTemperature() {
int t=0;
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_L_M, (uint8_t *)&t,1);
i2cRead(MAG_I2C_ADDRESS, LSM303DLHC_TEMP_OUT_H_M, (uint8_t *)&t+1,1);
return t/64;
}
volatile unsigned sysTiming;
volatile unsigned sysTicks = 0;
void SysTick_Handler(void) {
sysTicks++;
if (sysTiming > 0) --sysTiming;
}
void sysDelayMs(unsigned dly) {
sysTiming = dly;
while (sysTiming > 0) __wfi();
}
int main(void) {
SysTick_Config((SystemCoreClock / 1000));
RCC->AHBENR |= RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIOAEN;
GPIOE->MODER = (GPIOE->MODER&0xffff) | 0x55550000; // output mode for PE8-15
GPIOA->MODER = (GPIOA->MODER&0xfffffffc) ; // input mode for PA0
MemsConfig();
int16_t acc[3],mag[3],temp;
int b=0;
int TH=200*16;
while(1) {
ReadAccelerometer(acc);
ReadMagnetometer(mag);
temp=ReadTemperature();
printf("Acc: %d %d %d\n",acc[0]/16,acc[1]/16,acc[2]/16);
printf("Mag: %d %d %d %d\n",mag[0],mag[1],mag[2],temp);
GPIOE->BSRR=b<<(8+16);
b=0;
if(acc[1]<-TH) {
if(acc[0]<-TH) b=1<<4;
else if(acc[0]>TH) b=1<<2;
else b=1<<3;
} else {
if(acc[1]>TH) {
if(acc[0]<-TH) b=1<<6;
else if(acc[0]>TH) b=1<<0;
else b=1<<7;
} else {
if(acc[0]<-TH) b=1<<5;
else if(acc[0]>TH) b=1<<1;
}
}
GPIOE->BSRR=b<<8;
while(GPIOA->IDR&1);
sysDelayMs(100);
}
}