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?

asked Mar 19, 2015 at 16:50
\$\endgroup\$
1
  • \$\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\$ Commented Mar 20, 2015 at 12:08

1 Answer 1

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);

answered Mar 20, 2015 at 22:32
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.