stm32学习
stm32基本情况
下载方式
- 关于比较详细的下载过程有链接
- isp下载
- boot0=1,boot1=0,用串口线和Flash Loader Demonstrator软件即可下载,网上有相应的教程
- jtag下载
- 在debugger里的cortex M3的settings中最好选择JTAG方式而非SW模式
- 不能选仿真模式
- jlink仿真器中有一个跳线帽,如果插电之后芯片不亮,看是否是跳线帽没有选到3.3V上去。
GPIO配置
配置的基本代码
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PF端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC GPIO_SetBits(GPIOC,GPIO_Pin_13); //初始化设置为0
管脚、输出方式可以修改
串口通信
- 可以用printf实现,与C语言中相同,只是需要重新一下fputc和fgetc函数,具体有链接
- 该方法没有尝试,直接使用例程文件的
PWM配置
TIM
- TIM可以产生PWM波,TIM1为高级定时器,TIM2~4为普通定时器
产生PWM波的步骤如下
TIMER输出PWM实现步骤:1. 设置RCC时钟; 2. 设置GPIO时钟; 3. 设置TIMx定时器的相关寄存器; 4. 设置TIMx定时器的PWM相关寄存器。
TIM1最后需要加上
TIM_CtrlPWMOutputs(TIM1, ENABLE);
源码
说明:TIM2 两通道PWM波产生
/* * 函数名:TIM2_GPIO_Config * 描述 :配置TIM2复用输出PWM时用到的I/O * 输入 :无 * 输出 :无 * 调用 :内部调用 */ void TIM2_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* TIM2 clock enable */ //PCLK1经过2倍频后作为TIM2的时钟源等于36MHz RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* GPIOA and GPIOB clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /*GPIOA Configuration: TIM2 channel 1 and 2 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } void TIM2_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* PWM信号电平跳变值 */ u16 CCR1_Val = 5000; u16 CCR2_Val = 5000; /* ----------------------------------------------------------------------- TIM2 Configuration: generate 4 PWM signals with 4 different duty cycles: TIM2CLK = 36 MHz, Prescaler = 0x0, TIM2 counter clock = 36 MHz TIM2 ARR Register = 999 => TIM2 Frequency = TIM2 counter clock/(ARR + 1) TIM2 Frequency = 36 KHz. TIM2 Channel1 duty cycle = (TIM2_CCR1/ TIM2_ARR)* 100 = 50% TIM2 Channel2 duty cycle = (TIM2_CCR2/ TIM2_ARR)* 100 = 37.5% TIM2 Channel3 duty cycle = (TIM2_CCR3/ TIM2_ARR)* 100 = 25% TIM2 Channel4 duty cycle = (TIM2_CCR4/ TIM2_ARR)* 100 = 12.5% ----------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 9999; //当定时器从0计数到9999,即为10000次,为一个定时周期 TIM_TimeBaseStructure.TIM_Prescaler = 144; //设置预分频:不预分频,即为36MHz TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分频系数:不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置跳变值,当计数器计数到这个值时,电平发生跳变 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平 TIM_OC1Init(TIM2, &TIM_OCInitStructure); //使能通道1 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //设置通道2的电平跳变值,输出另外一个占空比的PWM TIM_OC2Init(TIM2, &TIM_OCInitStructure); //使能通道2 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); // 使能TIM2重载寄存器ARR /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); //使能定时器2 } /* * 函数名:TIM2_Mode_Config * 描述 :TIM2 输出PWM信号初始化,只要调用这个函数 * TIM2的两个通道就会有PWM信号输出,此时设置的PWM波占空比为50% * 输入 :无 * 输出 :无 * 调用 :外部调用 */ void TIM2_PWM_Init(void) { TIM2_GPIO_Config(); TIM2_Mode_Config(); } //TIM_CtrlPWMOutputs(TIM1, ENABLE); /* 改变PWM波的占空比 * 在此只能改变1、2通道的占空比 * 初始化之后,朱旭调用此函数即可改变占空比 */ void TIM2_changeDutyOf_1_2(int value1 , int value2) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = value1; //设置跳变值,当计数器计数到这个值时,电平发生跳变 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平 TIM_OC1Init(TIM2, &TIM_OCInitStructure); //使能通道1 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = value2; //设置通道2的电平跳变值,输出另外一个占空比的PWM TIM_OC2Init(TIM2, &TIM_OCInitStructure); //使能通道2 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); // 使能TIM2重载寄存器ARR /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); //使能定时器2 }