검색결과 리스트
CPU에 해당되는 글 19건
- 2013.02.08 STM32 TIM3 PWM MODE
- 2013.02.08 STM32F103 TIM2 OUTPUT COMPARE TIMMING
- 2013.02.08 STM32 SysTick 사용하기
- 2013.02.08 STM32 ADC2 Interrupt Mode 사용 1
- 2013.02.07 STM32 ADC1 DMA 사용방법1 1
- 2013.02.07 STM32 GPIO INPUT 사용하기
- 2013.02.07 STM32 UART DEBUG포트 사용하기
- 2013.02.07 STM32 GPIO 제어
- 2013.02.06 STM32F103VB
글
STM32 TIM3 PWM MODE
이번엔 TIMER3를 이용해서 PWM모드를 실험해 보겠씁니다.
Example description
===================
This example shows how to configure the TIM peripheral in PWM (Pulse Width Modulation) mode.
The TIMxCLK frequency is set to 36 MHz, the Prescaler is 0 so the TIM3 counter clock is 36 MHz.
The TIM3 is running at 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1)
The TIM3 CCR1 register value is equal to 500, so the TIM3 Channel 1 generates a
PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 50%:
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR + 1)* 100 = 50%
The TIM3 CCR2 register value is equal to 375, so the TIM3 Channel 2 generates a
PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 37.5%:
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR + 1)* 100 = 37.5%
The TIM3 CCR3 register value is equal to 250, so the TIM3 Channel 3 generates a
PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 25%:
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR + 1)* 100 = 25%
The TIM3 CCR4 register value is equal to 125, so the TIM3 Channel 4 generates a
PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 12.5%:
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR + 1)* 100 = 12.5%
The PWM waveform can be displayed using an oscilloscope.
'CPU > STM32F103' 카테고리의 다른 글
BOOT MODE에 관한 내용 (0) | 2013.06.20 |
---|---|
Serial DownLoad방법 (0) | 2013.06.20 |
STM32F103 TIM2 OUTPUT COMPARE TIMMING (0) | 2013.02.08 |
STM32 SysTick 사용하기 (0) | 2013.02.08 |
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
설정
트랙백
댓글
글
STM32F103 TIM2 OUTPUT COMPARE TIMMING
STM32F103VB의 스펙입니다.
7 timers
- Three 16-bit timers, each with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input
- 16-bit, motor control PWM timer with dead-time generation and emergency stop
- 2 watchdog timers (Independent and Window)
- SysTick timer 24-bit downcounter
다음과 같은 스펙을 가지고 있네요. 엄청 여러가지 기능이 있는데 아는건 많지 않네요.ㅎㅎ
타이머 7개 그중 3개는 16비트에 각각의 타이머는 4개의 IC/OC/PWM를 제공하네요.
TIM2-4까지가 이것에 해당합니다.
1개는 16비트 모터 콘트롤 PWM타이머 제공(이건 TIM1인것 같군요)
2개의 WATCHDOG
1개의 SysTick 24bit 카운터를 제공합니다.(이것은 이전에 구현했지요)
자 그럼 이번엔 첫번째 나와 있는 3개의 타이머중 TIM2를 OC로 구현 해보겠습니다.
Example description
===================
This example shows how to configure the TIM peripheral in Output Compare Timing
mode with the corresponding Interrupt requests for each channel in order to generate
4 different time bases.
The TIMxCLK frequency is set to 36 MHz, the Prescaler is 4 so the TIM2 counter
clock is 7.2 MHz.
The TIM2 CC1 register value is equal to 49152,
CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz,
so the TIM2 Channel 1 generates an interrupt each 6.8ms
The TIM2 CC2 register is equal to 32768,
CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 HzHz
so the TIM2 Channel 2 generates an interrupt each 4.55ms
The TIM2 CC3 register is equal to 16384,
CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4Hz
so the TIM2 Channel 3 generates an interrupt each 2.27ms
The TIM2 CC4 register is equal to 8192,
CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz
so the TIM2 Channel 4 generates an interrupt each 1.13ms.
1. stm32f10x_conf.h에 등록
#define _TIM
#define _TIM2
2. 프로젝트에 stm32f10x_tim.c 를 등록한다.
3. 메인함수
vu16 CCR1_Val = 49152;
vu16 CCR2_Val = 32768;
vu16 CCR3_Val = 16384;
vu16 CCR4_Val = 8192;
main()
{
..............
TIM2_Configuration();
}
이렇게 불렀습니다.
3.1 클럭 초기화
void TIM2_Configuration_RCC(void)
{
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
클럭 Enable합니다.
TIM2에 인가되는 클럭은 다음과 같습니다.
OSC 8M - PLL(72MHZ) - /2 - PCLK1(36MHZ)
RCC_PCLK1Config(RCC_HCLK_Div2); // PLL/2로 36MHZ가 됩니다.
3.2 인터럽트 초기화
void TIM2_Configuration_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
이렇게 등록합니다.
3.3 타이머 초기화
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM2_Configuration_RCC();
TIM2_Configuration_NVIC();
/* ---------------------------------------------------------------
TIM2 Configuration: Output Compare Timing Mode:
TIM2CLK = 36 MHz, Prescaler = 4, TIM2 counter clock = 7.2 MHz
CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz
CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz
CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz
CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz
--------------------------------------------------------------- */
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Prescaler configuration */
TIM_PrescalerConfig(TIM2, 4, TIM_PSCReloadMode_Immediate);
/* Output Compare Timing Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Timing Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Timing Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Timing Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
상당히 기네요.
일단 클럭관련 인터럽트 관련 초기화 함수를 호출합니다.
그리고 타이머 관련 설정
클럭 분주
OUTPUT COMPARE관련 설정
인터럽트 ENABLE
타이머 ENABLE합니다.
4. 인터럽트 서비스 루틴
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
/* Pin PE.12 toggling with frequency = 73.24 Hz */
GPIO_WriteBit(GPIOE, GPIO_Pin_12, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_12)));
capture = TIM_GetCapture1(TIM2);
TIM_SetCompare1(TIM2, capture + CCR1_Val);
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
/* Pin PE.13 toggling with frequency = 109.8 Hz */
GPIO_WriteBit(GPIOE, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_13)));
capture = TIM_GetCapture2(TIM2);
TIM_SetCompare2(TIM2, capture + CCR2_Val);
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
/* Pin PE.14 toggling with frequency = 219.7 Hz */
GPIO_WriteBit(GPIOE, GPIO_Pin_14, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_14)));
capture = TIM_GetCapture3(TIM2);
TIM_SetCompare3(TIM2, capture + CCR3_Val);
}
else
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
/* Pin PE.15 toggling with frequency = 439.4 Hz */
GPIO_WriteBit(GPIOE, GPIO_Pin_15, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_15)));
capture = TIM_GetCapture4(TIM2);
TIM_SetCompare4(TIM2, capture + CCR4_Val);
}
}
그럼 클럭에 따라서 설정된 카운트 값이 되면 인터럽트가 발생되어 해당 인터럽트로 들어 올것 입니다.
해당 주기는 소스에 표시 되어 있습니다.
오실로 스코프가 있어야 정확한지 확인해 보는데...스코프가 없어서 LED로 대충 되는 구나 확인하고 넘어 갑니다...
'CPU > STM32F103' 카테고리의 다른 글
Serial DownLoad방법 (0) | 2013.06.20 |
---|---|
STM32 TIM3 PWM MODE (0) | 2013.02.08 |
STM32 SysTick 사용하기 (0) | 2013.02.08 |
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
설정
트랙백
댓글
글
STM32 SysTick 사용하기
이번엔 STM32의 SysTick를 사용하여 Delay를 구현 해보도록 하겠습니다.
1. SysTick 사용설정
먼저 stm32f10x_conf.h에서 다음과 같이 설정합니다.
#define _SysTick
이래야 SysTick를 쓰겠죠!
2. SysTick를 프로젝트에 추가합니다.
stm32f10x_systick.c
3. Clock설정확인
SysTick에 공급되는 Clock에 따라서 타이머가 동작되는데..얼마나 공급할까요?
The RCC feeds the Cortex System Timer (SysTick) external clock with the AHB clock
(HCLK) divided by 8. The SysTick can work either with this clock or with the Cortex clock
(HCLK), configurable in the SysTick Control and Status Register.
이렇게 되어 있네요.
그림상으로는 8M OSC - PLL (72M) -ABH - /8 - Cortex System Timer
즉 9MHz가 되네요.
4. 기본설정
int main(void)
{
.......
/* SysTick end of count event each 1ms with input clock equal to 9MHz (HCLK/8, default) */
1> SysTick_SetReload(9000);
/* Enable SysTick interrupt */
2> SysTick_ITConfig(ENABLE);
while (1)
{
/* Insert 300 ms delay */
Delay(300);
// do somthing
}
}
1> The SysTick calibration value is set to 9000, which gives a reference time base of 1 ms with
the SysTick clock set to 9 MHz (max HCLK/8).라고 표시 되어 있네요.
즉 입력 clock이 9MHz이니 Timer에 9000를 설정하면 카운트하고 넘치거나하면 인터럽트가 발생하겠네요. 그러니 1msec마다 인터럽트가 발생하겠지요..
2>는 인터럽트 Enable하고 있네요.
그럼 여기서 Delay함수를 살펴봐야겠네요.
void Delay(u32 nTime)
{
/* Enable the SysTick Counter */
1> SysTick_CounterCmd(SysTick_Counter_Enable);
2> TimingDelay = nTime;
3> while(TimingDelay != 0);
/* Disable SysTick Counter */
4> SysTick_CounterCmd(SysTick_Counter_Disable);
/* Clear SysTick Counter */
5> SysTick_CounterCmd(SysTick_Counter_Clear);
}
1>에서 Timer를 동작시키네요.
2>는 Delay(300);이라고 호출되었으니 TimingDelay = 300 이 되고
3> TimingDelay 가 0이 될때 까지 기다리는 군요. 요건 인터럽트에서 하나씩 감소 시키다 0으로 되겠네요.
4> Timer를 Disable시키고,
5> 카운트 값을 Clear하네요.
5. 인터럽트 서비스 루틴 등록
void SysTickHandler(void)
{
TimingDelay_Decrement();
}
인터럽트가 발생하면 TimingDelay_Decrement()를 호출하네요.
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
TimingDelay_Decrement는 단순히 값을 하나씩 감소 시키네요.
이렇게 해서 SysTick Timer를 구현해 보았습니다.
다른건 Clock Enable이 있는데..SysTick은 없네요. 클럭도 /8로 고정되어 있고. 다른 모듈보다는 간단해서 좋네요..
인제 타이머 모듈로 넘어 갈까 합니다.
'CPU > STM32F103' 카테고리의 다른 글
STM32 TIM3 PWM MODE (0) | 2013.02.08 |
---|---|
STM32F103 TIM2 OUTPUT COMPARE TIMMING (0) | 2013.02.08 |
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
설정
트랙백
댓글
글
STM32 ADC2 Interrupt Mode 사용
이번엔 ADC2를 사용하여 인터럽트 모드로 동작 시켜 보겠습니다.
전반적인 내용은 이전 내용과 비슷하지만 adc의 설정이 약간 다르고, 인터럽트 관련 설정이 추가 되었습니다.
0. 환경설정
환경설정은 stm32f10x_conf.h에서
#define _ADC2
을 설정합니다.
1. 인터럽트 설정
1.1 인터럽트 등록
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
..................
/* Configure and enable ADC interrupt */
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
ADC1_2_IRQChannel인터럽트를 활성화 합니다.
1.2 인터럽트 서비스 루틴 추가
stm32f10x_it.c 에 인터럽트 처리함수를 추가합니다.
vu16 ADC2ConvertedValue
/*******************************************************************************
* Function Name : ADC1_2_IRQHandler
* Description : This function handles ADC1 and ADC2 global interrupts requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void ADC1_2_IRQHandler(void)
{
/* Get injected channel13 converted value */
ADC2ConvertedValue = ADC_GetConversionValue(ADC2);
}
인터럽트 서비스 루틴에서 EOC마다 변수에 저장합니다.
2. ADC관련 설정
2.1 CLOCK관련
/* Enable ADC1, ADC2, ADC3 and GPIOC clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOC, ENABLE);
해당 ADC2와 포트 GPIOC에 클럭을 설정합니다.
2.2 GPIO설정
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PC.0 (ADC Channel10, as analog inputs */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
해당 ADC핀을 아나로그 입력으로 설정합니다.
2.3 ADC설정
/* ADC2 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC2 regular channels configuration */
ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_28Cycles5);
/* Enable ADC2 EOC interupt */
ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* Enable ADC2 reset calibaration register */
ADC_ResetCalibration(ADC2);
/* Check the end of ADC2 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC2));
/* Start ADC2 calibaration */
ADC_StartCalibration(ADC2);
/* Check the end of ADC2 calibration */
while(ADC_GetCalibrationStatus(ADC2));
/* Start ADC2 Software Conversion */
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
위의 설정에서 ADC_ScanConvMode 가 DISABLE되고,
ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);와 같이 인터럽트를 ENABLE시킴니다. 그럼 NVIC에서 등록된것은 인터럽트 MASK정도 될듯하네요.
그럼 준비 완료되고.
3. 확인
메인루프에서 다음과 같이 찍었습니다.
printf("==== %d ====\r\n",ADC2ConvertedValue*3300/4096);
잘 나오네요.
인제 대충감이 잡히네요.
1> stm32f10x_conf.h에서 기능선택
2> 클럭관련 모듈설정
3> 해당 모듈의 인아웃 핀 섲정
3> 해당 기능 설정
4> 사용.
더블어 인터럽트는
1> NVIC_Configuration에 인터럽트 enable
2> 해당 모듈의 인터럽트 enable
3> 인터럽트 서비스 루틴 구현
주의 점은 인터럽트에서 합수 호출시 멈추는 경우가 있네요.
예로.
void ADC1_2_IRQHandler(void)
{
/* Get injected channel13 converted value */
ADC2ConvertedValue = ADC_GetConversionValue(ADC2);
/*if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_13) == 0x00)
GPIO_SetBits(GPIOE, GPIO_Pin_13);
else
GPIO_ResetBits(GPIOE, GPIO_Pin_13);*/
}
주석처리 된 부분이 그러네요..
요건 다시 분석 해보아야 겠네요.
그럼 오늘은 여기서 이만.
'CPU > STM32F103' 카테고리의 다른 글
STM32F103 TIM2 OUTPUT COMPARE TIMMING (0) | 2013.02.08 |
---|---|
STM32 SysTick 사용하기 (0) | 2013.02.08 |
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
STM32 UART DEBUG포트 사용하기 (0) | 2013.02.07 |
설정
트랙백
댓글
글
STM32 ADC1 DMA 사용방법1
STM32 ADC1 DMA 사용방법을 구현해 보겠씁니다.
ST example 의 설명입니다.
Example description
===================
This example describes how to use the ADC1 and DMA to transfer continuously
converted data from ADC1 to memory.
The ADC1 is configured to converts continuously ADC channel14.
Each time an end of conversion occurs the DMA transfers, in circular mode, the
converted data from ADC1 DR register to the ADC_ConvertedValue variable.
The ADC1 clock is set to 14 MHz.
그 동안 인터럽트 모드 폴링모드만 써 보았는데..STM32는 DMA로 사용할수 있네요.
설정 자체는 상당히 긴데..하나씩 살펴 보겠씁니다.
하드웨어는 PC0(ADC10)에 가변저항이 연결되어 있습니다.
1. stm32f10x_conf.h 수정
#define _ADC
#define _ADC1
#define _DMA
#define _DMA1_Channel1
을 설정해야 해당 라이브러리를 사용할수 있습니다.
2. Project file에 stm32f10x_adc.c 와 stm32f10x_dma를 포함합니다.
3. Main 초기화
3.1 Clock설정
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
ADC를 사용하기 위해 ADC와 DMA 그리고 GPIOC 포트DP 클럭을 인가합니다.
3.1 PORT PIN IO 설정
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
해당핀 PORT C의 0핀 즉 ADC10를 아나로그 입력으로 설정하다.
3.2 DMA 설정
1>#define ADC1_DR_Address ((u32)0x4001244C)
2>vu16 ADCConvertedValue;
3>DMA_InitTypeDef DMA_InitStructure;
/* DMA1 channel1 configuration ----------------------------------------------*/
3> DMA_DeInit(DMA1_Channel1);
4> DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
5> DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
6> DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
7> DMA_InitStructure.DMA_BufferSize = 1;
8> DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
9> DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
10> DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
11> DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
12> DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
13> DMA_InitStructure.DMA_Priority = DMA_Priority_High;
14> DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
15> DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
내용이 상당히 많다..머 이렇게 많은지.
1> 레지스터 ADC_DR의 주소이다.
2> typedef volatile unsigned short vu16;
3>Deinitializes the DMAy Channelx registers to their default reset values.
4> DMA_InitTypeDef DMA_InitStructure; 라고 정의 되어있고
typedef struct
{
u32 DMA_PeripheralBaseAddr;
u32 DMA_MemoryBaseAddr;
u32 DMA_DIR;
u32 DMA_BufferSize;
u32 DMA_PeripheralInc;
u32 DMA_MemoryInc;
u32 DMA_PeripheralDataSize;
u32 DMA_MemoryDataSize;
u32 DMA_Mode;
u32 DMA_Priority;
u32 DMA_M2M;
}DMA_InitTypeDef;
이렇게 정의 되어 있네요.
각각의 내용은 CPU내용을 참조해되는데 상당히 복잡하네요..요것은 다음에 다시 한번 살펴보기로 하고. 각각의 필드를 채우고 아래 함수를 콜 하네요.
/*******************************************************************************
* Function Name : DMA_Init
* Description : Initializes the DMAy Channelx according to the specified
* parameters in the DMA_InitStruct.
* Input : - DMAy_Channelx: where y can be 1 or 2 to select the DMA and
* x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the
* DMA Channel.
* - DMA_InitStruct: pointer to a DMA_InitTypeDef structure that
* contains the configuration information for the specified
* DMA Channel.
* Output : None
* Return : None
******************************************************************************/
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
{
u32 tmpreg = 0;
/* Check the parameters */
assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));
assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));
assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));
assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));
assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));
assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));
assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));
assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M));
/*--------------------------- DMAy Channelx CCR Configuration -----------------*/
/* Get the DMAy_Channelx CCR value */
tmpreg = DMAy_Channelx->CCR;
/* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
tmpreg &= CCR_CLEAR_Mask;
/* Configure DMAy Channelx: data transfer, data size, priority level and mode */
/* Set DIR bit according to DMA_DIR value */
/* Set CIRC bit according to DMA_Mode value */
/* Set PINC bit according to DMA_PeripheralInc value */
/* Set MINC bit according to DMA_MemoryInc value */
/* Set PSIZE bits according to DMA_PeripheralDataSize value */
/* Set MSIZE bits according to DMA_MemoryDataSize value */
/* Set PL bits according to DMA_Priority value */
/* Set the MEM2MEM bit according to DMA_M2M value */
tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;
/* Write to DMAy Channelx CCR */
DMAy_Channelx->CCR = tmpreg;
/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/
/* Write to DMAy Channelx CNDTR */
DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;
/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/
/* Write to DMAy Channelx CPAR */
DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/
/* Write to DMAy Channelx CMAR */
DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;
}
나머진 다음에
3.3 ADC 설정
ADC_InitTypeDef ADC_InitStructure;
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
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 = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
위와 같이 설정을 합니다.
여기도 상당히 내용이 많은데 일단 패스 .. 그럼 일단 입력된 아나로그 데이타가 변수 ADCConvertedValue 저장됩니다. 그럼 읽기만 하면 되는거죠.
/* ADC Init structure definition */
typedef struct
{
u32 ADC_Mode;
FunctionalState ADC_ScanConvMode;
FunctionalState ADC_ContinuousConvMode;
u32 ADC_ExternalTrigConv;
u32 ADC_DataAlign;
u8 ADC_NbrOfChannel;
}ADC_InitTypeDef;
4. 사용법
printf("==== %d ====\r\n",ADCConvertedValue*3300/4096);
메인의 무한 루프에서 다음과 같이 뺑뺑이 돌리면서 값을 바꾸어 보았습니다. 5mV정도 흔들리고 값을 잘 나오네요... 뒤에 3300/4096은 3.3V일때 3300으로 표시하기 위하여 변환용으로 사용합니다.
어째든 DMA기능이 있으니 쓰기는 상당히 편리하네요.. 그냥 변수만 읽으면 되니 근데.값이 언제 바뀌는지 알수 없네요. 일반적으로 ADC컨버젼 끝나고 값저장하고 흔들리는것을 방지하기 위해 이전의 값들과 평균내는 방법을 사용하기도 하는데....위와 같이 사용하면 요 방법을 쓰기가 힘드네요..
좀더 고민해 보아야 겠습니다.
또한 여러 채널일때 설정도 좀 공부해야될것 같습니다.
그럼 다음 다체널 ADC를 시도 해보지요.
'CPU > STM32F103' 카테고리의 다른 글
STM32 SysTick 사용하기 (0) | 2013.02.08 |
---|---|
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
STM32 UART DEBUG포트 사용하기 (0) | 2013.02.07 |
STM32 GPIO 제어 (0) | 2013.02.07 |
설정
트랙백
댓글
글
STM32 GPIO INPUT 사용하기
GPIO INPUT사용하기
이번엔 GPIO INPUT를 설정하여 확인 하여보자.
1. 포트 설정
1> RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
3> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
4> GPIO_Init(GPIOA, &GPIO_InitStructure);
1> 해당 포트에 CLOCK를 인가한다.
2> 해당포트의 핀을 설정한다.
3> 핀의 입력모드를 설정한다.
typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
4> 위의 설정값을 레지스터에 설정한다.
2. 입력확인
1> if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) != 0x00)
2> printf("==== GPIO PORT A PIN 0 == 0 ====\r\n");
하드웨어는 눌렸을때 HIGH가 입력되고, 평소에는 LOW가 입력됨
1> 현재 입력이 1인가 확인
2> 입력이 1 즉 KEY 눌리면 PRINTF수행
'CPU > STM32F103' 카테고리의 다른 글
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
---|---|
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 UART DEBUG포트 사용하기 (0) | 2013.02.07 |
STM32 GPIO 제어 (0) | 2013.02.07 |
STM32F103VB (0) | 2013.02.06 |
설정
트랙백
댓글
글
STM32 UART DEBUG포트 사용하기
이번엔 UART를 포팅할 예정이다.
말이 포팅이지 ST에서 제공하는 소스 가지고, 해당 보드에 확인 테스트 하는 것이다.
예전엔 CPU DATASHEET가지고 하나하나 코딩해서 레지스터 세팅하고 했는데. 지금은 카피하고 해당포트만 맞추어 주면 끝...나도 나이가 많이 먹었나 보다..옛날 이야기 하니..
자그럼 디버그를 위한 UART를 설정하자.
1. 사용방법
1.1 stm32f10x_conf.h 설정
#define DEBUG 1
#define _USART
#define _USART1
stm32f10x_lib.h --> stm32f01x_map.h --> stm32f10x.conf.h 요렇게 링크하네요.
위와 같이 해당 모듈에 대한 define를 해주어야 이후 stm32f10x_lib.h 을 통해 해당 h들이 포함된다.
1.2 UART 입출력 포트 설정
아래와 같이 uart를 사용하기 위하여 rx,tx핀에 대한 입출력을 설정하야한다.
avr은 그냥 자동으로 변경되었는데..stm32는 해줘어야 되나보다.
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
1.3 클럭관련 설정한다.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- RCC_Configuration함수에서 마지막에 위를 호출하여 USART1에 대하여 클럭를 설정한다.
1.4 UART1에 대한 초기화 작업
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART1 configuration ------------------------------------------------------*/
/* USART1 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
*/
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_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* Enable USART1 */
USART_Cmd(USART1, ENABLE); //인제 동작시작
}
일단 UART에 대한 초기작업은 되었고 이후는 사용만 하면 된다.
1.5 PUTCHAR_PROTOTYPE 선언
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (u8) ch);
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
return ch;
}
원래main에서 printf를 사용하면 <stdio.h>에서 호출하고 printf함수에서 PUTCHAR_PROTOTYPE를 호출하여 사용하는것 같다.
1.6 사용
printf("\r\n STM32F10x Firmware Library compiled in DEBUG mode... \n\r");
이럼... UART1에서 TERMINAL로 출력이 생긴다.
2. 전체
int main(void)
{
int i=0;
#ifdef DEBUG
debug(); //요건 몰까요?
#endif
/* Configure the system clocks */
RCC_Configuration(); // 클럭관련 설정후 UART 클럭도 설정
/* NVIC Configuration */
NVIC_Configuration();
/* Configure the GPIOs */
GPIO_Configuration(); // uart관련 io설정
/* Configure the USART1 */
USART_Configuration(); // UART1에 대하여 초기화 작업
printf("\r\n STM32F10x Firmware Library compiled in DEBUG mode... \n\r");
printf("...Run-time checking enabled \n\r");
while (1)
{
Delay(0xFFFFF);
printf("==== %d ====\r\n",i++); // 뺑뺑이 돌려보았습니다.
}
}
'CPU > STM32F103' 카테고리의 다른 글
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
---|---|
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
STM32 GPIO 제어 (0) | 2013.02.07 |
STM32F103VB (0) | 2013.02.06 |
설정
트랙백
댓글
글
STM32 GPIO 제어
1.GPIO설정
1.1 해당 포트에 대하여 CLOCK설정한다.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_LED, ENABLE);
-RCC_APB2Periph_GPIO_LED는 platform_config.h에 아래와 같이 정의
-#define RCC_APB2Periph_GPIO_LED RCC_APB2Periph_GPIOE
1.2 해당 포트의 각 핀 마다 모드를 설정한다.
1>GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_12;
2>GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
3>GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4>GPIO_Init(GPIO_LED, &GPIO_InitStructure);
-1>은 설정하고자 하는 핀의 목록을 설정한다.
-2>은 1>에서 설정한 핀의 모드를 설정한다.
-3>은 1>에서 설정한 출력속도를 설정한다.
-4>은 해당 구조체를 , 해당포트와 설정하여 GPIO_Init함수를 호출하여 CPU에 적용한다.
-GPIO_LED는 platform_config.h에 정의
-#define GPIO_LED GPIOE
2.. 전체구조
#include "stm32f10x_lib.h"
#include "platform_config.h"
GPIO_InitTypeDef GPIO_InitStructure;
ErrorStatus HSEStartUpStatus;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void Delay(vu32 nCount);
int main(void)
{
/* System Clocks Configuration **********************************************/
RCC_Configuration(); // clock에 대한 정의를 한다.
/* NVIC Configuration *******************************************************/
NVIC_Configuration(); // ram 또는 rom 에 따라 vector를 설정한다.
/* Configure IO connected to LD1, LD2, LD3 and LD4 leds *********************/
/* Enable GPIO_LED clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_LED, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_12; 핀설정
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_LED, &GPIO_InitStructure);
while (1)
{
/* Turn on LD1 */
GPIO_SetBits(GPIO_LED, GPIO_Pin_12); // 해당 핀 셋
/* Insert delay */
Delay(0xFFFFF);
GPIO_ResetBits(GPIO_LED, GPIO_Pin_12); // 해당핀 리셋
Delay(0xFFFFF);
}
}
'CPU > STM32F103' 카테고리의 다른 글
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
---|---|
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
STM32 UART DEBUG포트 사용하기 (0) | 2013.02.07 |
STM32F103VB (0) | 2013.02.06 |
설정
트랙백
댓글
글
STM32F103VB
http://www.st.com/internet/mcu/product/164493.jsp
- ARM 32-bit Cortex™-M3 CPU Core
- 72 MHz maximum frequency,1.25 DMIPS/MHz (Dhrystone 2.1) performance at 0 wait state memory access
- Single-cycle multiplication and hardware division
- Memories
- 64 or 128 Kbytes of Flash memory
- 20 Kbytes of SRAM
- Clock, reset and supply management
- 2.0 to 3.6 V application supply and I/Os
- POR, PDR, and programmable voltage detector (PVD)
- 4-to-16 MHz crystal oscillator
- Internal 8 MHz factory-trimmed RC
- Internal 40 kHz RC
- PLL for CPU clock
- 32 kHz oscillator for RTC with calibration
- Low power
- Sleep, Stop and Standby modes
- VBAT supply for RTC and backup registers
- 2 x 12-bit, 1 μs A/D converters (up to 16 channels)
- Conversion range: 0 to 3.6 V
- Dual-sample and hold capability
- Temperature sensor
- DMA
- 7-channel DMA controller
- Peripherals supported: timers, ADC, SPIs, I2Cs and USARTs
- Up to 80 fast I/O ports
- 26/37/51/80 I/Os, all mappable on 16 external interrupt vectors and almost all 5 V-tolerant
- Debug mode
- Serial wire debug (SWD) & JTAG interfaces
- 7 timers
- Three 16-bit timers, each with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input
- 16-bit, motor control PWM timer with dead-time generation and emergency stop
- 2 watchdog timers (Independent and Window)
- SysTick timer 24-bit downcounter
- Up to 9 communication interfaces
- Up to 2 x I2C interfaces (SMBus/PMBus)
- Up to 3 USARTs (ISO 7816 interface, LIN, IrDA capability, modem control)
- Up to 2 SPIs (18 Mbit/s)
- CAN interface (2.0B Active)
- USB 2.0 full-speed interface
- CRC calculation unit, 96-bit unique ID
- Packages are ECOPACK®
'CPU > STM32F103' 카테고리의 다른 글
STM32 ADC2 Interrupt Mode 사용 (1) | 2013.02.08 |
---|---|
STM32 ADC1 DMA 사용방법1 (1) | 2013.02.07 |
STM32 GPIO INPUT 사용하기 (0) | 2013.02.07 |
STM32 UART DEBUG포트 사용하기 (0) | 2013.02.07 |
STM32 GPIO 제어 (0) | 2013.02.07 |