Hello,
This is my first time here so, sorry for any mistake I make…
I’m trying to do a school project and the ideia is to read from the gyroscope via I2C and blink one led (for debug pruposes)
However, I manage only to get the I2C printed in a display (everything is ok in this part) but the led isn’t blinking.
Need some help to understand why I the led isn’t working
Thank you,
Eddy
/* Standard includes. */
#include <string.h>
#include <stdio.h>
#include <stdint.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
/* Mutex include */
#include "semphr.h"
/* Queue include */
#include "queue.h"
/* I2C Task */
static void prvI2CTask(void *pvParameters);
/* Configure RCC clock at 72 MHz */
static void prvSetupRCC(void);
/* Configure GPIO. */
static void prvSetupGPIO(void);
/* Simple LED toggle task. */
static void prvFlashTask1(void *pvParameters);
/* Task that sends the task list to USART */
static void prvFlashTask6(void *pvParameters);
/********** Useful functions **********/
/* USART2 configuration. */
static void prvSetupUSART2(void);
/* USART2 send message. */
static void prvSendMessageUSART2(char *message);
/***************************************/
/* Task 1 handle variable. */
TaskHandle_t HandleTask1;
TaskHandle_t HandleTask5;
//TaskHandle_t HandleTask6;
#define mainI2C_DELAY ( ( TickType_t ) 1000 / portTock_PERIOD_MS )
void Config_GPIO_USART_I2C();
void Init_I2C();
static int8_t ReadFromAccel(uint8_t Adress, uint8_t Register);
void i2c_write(uint8_t address, uint8_t data, uint8_t Register);
void Config_GPIO_Sensor();
int main(void) {
/*Setup the hardware, RCC, GPIO, etc...*/
prvSetupRCC();
prvSetupGPIO();
prvSetupUSART2();
/* Create the tasks */
xTaskCreate(prvFlashTask1, "Flash1", configMINIMAL_STACK_SIZE, NULL, 1, &HandleTask1);
xTaskCreate(prvI2CTask, "prvI2CTask", configMINIMAL_STACK_SIZE, NULL, 1, &HandleTask5);
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the idle task. */
return 0;
}
/*-----------------------------------------------------------*/
static void prvFlashTask1(void *pvParameters) {
/* Declare the variable xLastExecutionTime */
TickType_t xLastExecutionTime;
/* Initialize xLastExecutionTime */
xLastExecutionTime = xTaskGetTickCount();
for (;;) {
/* Block 1 second. */
/* vTaskDelay((TickType_t )1000/portTICK_PERIOD_MS); comment this line */
vTaskDelayUntil(&xLastExecutionTime, (TickType_t)1000/portTICK_PERIOD_MS);
/* Toggle the LED */
GPIO_WriteBit(GPIOB, GPIO_Pin_6, (1 - GPIO_ReadOutputDataBit( GPIOB, GPIO_Pin_6)));
// prvSendMessageUSART2("Mensagen enviada ao fim de 10 ms a partir de uma tarefa de baixa prioridade.\r\n");
}
// for (i = 0; i < 65535; i++) {
// }
}
/*-----------------------------------------------------------*/
static void prvI2CTask(void *pvParameters) {
lcd_init();
char buffer_USART[100], data_buffer[10], buffer[20];
uint8_t deviceID = ReadFromAccel(0xA6, 0x00);
for (;;) {
if (deviceID == 0b11100101) {
sprintf(buffer_USART, "Device 0xE5 OK\n");
prvSendMessageUSART2(buffer_USART);
lcd_draw_string(5, 0, "Device 0xE5 OK", 0xFFFF, 1);
display();
i2c_write(0xA6, 0x00, 0x2D); // reset a todos os bits do Registo 0x2D - Power_CTL
i2c_write(0xA6, 0x01, 0x31); // escala +- 4g
i2c_write(0xA6, 0x08, 0x2D); // medição e "wake up" 8hz
/*
* Os dados estão armazenados nos registos 0x32 a 0x37 na forma de DATAX0, DATAX1, DATAY0, DATAY1, DATAZ0, DATAZ1.
* Os registos são de 8 bits.
*
* Accel_X_RAW | Accel_Y_RAW | Accel_Z_RAW obtêm-se concatenando os dois registos, o que implica deslocar os 8 MSB bits para a esquerda
*/
data_buffer[0] = (ReadFromAccel(0xA6, 0x32));
data_buffer[1] = ReadFromAccel(0xA6, 0x33);
int Accel_X_RAW = (int16_t) (data_buffer[1] << 8 | data_buffer[0]);
data_buffer[2] = ReadFromAccel(0xA6, 0x34);
data_buffer[3] = ReadFromAccel(0xA6, 0x35);
int Accel_Y_RAW = (int16_t) (data_buffer[3] << 8 | data_buffer[2]);
data_buffer[4] = ReadFromAccel(0xA6, 0x36);
data_buffer[5] = ReadFromAccel(0xA6, 0x37);
int Accel_Z_RAW = (int16_t) (data_buffer[5] << 8 | data_buffer[4]);
/* Uma vez que o formato float não está disponível, calcula-se o quociente e o resto da divisão
* para poder ser apresentada no display presente na placa de expansão
*
* Pela consulta do datasheet e pelas escala configurada - obtêm-se os valores lidos dos registos, dividindo por 128.205 LSB/mg
* ou multiplicando por 78mg/LSB
*/
int AxI = Accel_X_RAW / 128.205;
int RestoAxI = Accel_X_RAW - (128.205 * AxI);
RestoAxI = (RestoAxI / 128.205) * 100;
/* Converter o cálculo do resto num número positivo */
if (RestoAxI < 0) {
RestoAxI = (-1) * RestoAxI;
}
/* Apresentação dos resultados na USART e display */
if (Accel_X_RAW < 0) {
sprintf(buffer, "x=-%d,%d", AxI, RestoAxI);
lcd_draw_string(5, 25, (char*) buffer, 0x07F0, 1);
display();
} else {
sprintf(buffer, "x=%d,%d", AxI, RestoAxI);
lcd_draw_string(5, 25, (char*) buffer, 0x07F0, 1);
display();
}
int AyI = Accel_Y_RAW / 128.205;
int RestoAyI = Accel_Y_RAW - (128.205 * AyI);
RestoAyI = (RestoAyI / 128.205) * 100;
if (RestoAyI < 0) {
RestoAyI = (-1) * RestoAyI;
}
if (Accel_Y_RAW < 0) {
sprintf(buffer, "y=-%d,%d", AyI, RestoAyI);
lcd_draw_string(5, 35, (char*) buffer, 0x07F0, 1);
display();
} else {
sprintf(buffer, "y=%d,%d", AyI, RestoAyI);
lcd_draw_string(5, 35, (char*) buffer, 0x07F0, 1);
display();
}
int AzI = Accel_Z_RAW / 128.205;
int RestoAzI = Accel_Z_RAW - (128.205 * AzI);
RestoAzI = (RestoAzI / 128.205) * 100;
if (RestoAzI < 0) {
RestoAzI = (-1) * RestoAzI;
}
if (Accel_Z_RAW < 0) {
sprintf(buffer, "z=-%d,%d", AzI, RestoAzI);
lcd_draw_string(5, 45, (char*) buffer, 0x07F0, 1);
display();
} else {
sprintf(buffer, "z=%d,%d", AzI, RestoAzI);
lcd_draw_string(5, 45, (char*) buffer, 0x07F0, 1);
display();
}
sprintf(buffer_USART, "(x,y,z)=(%d.%d, %d.%d, %d.%d)\n", AxI, RestoAxI, AyI, RestoAyI, AzI, RestoAzI);
prvSendMessageUSART2(buffer_USART);
} else {
sprintf(buffer_USART, "DeviceID not found\n");
prvSendMessageUSART2(buffer_USART);
lcd_draw_string(0, 0, "DeviceID not found", 0xFFFF, 1);
display();
}
}
}
/*-----------------------------------------------------------*/
//static void prvFlashTask6(void *pvParameters) {
// char info[256];
// TickType_t xLastExecutionTime;
//
// xLastExecutionTime = xTaskGetTickCount();
// for (;;) {
// vTaskDelayUntil(&xLastExecutionTime,(TickType_t)1000/portTICK_PERIOD_MS);
// prvSendMessageUSART2("----------------------------------------------------------------------------------------\n");
// vTaskList(info);
// prvSendMessageUSART2(info);
// }
//}
/*-----------------------------------------------------------*/
static void prvSetupRCC(void) {
/* RCC configuration - 72 MHz */
ErrorStatus HSEStartUpStatus;
RCC_DeInit();
/*Enable the HSE*/
RCC_HSEConfig(RCC_HSE_ON);
/* Wait untill HSE is ready or time out */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS) {
/* Enable The Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 72 MHZ - 2 wait states */
FLASH_SetLatency(FLASH_Latency_2);
/* No division HCLK = SYSCLK = 72 MHz*/
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK1 = HCLK/2 (36MHz) */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PCLK2 = HCLK (72MHz)*/
RCC_PCLK2Config(RCC_HCLK_Div1);
/* Use PLL with HSE = 12 MHz (12 MHz * 6 = 72 MHz) */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6);
/* Enable the PLL */
RCC_PLLCmd(ENABLE);
/* Wait for PLL ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
;
/* Select the PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait until PLL is used as system clock */
while (RCC_GetSYSCLKSource() != 0x08)
;
} else {
/* HSE error? No further action */
while (1)
;
}
}
/*-----------------------------------------------------------*/
static void prvSetupGPIO(void) {
/* GPIO configuration */
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA,
ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*-----------------------------------------------------------*/
void prvSetupUSART2(void) {
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* USART2 is configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- 1 Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled */
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
/* USART Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Tx an AF */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* RX as In Floating*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 115200 8N1*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
/* Configure the USART2 */
USART_Init(USART2, &USART_InitStructure);
/* Enable the USART2 */
USART_Cmd(USART2, ENABLE);
}
/*-----------------------------------------------------------*/
/* This is a !blocking! send USART function */
static void prvSendMessageUSART2(char *message) {
uint16_t cont_aux = 0;
uint16_t nbytes = 0;
nbytes = strlen(message);
while (cont_aux != nbytes) {
USART_SendData(USART2, (uint8_t) message[cont_aux]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {
}
cont_aux++;
}
}
/*-----------------------------------------------------------*/
/* Inicializa o I2C */
void Init_I2C() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
static int8_t ReadFromAccel(uint8_t Adress, uint8_t Register) {
int8_t value;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
;
I2C_GenerateSTART(I2C1, ENABLE); //Start
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
;
I2C_Send7bitAddress(I2C1, Adress, I2C_Direction_Transmitter); //Slave Address + Write
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
; //Acknowledge acknowledge
I2C_SendData(I2C1, Register);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
;
I2C_Send7bitAddress(I2C1, Adress, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
;
value = I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, DISABLE); // NACK
I2C_GenerateSTOP(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
;
return value;
}
/* Escreve no "Slave" - Sensor */
void i2c_write(uint8_t address, uint8_t data, uint8_t Register) {
/* enviar comando */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
;
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS)
;
I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)
!= SUCCESS)
;
I2C_SendData(I2C1, Register);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
;
I2C_SendData(I2C1, data);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
;
I2C_GenerateSTOP(I2C1, ENABLE);
}