打印
[开发工具]

STM32系列之STM32打开Flash读保护后,无法使用jlink下载程序的...

[复制链接]
1869|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
598330983|  楼主 | 2016-5-23 19:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如果在程序中打开了Flash读保护:
FLASH_ReadOutProtection(ENABLE);
再次用jlink下载程序时会出错:


解决办法:


运行J-link stm32 unlock后即可解决。

沙发
598330983|  楼主 | 2016-5-23 19:41 | 只看该作者
STM32之呼吸灯
作为初学者,刚刚接触STM32,所以**有何不妥之处,敬请指出,一定会改。
听说呼吸灯是很久以前的事情了,那时候刚刚学习51单片机,没有单片机的基础。后来在网上看到了一个呼吸灯的电路图,甚是复杂,根本看不懂,无奈之下放弃了呼吸灯的制作。在接触了STM32后,发现呼吸灯还是比较容易实现的,而且不需要什么硬件知识就可以完成。于是开始尝试做呼吸灯了。

其实做呼吸灯还是有一些波折的,程序有各种版本,且由于刚刚学习STM32——看不懂程序,所以在了解了大概的思路后,便开始自己尝试写程序了。哈哈美图隔开。


下面进入今天的正题——呼吸灯。
首先我们应该了解呼吸灯的基本原理——关键是用STM32输出占空比可调的方波。
用到了STM32的PWM输出,我们就必须了解它。STM32是带有PWM输出功能的。我们以TIM3来实现PWM的输出。
关于TIM3大家可以查阅STM32的相关资料,在这里我不在详解。
由以上可知道我们必须让STM32输出PWM或者说输出方波,因此我们必须知道怎么让STM32输出PWM。
用STM32输出占空比可调的PWM制作呼吸灯的步骤:(自己感觉很重要)
① 配置系统时钟(RCC_Config)
② 配置GPIO口(TIM3_GPIO_Config)
③ 配置TIMER(TIM3_Mode_Config)
④ 写实现呼吸灯的主体程序
⑤ 进行呼吸灯的调试
现在我们来一步一步理解程序:
① 配置系统时钟(RCC_Config):
      
将TIM3和GPIO的时钟打开。
由以上可以看出:
                            TIM3挂载在APB1
                            GPIO挂载在APB2
② 配置GPIO口(TIM3_GPIO_Config):

这里新手一般都会很疑惑,尤其是自学者都不知道为什么要设置Pin,Mode,Speed等等。
还有人常常有疑问,再用某个功能之前我怎么知道都要设置哪些东西。其实大家可以看看学习STM32至关重要的资料——STM32固件库手册,便会有所了解。
③ 配置TIMER(TIM3_Mode_Config)
void TIM3_Mode_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//设置一个TIM_TimeBaseStructure结构体。
  TIM_OCInitTypeDef TIM_OCInitStructure;//设置一个TIM_OCInitStructure结构体。
  TIM_TimeBaseStructure.TIM_Period=1000-1;//个人理解就是计几个数。(由此可以得到PWM的周期)
  TIM_TimeBaseStructure.TIM_Prescaler=0;//设置用来作为 TIMx 时钟频率除数的预分频值。
  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分割。
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择了计数器模式。
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//将设置好的参数初始化。
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置TIM输出模式PWM1。
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//选择输出比较状态(?)
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//TIM 输出比较极性高。
  TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//设置了待装入捕获比较寄存器的脉冲值。
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);//将设定好的参数初始化给通道1。
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的预装载寄存器。
  TIM_OCInitStructure.TIM_Pulse=CCR2_Val;
  TIM_OC2Init(TIM3,&TIM_OCInitStructure);//通道2
  TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM3,ENABLE);//使能TIM3在 ARR 上的预装载寄存器。
  TIM_Cmd(TIM3,ENABLE);//使能TIM3的外设
}


使用特权

评论回复
板凳
598330983|  楼主 | 2016-5-23 19:42 | 只看该作者
④ 写实现呼吸灯的主体程序:


其实这就是主函数,任何情况下主函数是必须有的。这个呼吸灯实现的方法和网上的大神写的差很多,但是它实现了呼吸灯的逐渐明暗,自我感觉适合初学者学习呼吸灯以后大家把STM32学习的比较明白了后,就自然而然会写那些更加“高大上”的呼吸灯程序了。
为了方便自学初学的需要下面添加一些附件(芯片型号和整体程序)
① 芯片信号STM32F103RB,晶振用的是8M。
② 整体程序:
#include "stm32f10x.h"
u16 CCR1_Val=1000;
u16 CCR2_Val=0;
u8 a=0;
void Delay(__IO u32 nCount)
{
  while(nCount--);
}
void RCC_Config(void)
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
}
void TIM3_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;//设置一个GPIO_InitStructure结构体。
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//选择引脚6和7。
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择输出模式为复用推挽输出。
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置引脚最高输出速率为50MHz。
  GPIO_Init(GPIOA,&GPIO_InitStructure);//将设定好的参数初始化。
}
void TIM3_Mode_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//设置一个TIM_TimeBaseStructure结构体。
  TIM_OCInitTypeDef TIM_OCInitStructure;//设置一个TIM_OCInitStructure结构体。
  TIM_TimeBaseStructure.TIM_Period=1000-1;//个人理解就是计几个数。(由此可以得到PWM的周期)
  TIM_TimeBaseStructure.TIM_Prescaler=0;//设置用来作为 TIMx 时钟频率除数的预分频值。
  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分割。
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择了计数器模式。
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//将设置好的参数初始化。
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置TIM输出模式PWM1。
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//选择输出比较状态(?)
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//TIM 输出比较极性高。
  TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//设置了待装入捕获比较寄存器的脉冲值。
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);//将设定好的参数初始化给通道1。
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的预装载寄存器。
  TIM_OCInitStructure.TIM_Pulse=CCR2_Val;
  TIM_OC2Init(TIM3,&TIM_OCInitStructure);//通道2
  TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM3,ENABLE);//使能TIM3在 ARR 上的预装载寄存器。
  TIM_Cmd(TIM3,ENABLE);//使能TIM3的外设
}
int main(void)
{
    RCC_Config();
TIM3_GPIO_Config();
TIM3_Mode_Config();
while(1)
{
     if(CCR1_Val>0&&a<40&&CCR2_Val<1000)
     {
       CCR1_Val-=25;
       CCR2_Val+=25;
       TIM3_Mode_Config();
       a++;
       Delay(0XF424);
     }
    else
    {
       CCR1_Val+=25;
       CCR2_Val-=25;
       TIM3_Mode_Config();
       Delay(0XF424);
       a++;
    if(a==80)a=0;
     }
}
}


使用特权

评论回复
地板
捉虫天师| | 2016-5-23 20:28 | 只看该作者
从来都没有遇到过这种坑爹的事情。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

249

主题

5397

帖子

22

粉丝