STM32F103官方初始化模板

发布者:Serendipitous33最新更新时间:2018-08-12 来源: eefocus关键字:STM32F103  初始化模板 手机看文章 扫描二维码
随时随地手机看文章


#include "stm32f10x_lib.h"

 

 

系统时钟初始化函数==========================================================================================

 

void RCC_Configuration(void)

{

    /* 定义枚举类型变量 HSEStartUpStatus */

    ErrorStatus HSEStartUpStatus;

    

    /* 复位系统时钟设置*/

    RCC_DeInit();

    /* 开启HSE*/

    RCC_HSEConfig(RCC_HSE_ON);

    /* 等待HSE起振并稳定*/

    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    /* 判断HSE起是否振成功,是则进入if()内部 */

    if(HSEStartUpStatus == SUCCESS)

    {

    /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */

    RCC_HCLKConfig(RCC_SYSCLK_Div1); 

    /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */

    RCC_PCLK2Config(RCC_HCLK_Div1); 

    /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */

    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* 设置FLASH延时周期数为2 */

    FLASH_SetLatency(FLASH_Latency_2);

    /* 使能FLASH预取缓存 */

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* 使能PLL */ 

    RCC_PLLCmd(ENABLE);

    /* 等待PLL输出稳定 */

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    /* 选择SYSCLK时钟源为PLL */

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* 等待PLL成为SYSCLK时钟源 */

    while(RCC_GetSYSCLKSource() != 0x08);

    }

    

    /* 打开APB2总线上的GPIOA时钟*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);

}

 

GPIO口初始化函数====================================================================================================

 

void GPIO_Configuration(void)

{

    /* 定义GPIO初始化结构体 GPIO_InitStructure */

    GPIO_InitTypeDef GPIO_InitStructure;

    

    /* 设置 GPIOA.4 为推挽输出,最大翻转频率为50MHz*/

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

}

 

常用GPIO函数:

  GPIO_WriteBit(GPIOA,GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4)));//翻转GPIOA.4电平

  GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_11);  //读取电平,返回1或0;

 

系统节拍定时器初始化====================================================================================================

 

void Systick_Configuration(void)

{

    SysTick_CounterCmd(SysTick_Counter_Disable);  /* 失能Systick定时器 */

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  /* 选择HCLK为Systick时钟源 */

    SysTick_CounterCmd(SysTick_Counter_Clear); /* 清除Systick计数器 */

    SysTick_SetReload(900);  /* 主频为72/8MHz,配置计数值为900 可以得到0.1ms定时间隔*/

}

 

利用系统节拍定时器延时0.1ms函数(带参)================================================================================

 

void Delay_01ms(int c)

{

     int cc;

     for(cc=0;cc

    SysTick_CounterCmd(SysTick_Counter_Enable);/* 启动Systick计数 */

    while(SysTick_GetFlagStatus(SysTick_FLAG_COUNT) == 0); /* 等待Systick计数至0 */

    SysTick_CounterCmd(SysTick_Counter_Disable);  /* 失能Systick定时器 */

    SysTick_CounterCmd(SysTick_Counter_Clear); /* 清除Systick计数器 */

}

}

//SysTick_ITconfig(ENABLE);//使能SysTick中断

 

利用USART1进行串口通信初始化==============================================================================================

 

void USART_Configuration(void)

{

    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 9600; //波特率为9600bps

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 8位数据长度

    USART_InitStructure.USART_StopBits = USART_StopBits_1;// 1个停止位,无校验

    USART_InitStructure.USART_Parity = USART_Parity_No ;  // 禁用硬件流控制

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 禁止USART时钟

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //在第2个边沿捕获数据,最后一位数据的时钟脉冲不从 SCLK 输出

    USART_Init(USART1 , &USART_InitStructure);

    USART_Cmd(USART1 , ENABLE); // /* 使能USART1 */

}

 

/* 设置USART1的Tx脚(PA.9)为第二功能推挽输出模式 */

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

    /* 设置USART1的Rx脚(PA.10)为浮空输入脚 */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOA , &GPIO_InitStructure);

 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE);

 

 

串口通信模板===========================================================================================================

 

/* 等待USART1接收数据完毕 */

        if(USART_GetFlagStatus(USART1 , USART_IT_RXNE) == SET)

        {

            /* 向串口发送接收到的数据 */

            USART_SendData(USART1 , USART_ReceiveData(USART1));

            /* 短延时,保证收发稳定性 */

            for(i = 0; i < 500; i ++);

        }

 

翻转电平===============================================================================================================

 

GPIO_WriteBit(GPIOA,GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4)));//翻转GPIOA.4电平

 

判断串口接收数据========================================================================================================

 

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)

 

 

位带操作================================================================================================================

 

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 

#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 

#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 

#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 

#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 

#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 

#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 

#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 

#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    

#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 

#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 

#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 

#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 

#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 

#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 

#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 

#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //Êä³ö 

#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //ÊäÈë 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //Êä³ö 

#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //ÊäÈë 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //Êä³ö 

#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //ÊäÈë 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //Êä³ö 

#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //ÊäÈë 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //Êä³ö 

#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //ÊäÈë

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //Êä³ö 

#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //ÊäÈë

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //Êä³ö 

#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //ÊäÈë

 

#define LED PAout(8)// 定义PA8

 

NVIC中断优先级配置======================================================================================================

 

void NVIC_Configuration(void)

{

 

NVIC_InitTypeDef NVIC_InitStructure; 

#ifdef  VECT_TAB_RAM  

  NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0); /* 中断向量表起始地址从 0x20000000 开始 */ 

#else 

  NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0);  /* 中断向量表起始地址从 0x80000000 开始 */  

#endif

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 选择NVIC优先级分组2 */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQChannel; /* 使能EXIT 2通道 ,1级先占优先级 ,0级次占优先级 (0级优先级最高)*/

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

外部中断设置============================================================================================================

 

void EXIT_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

/* 设置外部中断0通道(EXIT Line0)在下降沿时触发中断 */  

  EXTI_InitStructure.EXTI_Line = EXTI_Line2 ;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

// EXTI_GenerateSWInterrupt(EXTI_Line2);//这个函数可以软件进入中断

}

 

//注意:在void GPIO_Configuration(void)函数中需要添加如下:(或者在当前函数下添加)

//GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource2);//此处选定PA2引脚,所占用中断必为EXIT2

//注意:使用外部中断必须打开复用口时钟,在void RCC_Configuration(void)中需要添加如下:

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);后面的AFIO

//中断服务函数在stm32f10x_it.c中,中断结束需要清除,如:EXTI_ClearFlag(EXTI_Line2);

 

窗口看门狗设置===========================================================================================================

 

在RCC配置中加入:RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

 

void WWDG_Configuration(void)

{

    WWDG_SetPrescaler(WWDG_Prescaler_8); /* 设置WWDG预分频值为8,WWDG时钟频率 = (PCLK1/4096)/8 = 244 Hz(~4ms)*/

    WWDG_Enable(0x7F);/* 设置WWDG初始计数值为0x7F并启动WWDG,此时WWDG 超时时间为4ms * (0x7F - 0x3F) = 264ms */

    WWDG_ClearFlag(); /* 清除 WWDG 早期唤醒中断(EWI)标志 */

    WWDG_EnableIT(); /* 使能 WWDG 早期唤醒中断(EWI) */

}

 

在NVIC配置中加入:

    NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//先占优先级1(用户值可选)

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_Init(&NVIC_InitStructure);

 

在中断服务文件中的void WWDG_IRQHandler(void)函数中加入:

    WWDG_SetCounter(0x7F);/* 更新 WWDG 计数器 */

    WWDG_ClearFlag(); /* 清除 WWDG 早期唤醒中断(EWI)标志 */

 

在main中的初始化区域里加入以检查是否发生过窗口看门狗复位:

 if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)

    {

        printf("\r\n The STM32 has been reset by WWDG  \r\n");

    RCC_ClearFlag(); /* 清除看门狗复位标志 */

    }

    else

    {

        WWDG_Configuration();/* 设置 WWDG */

        printf("\r\n The STM32 has't been reset by WWDG before  \r\n");

    }

 

ADC采集PB0口电压模拟值====================================================================================================

 

void ADC_Configuration(void)

{

ADC_InitTypeDef ADC_InitStructure;

RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* 配置ADC时钟分频 */

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 数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = 1;   //进行规则转换的 ADC 通道的数目为1

ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);//设置ADC1使用8转换通道转换顺序1采样时间为55.5周期

ADC_Cmd(ADC1, ENABLE);/* 使能 ADC1 */ 

ADC_ResetCalibration(ADC1);/* 复位 ADC1 的校准寄存器 */ 

while(ADC_GetResetCalibrationStatus(ADC1)); /* 等待 ADC1 校准寄存器复位完成 */

ADC_StartCalibration(ADC1);/* 开始 ADC1 校准 */

while(ADC_GetCalibrationStatus(ADC1)); /* 等待 ADC1 校准完成 */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);/* 启动 ADC1 转换 */

}

 

定义输出模拟量 float VolValue

 

RCC配置: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 |RCC_APB2Periph_GPIOB, ENABLE);

 

GPIO配置,将 PB.0 设置为模拟输入脚:

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOB , &GPIO_InitStructure);

 

采集函数:

VolValue = 2.56 * ADC_GetConversionValue(ADC1) / 0X0FFF;

//2.56为参考电压,0X0FFF为转换结果最大值

 

通用定时器之基本定时=====================================================================================================

 

void TIM_Configuration(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    TIM_DeInit(TIM2);                              //复位TIM2定时器

    TIM_InternalClockConfig(TIM2);  //采用内部时钟给TIM2提供时钟源    

    TIM_TimeBaseStructure.TIM_Period = 2000;        // 1s (2000*500us)     

    TIM_TimeBaseStructure.TIM_Prescaler = 36000-1;    // 分频36000  (500us)     

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分频  

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数方向向上计数

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);  //清除TIM2溢出中断标志

TIM_ARRPreloadConfig(TIM2,DISABLE);  //禁止ARR预装载缓冲器(如果允许就能够更改TIM_period:2000这个值)

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //TIM2溢出中断允许

    TIM_Cmd(TIM2, ENABLE); //开启tim2计数

}

 

RCC配置中加入:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

NVIC配置中加入:

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

中断服务函数:

        if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET){

            //GPIO_WriteBit(GPIOB,GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_8)));

TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);//清除TIM2的中断待处理位

}

 

常用函数:

  TIM2->CNT=0;  //清零计数器

  TIM=TIM_GetCounter(TIM2);    //将TIM2里计数器的值返回给变量TIM

 

通用计时器--时间基准======================================================================================================

(此段代码并不充分,其基本功能是用一个定时器来定时4个不同时间段来改变4个IO口电平,通道不需要与IO口相匹配)

 

vu16 CCR1_Val = 40000; /* 初始化输出比较通道1计数周期变量*/

vu16 CCR2_Val = 20000; /* 初始化输出比较通道2计数周期变量*/

vu16 CCR3_Val = 10000; /* 初始化输出比较通道3计数周期变量*/

vu16 CCR4_Val = 5000; /* 初始化输出比较通道4计数周期变量*/

 

void TIM_Configuration(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;/* 定义 TIM_TimeBase 初始化结构体 TIM_TimeBaseStructure */

TIM_OCInitTypeDef  TIM_OCInitStructure;/* 定义 TIM_OCInit 初始化结构体 TIM_OCInitStructure */

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

TIM_PrescalerConfig(TIM2 , 7199 , TIM_PSCReloadMode_Immediate);/* 设置预分频值,且立即装入 */

/*

* 设置 OC1,OC2,OC3,OC4 通道

*   工作模式为计数器模式

*   使能比较匹配输出极性

*   时钟分割0

*   向上计数模式

*/

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OCInitStructure.TIM_Pulse = CCR1_Val;

TIM_OC1Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

TIM_OC2Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

TIM_OC3Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

TIM_OC4Init(TIM2, &TIM_OCInitStructure);

/* 禁止预装载寄存器 */

TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Disable);

TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Disable);

TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Disable);

TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Disable);

TIM_ITConfig(TIM2 , TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 , ENABLE); /* 使能 TIM 中断 */

TIM_Cmd(TIM2 , ENABLE);/* 启动 TIM 计数 */

}

 

中断服务程序:

extern vu16 CCR1_Val; /* 外部声明输出比较通道1计数周期变量*/

extern vu16 CCR2_Val; /* 外部声明输出比较通道2计数周期变量*/

extern vu16 CCR3_Val; /* 外部声明输出比较通道3计数周期变量*/

extern vu16 CCR4_Val; /* 外部声明输出比较通道4计数周期变量*/

 

vu16  capture = 0; /* 当前捕获计数值局部变量 */

 

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

{

  //         GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_4)))

capture = TIM_GetCapture1(TIM2);/* 读出当前计数值 */

TIM_SetCompare1(TIM2, capture + CCR1_Val);/* 根据当前计数值更新输出捕获寄存器 */

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);//清除中断标志

}

else if......

 

通用定时器之PWM输出========================================================================================================

(此段代码并不充分,其基本功能是用一个定时器在4个口输出PWM信号,注意!通道必须与IO口相匹配)

 

vu16 CCR1_Val = 60000; /* 初始化输出比较通道1计数周期变量 */

vu16 CCR2_Val = 30000; /* 初始化输出比较通道2计数周期变量 */

vu16 CCR3_Val = 15000;   /* 初始化输出比较通道3计数周期变量 */

vu16 CCR4_Val = 7500; /* 初始化输出比较通道4计数周期变量 */

 

RCC配置:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /* 打开 TIM2 时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /* 打开 APB 总线上的 GPIOA,USART1 时钟 */

 

GPIO配置:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //与通道对应

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //第二功能推挽输出

 

void TIM_Configuration(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;

TIM_TimeBaseStructure.TIM_Period = 60000;  //   计数重载值为6000

TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频值为(0+ 1 = 1)

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //工作模式为 PWM 输出模式

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //使能比较匹配输出极性

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //向上计数模式

TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //得到的占空比分别为 100%, 50%, 25%, 12.5%

TIM_OC1Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

TIM_OC2Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

TIM_OC3Init(TIM2, &TIM_OCInitStructure);

TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

TIM_OC4Init(TIM2, &TIM_OCInitStructure);

/* 使能预装载寄存器 */

TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Enable);

TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Enable);

TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Enable);

TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM2, ENABLE); //注意!!这个要启动!

TIM_Cmd(TIM2 , ENABLE);/* 启动 TIM 计数 */

}

//不需要中断


关键字:STM32F103  初始化模板 引用地址:STM32F103官方初始化模板

上一篇:STM32F105的串口乱码问题
下一篇:STM32 UART/USART初始化时钟使能

推荐阅读最新更新时间:2024-03-16 16:10

STM32学习【2】STM32F103C8T6串口2USART2程序
STM32F103C8T6串口1(PA10/RXD1,PA9/TXD1)用来烧写程序,串口2(PA3/RXD2,PA2/TXD2)接串口模块与电脑串口助手通信。IO口PA1接LED+470R电阻+D3V3。 调试后,能正常运行的程序如下: #include stm32f10x.h #include stm32f10x_usart.h #define LED_ON GPIO_ResetBits(GPIOA ,GPIO_Pin_1) #define LED_OFF GPIO_SetBits(GPIOA ,GPIO_Pin_1) void GPIO_Config(void); void USART2_Config(vo
[单片机]
STM32学习【2】<font color='red'>STM32F103</font>C8T6串口2USART2程序
STM32F103使用SWD烧写错误提示的问题
今天使用STLINK和ULINK进行烧写,都无法成功,烧写模式为SWD! 错误提示为: flash timeout,reset the target and try it again Error: Flash Download failed - Cortex-M3 共2个错误 故网上搜索了下,得到以下解决方案: 1.对于“flash timeout,reset the target and try it again” 需在debug设置里,勾选Erase Full Chip Reset and Run program verify 2.对于 “Error: Flash Download failed - Cortex-M3 “
[单片机]
STM32f103的电阻触摸屏的五点校正算法
由于电阻式触摸屏就是一种传感器,它利用压力感应进行控制,将矩形区域中触摸点(X,Y)的物理位置转换为代表 X坐标和 Y 坐标的电压。这里先引入两个概念,物理坐标和逻辑坐标。物理坐标指触摸屏上点的实际位置,通常以液晶上点的个数来度量。逻辑坐标指这点被触摸时A/D 转换后的坐标值。如图1,我们假定液晶最左下角为坐标轴原点A ,在液晶上任取一点B (十字线交叉中心),B 在X 方向距离A 10 个点,在Y 方向距离A20 个点,则这点的物理坐标为(10,20)。如果我们触摸这一点时得到的X 向A/D 转换值为100,Y 向A/D 转换值为200,则这点的逻辑坐标为(100,200)。 常用的电阻式触摸屏矫正方法有两点校准法和三点校准法
[单片机]
<font color='red'>STM32f103</font>的电阻触摸屏的五点校正算法
stm32f103 学习笔记 —— 07 CAN通讯协议
1.报文种类 数据帧 :用于节点向外传送数据 遥控帧 :用于向远端节点请求数据 错误帧 :用于向远端节点通知校验错误,请求重新发送上一个数据 过载帧 :用于通知远端节点本节点尚未做好接受准备 帧间隔 :用于将数据帧及遥控帧与前面的帧分离开来 2.报文结构(以数据帧为例) 以一个显性位(逻辑0)开始,以7个连续的隐性位(逻辑1)结束 帧起始(Start Of Frame):只有一个数据位(显性电平,逻辑0) 仲裁段 :决定发送优先级(通过“线与”的方式,即同时出现显性和隐形电平时总线状态被置为显性);CAN控制器根据ID过滤报文 远程传输请求位(Remote Transmission Reques
[单片机]
<font color='red'>stm32f103</font> 学习笔记 —— 07 CAN通讯协议
STM32F103标准库开发---Uart串口通信实验---函数发送和中断接收
一、Uart串口通信----函数发送 1. Uart串口发送(标准库)函数—单字节发送 Uart串口发送函数在STM32F103标准库的 stm32f103x_usart.c 文件中,具体如下图所示: 具体函数如下: /** *@功能:通过USARTx外设传输单个字节数据 *@参数1:指定USART外设(USART1,USART2,USART3,USART4,USART5) *@参数2:要传输的数据(最多9位数据,由初始化配置决定) *@返回值:无 */ void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) { /* Check the parame
[单片机]
<font color='red'>STM32F103</font>标准库开发---Uart串口通信实验---函数发送和中断接收
STM32F103X 通用定时器2~5 的输入捕获边沿选择
在官方V3.5库帮助文档中提到有上升沿、下降沿、双边沿出发选择。如图1。 但是在手册中看到寄存器的那个位【3:2】为保留,故将双边沿的数据写入这个保留的寄存器中其实和设置为下降沿效果是相同的。如图2。 故在测量譬如脉冲频率、占空比时只能:1.在中断中不断改变触发边沿 或者 2.连接到定时器的两个通道 或者 3.连接同一个通道,但是将同一通道的信号输出给2路IC(这很像PWM输入模式)。如图3。 图一 图二 图三
[单片机]
<font color='red'>STM32F103</font>X 通用定时器2~5 的输入捕获边沿选择
STM32F103和STM32F107差别浅谈
两个系列的处理器都是以 stm32 为开头的,即这两个都是stm32芯片,是意法半导体为ARM Cortex-M3内核出的用于自动控制领域的微处理器。F107是互联型接口,且内部资源较多,F103是增强型(比F101强),相比F103,F107加入IEEE以太网接口,2个IIS音频接口(做音频解码用),全部64KByte的SRAM缓存。除此之外,两系列的芯片基本相同。 这两个芯片的开发方法和调用的库函数都是一样的,通过官方称他们为STM32f10X就知道了,引脚绝大部分也是兼容的。那么在使用中,如果开发产片偏向于以太网和IIS音频设备,建议选用F107系列产品,否则F103就可以了。
[单片机]
基于STM32F103C8T6+L298N通过PWM控制直流电机
01 前言 原来做的差速小车是基于Arduino控制的,感觉有些简单,也有些基础,Arduino方便简单的同时,可操作性感觉也少了很多,所以想将控制器换成STM32,然后将树莓派作为上位机,STM32作为下位机,通过树莓派和STM32进行通讯,实现对差速移动小车的控制,本人也是寒假期间初学STM32,也是奔着应用去的,所以对于STM32编程原理方面可能不太精通,这里偏重于记录应用层面的知识。 02 PWM调速原理 直流电机驱动是最简单的,给电机通上电就能转,根据电机的公式: 可知:当提高电压时,反电势升高,进而转速升高,电压与转速大致有如图所示的关系。 编辑 所以我们只要控制给电机通电的电压即可控制电机的转速,但是在实际
[单片机]
基于<font color='red'>STM32F103</font>C8T6+L298N通过PWM控制直流电机
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved