2
\$\begingroup\$

I need to read values from on-board LSM303DLHC (connected via I2C) sensor and send them through UART. UART part is working but PuTTy shows: "Sā–’ā–’" every restart... Can anyone tell me what's wrong? I know that I2C part is not perfect but it should return something, right?

PS. I don't want to use their library - I will learn more this way :)

#include "stm32f30x.h"

void SysTick_Handler(void);
void TimingDelay_Decrement(void);
void Delay(__IO uint32_t nTime);

static __IO uint32_t TimingDelay;
int b=0;

void UART_init (void);
void UART_SendChar (char data);
void USART_SendString (uint8_t * str);
int UART_read (void);

void i2c_conf();
void i2c_write_byte(uint8_t addr, uint8_t data);
uint8_t i2c_read_byte(uint8_t addr);

char read;
char data_from_i2c;

uint8_t CRA_REG_M = 0x00;
uint8_t MR_REG_M = 0x02;
uint8_t CRB_REG_M = 0x01;
uint8_t scldel;
uint8_t sdadel;

int main(void)
{
    SysTick_Config(SystemCoreClock / 1000);                         // Delay(1) = 1 ms with */1000

    UART_init();
    i2c_conf();

    /* ustaw zakres pomiarowy */
    i2c_write_byte(CRB_REG_M, 0x80);
    /* wlacz termometr i ustaw czestotliwosc odswiezania */
    i2c_write_byte(CRA_REG_M, 0x90);
    i2c_write_byte(MR_REG_M, 0x00);

    UART_SendChar('S'); 

    data_from_i2c = i2c_read_byte(0x03);
    UART_SendChar(data_from_i2c); 
    data_from_i2c = i2c_read_byte(0x04);
    UART_SendChar(data_from_i2c);

    while(1)
    {
//      uint8_t String[]="Hello world!";
//      USART_SendString (String);
//      Delay(1000);

        read=UART_read();
        UART_SendChar(read);
        read=0;

    }
}

void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}

void Delay(__IO uint32_t nTime)
{
  TimingDelay = nTime;

  while(TimingDelay != 0);
}

void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  { 
    TimingDelay--;
  }
}

void UART_init (void) {
    RCC -> AHBENR  |=  (1UL << 19);                                     // Enable GPIOC clock
    GPIOC -> MODER |= (2 << 2*10) | (2 << 2*11);                // PC10 PC11 as AF mode
    GPIOC -> AFR[1] |= (7 << 8);                                                // PC10 as AF7 - USART3_TX
    GPIOC -> AFR[1] |= (7 << 12);                                               // PC11 as AF7 - USART3_RX

    RCC->APB1ENR  |=  (1UL << 18);                                      // Enable USART3 clock
    USART3 -> BRR = 3750; //Baudrate based on 24MHz clock 
    USART3 -> CR1 |= (USART_CR1_RE | USART_CR1_TE); 
    USART3 -> CR1 |= USART_CR1_UE;
}

void UART_SendChar (char data) {
    while( ( USART3 -> ISR & USART_ISR_TXE) == 0 ); 
    USART3 -> TDR = data;
}

void USART_SendString (uint8_t * str) {
    while(*str != 0) {
        UART_SendChar(*str); 
        str++;
    }
    UART_SendChar(10); 
    UART_SendChar(13); 
}

int UART_read (void)
{
    while ( (USART3->ISR & USART_ISR_RXNE) == 0); 
    return USART3-> RDR & USART_RDR_RDR;
}

void i2c_conf() {
    /* ustaw altenatywne funkcje GPIO */
    RCC -> AHBENR |= RCC_AHBENR_GPIOBEN;
    GPIOB -> OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR6 | ~GPIO_OSPEEDER_OSPEEDR7;
    GPIOB -> MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1;
    GPIOB -> OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7;
    GPIOB -> AFR[0] |= (4 << 24) | (4 << 28);

    /* zegar z APB1 - 72 MHz */
    //RCC->CFGR3 |= RCC_CFGR3_I2C1SW;
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN ;

    /* skonfiguruj I2C1 */
    I2C1->CR1 |= I2C_CR1_ANFOFF;
    scldel = 4;
    sdadel = 5;
    I2C1->TIMINGR = 0xF0001317 | ((scldel & 0x0F) << 20) | ((sdadel & 0x0F) << 16);
    I2C1->CR2 |= (0x1E << 1);
    I2C1->CR1 |= I2C_CR1_PE;
}

void i2c_write_byte(uint8_t addr, uint8_t data) {
    I2C1->CR2 &= ~(I2C_CR2_RD_WRN);
    I2C1->CR2 |= I2C_CR2_START |  (2 << 16);
    while(I2C1->CR2 & I2C_CR2_START);
    I2C1->TXDR = addr;
    while (!(I2C1->ISR & I2C_ISR_TXE));

    I2C1->TXDR = data;
    while (!(I2C1->ISR & I2C_ISR_TXE));
    I2C1->CR2 |= I2C_CR2_STOP;
    while(I2C1->CR2 & I2C_CR2_STOP);
}

uint8_t i2c_read_byte(uint8_t addr) {
    uint8_t data = 0;

    I2C1->CR2 &= ~(I2C_CR2_RD_WRN);
    I2C1->CR2 &= ~(0xff << 16);
    I2C1->CR2 |= I2C_CR2_START | (1 << 16);
    while(I2C1->CR2 & I2C_CR2_START);

    I2C1->TXDR = addr;
    while (!(I2C1->ISR & I2C_ISR_TXE));

    I2C1->CR2 |= I2C_CR2_RD_WRN;
    I2C1->CR2 |= I2C_CR2_START | (1 << 16);
    while(I2C1->CR2 & I2C_CR2_START);
    while (!(I2C1->ISR & I2C_ISR_RXNE));
    data = I2C1->RXDR;
    I2C1->CR2 |= I2C_CR2_STOP;
    while(I2C1->CR2 & I2C_CR2_STOP);
    return data;
}

So the problem with UART is because I'm sending hex values which are shown as ASCII characters. So I'm receiving values which should be for example my X-axis acceleration data in two bits (High and Low) in two's complement. But how to convert that to decimal value and send it through UART?

\$\endgroup\$
  • \$\begingroup\$ So the problem with UART is because I'm sending hex values which are shown as ASCII characters. So I'm receiving values which should be for example my X-axis acceleration data in two bits (High and Low) in two's complement. But how to convert that to decimal value and send it through UART? \$\endgroup\$ – Ekci Mar 20 '15 at 12:08
1
\$\begingroup\$

Problem solved. Here's corrected part of the code:

    i2c_write_byte(0x20, 0x37);  //CTRL_REG1_A = 00110111b

    test = i2c_read_byte(0x28);
    test2 = i2c_read_byte(0x29);
    X = (int16_t)(test | test2 << 8);

    test = i2c_read_byte(0x2A);
    test2 = i2c_read_byte(0x2B);
    Y = (int16_t)(test | test2 << 8);

    test = i2c_read_byte(0x2C);
    test2 = i2c_read_byte(0x2D);
    Z = (int16_t)(test | test2 << 8);

    AccYangle = (float) atan2(Y, Z) * 180/M_PI;
    AccXangle = (float) atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

    sprintf(buffer, "X = %f", AccXangle);
    USART_SendString(buffer);
    sprintf(buffer, "Y = %f", AccYangle);
    USART_SendString(buffer);

And correct address of Accelerometer: I2C1->CR2 |= (0x19 << 1);

\$\endgroup\$

Your Answer

By clicking ā€œPost Your Answerā€, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.