A try to controlling WS2812 LEDs using timer PWM and DMA. I almost succeeded but now I have a problem that I can't solve. As You can see on the image the first two LEDs glow green but another LEDs glow reed. But all of them should glow green.
![Link for image:] https://ibb.co/c2XEqS
I use Nucleo Board with STM32F1 microcontroller (64MHZ).
Timer initialization:
void Init_TIM4()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_8;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio);
TIM_TimeBaseInitTypeDef tim;
TIM_TimeBaseStructInit(&tim);
tim.TIM_CounterMode = TIM_CounterMode_Up;
tim.TIM_Period = 80;
tim.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM4, &tim);
TIM_OCInitTypeDef channel;
TIM_OCStructInit(&channel);
channel.TIM_OCMode = TIM_OCMode_PWM1;
channel.TIM_OutputState = TIM_OutputState_Enable;
channel.TIM_Pulse = 0;
channel.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OC3Init(TIM4, &channel);
}
DMA and rest of code:
#define BUFFER_SIZE 25
volatile uint16_t src_buffer[BUFFER_SIZE] = {32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,0};
void send_data()
{
DMA_SetCurrDataCounter(DMA1_Channel1, BUFFER_SIZE);
DMA_Cmd(DMA1_Channel1, ENABLE);
TIM_Cmd(TIM4, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
TIM_Cmd(TIM4, DISABLE);
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_ClearFlag(DMA1_FLAG_TC1);
}
int main(void)
{
Init_TIM4();
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_InitTypeDef dma;
DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR3;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryBaseAddr = (uint32_t)src_buffer;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_BufferSize = BUFFER_SIZE;
dma.DMA_M2M = DMA_M2M_Disable;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_Mode = DMA_Mode_Normal;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_Init(DMA1_Channel1, &dma);
TIM_DMACmd(TIM4, TIM_DMA_CC1, ENABLE);
for (int i = 0; i < 8; i++) {
send_data();
}
while(1)
{
}
}
Related
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 want to read touch activity from the touchscreen.If i touch, i want to led blink. Some my definitions in below code but generally i want to get my activity with i2c
Some definitions:
uint8_t deviceaddr;
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len);
static const int I2C_TIMEOUT = 65536;
unsigned char i2c_buffer[256];
uint32_t res;
This is my i2c read code:
static uint32_t touch_i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t *pBuffer, uint16_t len)
{ //uint8_t deviceaddr ,0x00,(uint8_t *)&buf, sizeof(buf)
uint32_t timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if ((timeout--) == 0)
return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr << 1, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while (I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET)
{
if ((timeout--) == 0)
return 0;
}
}
This is my settings
void configure_interrupt_pins()
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/*ENABLE CLOCK FOR GPIOX*/
RCC_APB1PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
// ENABLE CLOCK FOR SYSCFG
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//SET PIN AS INPUT
// init_pin(EX_NCVIC_PORT, EX_NCVIC_Pin, GPIO_MODE_INPUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
//TELL THE SYSTEM THAT YOU WILL USE PXX FOR EXTI_LineX
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex);
//CONFIGIRATION of exti
EXTI_InitStruct.EXTI_Line = EXTI_Linex; //pxx connect to line x
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //enable interrupt
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //interrupt mode
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //triggers on rising and failing edge
EXTI_Init(&EXTI_InitStruct); //add to exti
//CONFIGURATION of nvic
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
This is my interrupt
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus((EXTI_Line0) != RESET))
{
res = touch_i2c_read(0x42, 0x00, i2c_buffer, 22);
printf("deneme");
if (!res)
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOE, GPIO_Pin_13);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
But my code not working. Stm32 dont understand touch activity how can i solve this.
Edit i change line 1 every external interupts but i have res value 0 how can i fix this it must be different 0
Using a while() loop in an interrupt will cause problems, because the controller will never exit the loop. Try to use your i2c read Function in main() (with other words, a not-interrupt-context) and look if it works there.
I solved this error.
I hadn't any signal pb7 and pb6 so i changed codes as below:
// enable APB1 peripheral clock for I2C1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// enable clock for SCL and SDA pins
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
And then,
Device adress of the FT6236 was mising. it is not include at datasheet so i used debugging. I found the device adress which is the (0x32). And than my code working succesfully.
I am experimenting with some VGA generating code by Artekit, at https://www.artekit.eu/vga-output-using-a-36-pin-stm32/. This code generates a PWM signal for HSYNC using TIM2 Channel 2, which is output on port PA1. This all works correctly. Now I would like to remap TIM2 so that the PWM signal is remapped to pin PB3. After calling GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE) the PWM signal no longer appears on PA1 but it does not appear on PB3 although all timer interrupts continue to work as normal. What am I missing?
RCC configuration is as follows:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SPI1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
Relevant code is below.
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef nvic;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
u32 TimerPeriod = 0;
u16 Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
// Remap PA1 -> PB3
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TimerPeriod = 2048;
Channel1Pulse = 144; /* HSYNC */
Channel2Pulse = 352; /* HSYNC + BACK PORCH */
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(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
/* TIM1 counter enable and output enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* Select TIM1 as Master */
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
TimerPeriod = 625; /* Vertical lines */
Channel2Pulse = 2; /* Sync pulse */
Channel3Pulse = 24; /* Sync pulse + Back porch */
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(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
/* TIM2 counter enable and output enable */
TIM_CtrlPWMOutputs(TIM2, ENABLE);
/* Interrupt TIM2 */
nvic.NVIC_IRQChannel = TIM2_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 1;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);
/* Interrupt TIM1 */
nvic.NVIC_IRQChannel = TIM1_CC_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 1;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM1, ENABLE);
Thanks #old_timer, that put me on the right track. SWO is enabled by default, which is on PB3 and needs to be disabled.
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
does the trick. The two remappings need to be done separately, combining them does not work.
I have to use 4 ADC channels in my stm32f3 Discovery, so I've decided to use DMA with Nvic. Values sent by USART are correct, however, the DMA1 Channel1 interrupt is called only once after downloading code to flash. I need a continuous conversion, is there something wrong with ADC/DMA/Nvic configuration?
#include"stm32f30x.h"
#include"stm32f30x_gpio.h"
#include"stm32f30x_rcc.h"
#include"stm32f30x_usart.h"
#include"stm32f30x_misc.h"
#include"stm32f30x_adc.h"
#include"stm32f30x_tim.h"
#include"stm32f30x_dma.h"
#define ADC1_DR ((uint32_t)0x4001244C)
__IO uint16_t calibration_value = 0;
__IO uint32_t TimingDelay = 0;
__IO uint16_t ADC_Values[4];
uint16_t tmp[4];
volatile uint32_t dmaFlag = 0;
volatile char rxData[100];
volatile long int rxIndex=0, rxFlag=0;
void USART_puts( USART_TypeDef* USARTx, char *str )
{
while(*str)
{
while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
USART_SendData(USARTx, *str);
*str++;
}
}
void adc_init(void);
int main(void)
{
int8_t dmaIndex;
int k;
usart_init();
USART_puts(USART1,"ok");
adc_init();
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_RDY));
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_StartConversion(ADC1);
//
while(1)
{
while(!dmaFlag);
usart_num(tmp[0]);
usart_num(tmp[1]);
usart_num(tmp[2]);
usart_num(tmp[3]);
for(k=0;k<10000000;k++);
dmaFlag= 0;
}
}
void adc_init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure1;
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure1);
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
ADC_InitStructure.ADC_NbrOfRegChannel = 4;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_StructInit(&ADC_InitStructure);
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) != RESET );
calibration_value = ADC_GetCalibrationValue(ADC1);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 4, ADC_SampleTime_7Cycles5);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Values;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16 bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16 bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
}
void DMA1_Channel1_IRQHandler(void)
{
USART_puts(USART1,"fsfr");
if (DMA_GetITStatus(DMA1_IT_TC1))
{
int dmaIndex;
for(dmaIndex=0; dmaIndex<4; dmaIndex++)
{
tmp[dmaIndex]=ADC_Values[dmaIndex]/4;
}
DMA_ClearITPendingBit(DMA1_IT_TC1);
dmaFlag= 1;
}
}
void usart_init( void )
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init( GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
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);
USART_ITConfig( USART1, USART_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd( USART1, ENABLE);
}
void USART1_IRQHandler( void )
{
if( USART_GetITStatus( USART1, USART_IT_RXNE) )
{
rxData[rxIndex] = USART_ReceiveData(USART1);
// USART_ClearITPendingBit(USART1,USART_IT_RXNE);
while( !(rxData[rxIndex] == 'e') )
{
if( USART_GetITStatus( USART1, USART_IT_RXNE) )
{
rxIndex++;
rxData[rxIndex] = USART_ReceiveData(USART1);
if( rxData[rxIndex] == ' ')
rxData[rxIndex] = '0';
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
rxFlag = 1;
}
///USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
void rxDataClear( void )
{
int i=0;
while( rxData[i] )
{
rxData[i] = 0;
i++;
}
rxIndex = 0;
}
void usart_float( float liczba )
{
float tmp;
char dane[7];
tmp = liczba;
dane[0]=(((int)tmp %1000) /100)+0x30;
dane[1]=(((int)tmp %100) /10)+0x30;
dane[2]=(((int)tmp %10))+0x30;
dane[3]='.';
dane[4]=((int)(tmp*10) %10)+0x30;
dane[5]=((int)(tmp*100) %10)+0x30;
dane[6]=((int)(tmp*1000) %10)+0x30;
dane[7]='\0';
USART_puts(USART1,dane);
}
void usart_num(signed int liczba)
{
int i, length=0,znak=0;
char liczba_str[10] = {0};
if( liczba < 0 )
{
znak = 1;
liczba = - liczba;
}
for( i = 1; (i <= liczba) && (length <= 10); i*=10 )
{
if( (liczba/i) > 0 )
length++;
}
if(length == 0)
length = 1;
i = 1;
while(length)
{
liczba_str[length-1]=liczba%(10*i)/i+48;
length--;
i*= 10;
}
if(znak)
USART_puts(USART1,"-");
else
USART_puts(USART1," ");
USART_puts(USART1, liczba_str );
}
Try this to continuous conversion,change this:
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
to :
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
and replace this:
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
by:
ADC_DMAConfig( ADC1, ADC_DMAMode_Circular );
/* Enable ADC1 DMA */
ADC_DMACmd( ADC1, ENABLE );
/* Enable ADC1 */
ADC_Cmd( ADC1, ENABLE );
/* Wait for ADC1 ready */
i = 0xFFFFF;
while(!ADC_GetFlagStatus( ADC1, ADC_FLAG_RDY ) && i) i--;
/* Enable the DMA1 channel1 */
DMA_Cmd( DMA1_Channel1, ENABLE );
/* Start ADC1 Software Conversion */
ADC_StartConversion( ADC1);`
I make this easy example, with count pulse input TI1 and reset pulse input TI2
when enable reset trigger counter give random numbers!
stm32 driver https://github.com/mbedmicro/mbed/blob/9b7d23d47153c298a6d24de9a415202705889d11/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32L4/stm32l4xx_hal_tim.h
function is like this:
/* Select the TIM_SMCR_TS_1 signal as Input trigger for the TIM */
htim->Instance->SMCR &= ~TIM_SMCR_TS;
htim->Instance->SMCR |= TIM_SMCR_TS_1;
Use the TIM_SMCR_TS_1 to reset the TIM counter each edge detection */
htim->Instance->SMCR &= ~TIM_SMCR_SMS;
htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
code:
#include "mbed.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_tim_ex.h"
//direction to PA_9 -- step pulse to PA_8
uint16_t count1;
void pulsecount(void)
{
TIM_HandleTypeDef timer;
TIM_IC_InitTypeDef ICconfiginit;
TIM_ClockConfigTypeDef counter;
TIM_SlaveConfigTypeDef SlaveModeselect;
GPIO_InitTypeDef GPIO_InitStruct;
__TIM1_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
timer.Instance = TIM1;
timer.Init.Period = 0xffff;
timer.Init.Prescaler = 0;
timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timer.Init.CounterMode = TIM_COUNTERMODE_UP;
ICconfiginit.ICFilter = 0x0f;
ICconfiginit.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
ICconfiginit.ICPrescaler = TIM_ICPSC_DIV1;
ICconfiginit.ICSelection = TIM_ICSELECTION_DIRECTTI;
counter.ClockSource = TIM_CLOCKSOURCE_TI1;
counter.ClockFilter = 0x0f;
SlaveModeselect.SlaveMode = TIM_SLAVEMODE_RESET;
SlaveModeselect.InputTrigger = TIM_TS_TI2FP2;
HAL_TIM_IC_Init(&timer);
HAL_TIM_IC_ConfigChannel(&timer, &ICconfiginit, TIM_CHANNEL_1);
HAL_TIM_ConfigClockSource(&timer, &counter);
HAL_TIM_SlaveConfigSynchronization(&timer, &SlaveModeselect); ///<<< not reset
HAL_TIM_IC_Start(&timer, TIM_CHANNEL_1);
TIM1->EGR = 1; // Generate an update event
TIM1->CR1 = 1; // Enable the counter
}
int main()
{
pulsecount();
while (1) {
count1=TIM1->CNT;
printf("%d\r\n", count1);
wait(1.0);
};
}