I try to finish the code about: ADC using DMA and then the data transfer through PC by using USART. I want to use USART_DMA to avoid occupying CPU. I use sample frequency rate 1000Hz by using array ADC[] and delay 1ms (delay here mean I use systemtick, you haven't check this point I am sure it work well).
In this code below, have I missed something?
So here my code:
USART_DMA code:
/* USARTx configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
#include "USART.h"
char TxBuffer[16];
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
void USART_Configuration(unsigned int BaudRate)
{
/* Characteristic of USART*/
USART_InitStructure.USART_BaudRate = BaudRate;
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_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* Enable USART*/
USART_Cmd(USART1, ENABLE);
}
void DMA_Configuration(void)
{
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer; // send buffer
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // Transmit
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel2, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET)
{}
}
ADC_DMA code:
#include "ADC_DMA.h"
uint32_t ADCValue[2] = {0};
void ADC_DMA(void){
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* DMA Configure */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCValue; // address of array data
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2; // kich thuoc mang du lieu tuong ung so phan tu cua ADCValue
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* DMA1_Stream0 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC Common Init */
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2; //so kenh ADC chuyen doi
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_7Cycles5);
/* Enable ADC DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
Main function:
#include "stm32f10x.h"
#include "stdio.h"
#include "ADC_DMA.h"
#include "USART.h"
/* Declare variable*/
__IO uint16_t x,y;
extern uint32_t time=0;
extern uint32_t ADCValue[];
extern char TxBuffer[16];
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void GPIO_Configuration(void);
void Delay(__IO uint32_t nCount);
int main()
{
GPIO_Configuration();
ADC_DMA();
RCC_DeInit();
USART_Configuration(115200);
SysTick_Config(SystemCoreClock / 1000);
/****************************************
*SystemFrequency/1000 1ms *
*SystemFrequency/100000 10us *
*SystemFrequency/1000000 1us *
*****************************************/
while(1)
{
Delay(1000); // 100000 = 100ms
x = ADCValue[0];
y = ADCValue[1];
}
sprintf(TxBuffer,"%d#\n%d$\n", x,y);
}
}
void GPIO_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PB0 PB1 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure PA0 in input mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable clock DMA1 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable clock ADC1 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
/* Configure ADC Pin PA0 & PA1 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable clock for USART1*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable clock DMA1 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Delay(__IO uint32_t nCount)
{
time = nCount;
while(nCount--);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
Related
#if EN_USART2
u16 _distance1=0;
u16 distance1=0;
void USART2_Init(u32 bound) {
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
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_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void){
u8 a;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
a =USART_ReceiveData(USART2);
if(a!=0xa5) _distance1=(_distance1<<8)|a;
else
{
distance1=_distance1;
_distance1=0;
}
}
}
#endif
#if EN_USART3
u16 _distance2=0;
u16 distance2=0;
void USART3_Init(u32 bound) {
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
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_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_Cmd(USART3, ENABLE);
}
void USART3_IRQHandler(void){
u8 a;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){
a =USART_ReceiveData(USART3);
if(a!=0xa5) _distance2=(_distance2<<8)|a;
else
{
distance2=_distance2;
_distance2=0;
}
}
}
#endif
This is part of the code of usart.c. EN_USART2 and EN_USART3 are all 1. main.c is as follows:
#include "stm32f10x.h"
#include "delay.h"
#include "system.h"
#include "usart.h"
// Device header
int main(void)
{
SystemInit();
USART1_Init(115200);
USART2_Init(115200);
USART3_Init(115200);
while(1)
{
printf("difference: %dmm\r\n",distance1-distance2);
delay_ms(100);
}
}
It runs on STM32F103C8T6. PA2 and PA3 connects to an ultrasound module, and PB10 and PB11 connects to another ultrasound module. I found that the interruption service function of USART2 can be implemented, but that of USART3 cannot. Why is that? USART3 and USART2 are all written similarly. (As for how do I know that USART2 doesn't work: I added printf("p") behind a =USART_ReceiveData(USART3);, but I didn't see any "p" on the serial debug window(however, messages printed in main() all displayed well, which means that USART1 is normal).
I searched for the template code, but I can't find anything wrong in my own code.
guys.
I generated PWM signal with timer TIM1.
I want get this PWM from TIM1 with timer TIM2 and repeat it on the some GPIO pin.
I used Standart Peripheral Library.
PWM has generated on pin PA8 with timer TIM1 successfully, but i can't receive this PWM signal from PA0 pin with TIM2.
(PA8 и PA0 i connected with cable.)
Help me, please.
type here
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "misc.h"
#include <stdio.h>
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM1_TimeBaseStruct;
TIM_OCInitTypeDef TIM1_OCInitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
volatile uint16_t capture1 = 0, capture2 = 0;
volatile uint8_t capture_is_first = 1, capture_is_ready = 0;
const uint32_t myPeriod = 61538 - 1;
const uint32_t myPrescaler = 1 - 1;
const uint32_t myPulse = 5000;
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Generate PWM on PA8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// Input capture PWM on PA0
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
TIM1_TimeBaseStruct.TIM_Period = myPeriod;
TIM1_TimeBaseStruct.TIM_Prescaler = myPrescaler;
TIM1_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStruct);
TIM1_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM1_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStruct.TIM_Pulse = myPulse;
TIM1_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM1_OCInitStruct.TIM_OCNPolarity = TIM_OutputState_Disable;
TIM1_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM1_OCInitStruct);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_TimeBaseInitTypeDef timer_base;
TIM_TimeBaseStructInit(&timer_base);
timer_base.TIM_Prescaler = 24000 - 1;
TIM_ICInitTypeDef timer_ic;
timer_ic.TIM_Channel = TIM_Channel_1;
timer_ic.TIM_ICPolarity = TIM_ICPolarity_Rising;
timer_ic.TIM_ICSelection = TIM_ICSelection_DirectTI;
timer_ic.TIM_ICPrescaler = TIM_ICPSC_DIV1;
timer_ic.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &timer_ic);
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
NVIC_EnableIRQ(TIM2_IRQn);
/* Включаем таймер */
TIM_Cmd(TIM2, ENABLE);
while (1)
{
}
} // main
void TIM2_IRQHandler(void)
{
int i = 0;
i++;
printf("I'm TIM2 IRQ Handler.");
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
capture1 = capture2;
capture2 = TIM_GetCapture1(TIM2);
if (!capture_is_first)
capture_is_ready = 1;
capture_is_first = 0;
if (TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1OF) != RESET)
{
TIM_ClearFlag(TIM2, TIM_FLAG_CC1OF);
// ...
}
}
}
I wrote the receive (input capture) PWM signal code using examples from the Internet, but i can't debug this. Help please. I'm new to embedded dev.
I am trying to transmit and receive data via UART/USART on stm32L476 discovery board to terminal on PC. I am able to transmit the data to PC, but I am not able to receive any.
My code is as follows:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
uint8_t cmd[] = {4,7,8,9};
uint8_t data[10];
uint8_t data1[10];
uint32_t err_code = 0;
int count = 0;
/* USER CODE BEGIN 0 */
int stat_re;
int mydata = 1;
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
// HAL_UART_Transmit(&huart2,(uint8_t*) cmd, 4, 5);
// HAL_Delay(1000);
/*
while (!(USART_ISR_RXNE));
mydata = (int)(USART_RDR_RDR & 0xFF);*/
HAL_UART_Receive(&huart2, data, 10, 5000 )
data1[10] = data[10];
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USART2 init function */
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
PA8 ------> RCC_MCO
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Configure GPIO pin : PB2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PE8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief This function is executed in case of error occurrence.
* #param None
* #retval None
*/
void _Error_Handler(char * file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* #}
*/
/**
* #}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Please let me know if you know the problem.
I have tried removing the resistor connected to the Joystick which is also connected to the receive pin of USART2.
You seem to be missing GPIO configuration.
For this particular MCU, USART2 RX alternate function can be assigned to either PA3 or PD6. TX is either PA2 or PD5. Pick the variant you need and initialize the pins - in both cases it's AF7. Also make sure the clocks for USART and GPIO are enabled.
As it is, your code blocks until 10 bytes are received or 5 seconds timeout has elapsed. Then you are trying to read 1 byte in the array, but your read is out of bounds.
To check that the UART works correctly you could try a very simple echo like this:
while(1)
{
uint8_t echo;
//Blocks indefinitely until 1 byte is received
HAL_UART_Receive(&huart2, &echo, 1, HAL_MAX_DELAY);
//Sends back the byte
HAL_UART_Transmit(&huart2, &echo, 1, HAL_MAX_DELAY);
}
How can I use the I2C for read data from the LSM303DLHC(Magnetometer) and store data in memory, in a buffer, via DMA ?
I try to modify the "LSM303DLHC_Read()" function to use it with the DMA but the output on the SerialChart is always 0.
Can you show me an example of I2C with DMA ?
uint16_t LSM303DLHC_DMA_Read(uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead)
{
__IO uint32_t LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
__IO uint32_t temp;
I2C_Initialization();
DMA_Config();
restart:
LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
/* Send START condition */
I2C_GenerateSTART(LSM303DLHC_I2C, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(LSM303DLHC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if (LSM303DLHC_Timeout-- == 0)
return ERROR;
}
/* Active the needed channel Request */
I2C_DMACmd(I2C1, ENABLE);
LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
/* Send slave address for read */
I2C_Send7bitAddress(LSM303DLHC_I2C, DeviceAddr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(LSM303DLHC_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if (LSM303DLHC_Timeout-- == 0)
{
I2C_ClearFlag(LSM303DLHC_I2C,I2C_FLAG_BUSY|I2C_FLAG_AF);
goto restart;
}
}
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(LSM303DLHC_I2C, ENABLE);
I2C_SendData(LSM303DLHC_I2C, RegisterAddr);
/* Test on EV8 and clear it */
LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
while (!I2C_CheckEvent(LSM303DLHC_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if (LSM303DLHC_Timeout-- == 0)
return ERROR;
}
if (NumByteToRead == 0x01)
{
restart3:
/* Send START condition */
I2C_GenerateSTART(LSM303DLHC_I2C, ENABLE);
while (!I2C_CheckEvent(LSM303DLHC_I2C, I2C_EVENT_MASTER_MODE_SELECT));
/* Send Slave address for read */
I2C_Send7bitAddress(LSM303DLHC_I2C, DeviceAddr, I2C_Direction_Receiver);
/* Wait until ADDR is set */
LSM303DLHC_Timeout = LSM303DLHC_LONG_TIMEOUT;
while (!I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_FLAG_ADDR))
{
if (LSM303DLHC_Timeout-- == 0)
{
I2C_ClearFlag(LSM303DLHC_I2C,I2C_FLAG_BUSY|I2C_FLAG_AF);
goto restart3;
}
}
/* Clear ACK */
I2C_AcknowledgeConfig(LSM303DLHC_I2C, DISABLE);
I2C_NACKPositionConfig(LSM303DLHC_I2C, I2C_NACKPosition_Current);
__disable_irq();
/* Clear ADDR flag */
temp = LSM303DLHC_I2C->SR2;
/* Program the STOP */
I2C_GenerateSTOP(LSM303DLHC_I2C, ENABLE);
__enable_irq();
while ((I2C_GetLastEvent(LSM303DLHC_I2C) & 0x0040) != 0x000040); /* Poll on RxNE */
I2C_DMACmd(I2C1, DISABLE);
/* Read the data */
//*pBuffer = I2C_ReceiveData(LSM303DLHC_I2C);
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((LSM303DLHC_I2C->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(LSM303DLHC_I2C, ENABLE);
return SUCCESS;
}
}
This is the DMA configuration :
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* Reset DMA Stream registers (for debug purpose) */
DMA_DeInit(DMA1_Stream0);
/* Check if the DMA Stream is disabled before enabling it.
Note that this step is useful when the same Stream is used multiple times:
enabled, then disabled then re-enabled... In this case, the DMA Stream disable
will be effective only at the end of the ongoing data transfer and it will
not be possible to re-configure it before making sure that the Enable bit
has been cleared by hardware. If the Stream is used only once, this step might
be bypassed. */
while (DMA_GetCmdStatus(DMA1_Stream0) != DISABLE) {}
/* Configure DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C_Register_DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buffer_X;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1 ;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream0, &DMA_InitStructure);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);
/* DMA Stream enable */
DMA_Cmd(DMA1_Stream0, ENABLE);
/* Check if the DMA Stream has been effectively enabled.
The DMA Stream Enable bit is cleared immediately by hardware if there is an
error in the configuration parameters and the transfer is no started (ie. when
wrong FIFO threshold is configured ...) */
// while ((DMA_GetCmdStatus(DMA2_Stream0) != ENABLE))
// { }
}
And this is the I2C configuration :
void I2C_Initialization(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable the I2C periph */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Enable SCK and SDA GPIO clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* I2C SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C SDA pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C configuration -------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
/* Apply LSM303DLHC_I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
/* Active the needed channel Request */
//I2C_DMACmd(I2C1, ENABLE);
/* LSM303DLHC_I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);
}
my first question is why you have DMA config and I2C initialization functions in read function?
I believe you're missing the configuration line for DMA1_Stream6. You'll need to alter the DMA_InitStructure and initialize the Tx stream - right now you're only initializing the Rx Stream. Something like the following should work:
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Stream0); //reset DMA1 channe1 to default values;
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)I2C_RxBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA1_Stream0, ENABLE);
while (DMA_GetCmdStatus(DMA1_Stream6) != ENABLE);
DMA_ClearFlag(DMA1_Stream0, DMA_FLAG_TCIF0 | DMA_FLAG_FEIF0 | DMA_FLAG_DMEIF0 | \
DMA_FLAG_TEIF0 | DMA_FLAG_HTIF0);
DMA_DeInit(DMA1_Stream6);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)I2C_TxBuffer;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_Init(DMA1_Stream6, &DMA_InitStructure);
DMA_Cmd(DMA1_Stream6, ENABLE);
while (DMA_GetCmdStatus(DMA1_Stream6) != ENABLE);
DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_TCIF6 | DMA_FLAG_FEIF6 | DMA_FLAG_DMEIF6 | \
DMA_FLAG_TEIF6 | DMA_FLAG_HTIF6);
I can't figure out why my code doesn't work! I've worked with TIM1 and everything works fine but when I change to TIM8, PC6 and PC7 are always on and the complementaries always off. Please help me out and happy holidays!
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "misc.h"
/* Private typedef -----------------------------------------------------------*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
/* Private define ------------------------------------------------------------*/
#define frequency 42500 /* output frequency 42500 KHz */
#define f1 1/2 /* phase shift 90 degrees */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int TimerPeriod = 0;
/* Private function prototypes -----------------------------------------------*/
void TIM_Config(void);
/* Private functions ---------------------------------------------------------*/
/**
* Main program
*/
int main(void)
{
/* TIM8 Configuration */
TIM_Config();
/* Compute the value to be set in ARR register to generate the desired signal frequency */
TimerPeriod = ((SystemCoreClock/2) / frequency) - 1;
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
/* Channel 1 and 2 Configuration in Toggle mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_Pulse = (TimerPeriod/6)+ (TimerPeriod * f1);
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = (TimerPeriod/6) ;
TIM_OC2Init(TIM8, &TIM_OCInitStructure);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 25; ///////// the right value for 250ns delay ////////
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM8, &TIM_BDTRInitStructure);
/* TIM8 counter enable */
TIM_Cmd(TIM8, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM8, ENABLE);
while (1)
{
}
}
/**
* Configure the TIM8 Pins.
*/
void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA, GPIOB and GPIOC clocks enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
/* TIM8 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
/*GPIOA Configuration: Channel 1N and BKIN as alternate function push-pull*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOA Configuration: Channel 1 and 2 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* GPIOB Configuration: Channel 2N as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pins to AF1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM8);
}
#Swanand try to change this
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
and let me know.