1.24学习计划

1、任务计划

    (1)在我们第一个课题的基础上。改写定时器中断的内容,做到每隔1s闪烁,再每隔2s闪烁,再隔3s闪烁,然后一直这样循环,其他的LED还有示波器都和原来的要求一样。
    (2)看NVIC中断优先级管理的教学视频;
    (3)看PWM输出实验的视频

2、计划完成度

    (1)今天一天只是做第一个任务,就调试了一天呢~对着一块32的板子,已经改了无数遍程序了。每改一遍程序,调的没有错误了,就开始下载,下载了再观察呢。我是先设置了LED1为1s闪烁一次,然后一遍一遍的对照着LED0开始计算LED1是不是已经达到了循环的要求。

    [1]每隔一秒闪烁 ,则周期为2;每隔2s闪烁则周期为4;每隔3s闪烁,周期为6;所以整体的周期就是2+4+6=12s。

  [2]我先是用flag作为标记,每当判断进入一次中断成立,if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)flag就++。因为周期为12,我就直接设置flag=flag%12。

    [3]刚开始写条件判断的时候,我是用的switch语句:

switch(flag)
{ 
  case1: LED0=!LED1,SIH0=!SHI0;
  case3: LED0=!LED1,SIH0=!SHI0;
  case7: LED0=!LED1,SIH0=!SHI0;
  defult: ;    
}
 TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

    结果灯每秒都会闪烁一次。

    [4]我刚开始开始设置以2,以3为周期的时候,设置计数时钟不知弄哪个函数,我就改了if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET),把其中的TIM3改为2*TIM3,3*TIM3,结果不符合STM32的使用规则,不能实现周期的改动。

    [5]后来学姐跟我讲,其实她是想让我用STM32的库函数TIM_SetAutoreload(TIM3,20000)来设置 TIMx 自动重装载寄存器值,这样当flag=3的时候,就可以实现以2为周期的循环了。

    [6]我就和之前的switch语句结合了一下

switch(flag)
{
  //case1: LED0=!LED1,SIH0=!SHI0;
  case3:TIM_SetAutoreload(TIM3,2000);
  case7:TIM_SetAutoreload(TIM3,3000);
  defult: ;      
}
  LED0=!LED1;
  SIH0=!SHI0;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    

大体思路是有的,但是每次调整这个条件语句的条件语句和执行语句,以及清除标志位的时候,基本上都是每秒循环一次,还有可能就是所有的灯都灭掉,连我设置的指示灯都不会亮,再就是亮了指示灯但是中断的灯一个都不亮,还有可能是中断的灯会亮会闪但是指示灯不会亮,但还是达不到要求的。
   [7]因为执行语句不是一句就好了的,虽然switch语句很简单,但是我想试试if了,毕竟if语句分开了三种情况,可以更明确一些嘛
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
  {
     flag=flag++;
     flag=flag%12;
      {		
        if(flag==1)
	  {
	    LED0=!LED0;
	    SHI0=!SHI0;
            //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);		     }
        else if(flag==3)
          {
             TIM_SetAutoreload(TIM3,20000);		      LED0=!LED0;
	     SHI0=!SHI0;
	     //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	  	  }
	 else if(flag==7)
	   {
              TIM_SetAutoreload(TIM3,30000);
              LED0=!LED0;
	      SHI0=!SHI0;
	      //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
           } 
           TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
      }
}
    这样改动了之后出现了更多的循环情况。在我每次在这个基础上做改动的时候,要么全是1s的循环,要么就是3s的循环,还有可能就是所有的灯都灭掉,连我设置的指示灯都不会亮,再就是亮了指示灯但是中断的灯一个都不亮,还有可能是中断的灯会亮会闪但是指示灯不会亮,最好的情况就是两个灯能一起的亮1s的循环和3s的循环了。但是还没有达到要求。

   [8]我觉得可能是执行完一趟if之后,flag++,无法构成个循环,它本身跳不出来。我就试了试for循环
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
		{
	    for (flag=1;flag<=12;flag++)
			{
    		if(flag==1)
			   {
			    LED0=!LED0;
			    SHI0=!SHI0;
			   //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
		     }
  	    else if(flag==3)
		     {
			      TIM_SetAutoreload(TIM3,20000);
			      LED0=!LED0;
			      SHI0=!SHI0;
		 	      //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	  	  }
	     	else if(flag==7)
	     	{
	     		TIM_SetAutoreload(TIM3,30000);
		    	LED0=!LED0;
	      	SHI0=!SHI0;
	      	//TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
		    } 
				flag=flag%12;
		  	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
            }
	}
    但是这样最好也是做到3s的循环呢~

   [9]想到前段时间,实验室有小伙伴写外部中断的实验,来控制流水灯的三个流速。一共有快中慢三种速度,每按一下键就可以改变一次。虽然他们是写的51的吧,系统不一样,但是还可以找找思路的。我看了他们控制速度的这部分程序。
  可以总结为,分了三部分来写的。首先一个delay的函数来控制相应的键按下时是什么速度,再一个实参的函数,判断每次是按下了哪一种的键,最后在main函数中调用。
     显然系统不一样,写出来的程序差距还是很大的。
    首先我们不能用delay函数,因为这个已经在SYSTEM中调用了。当然这都是小事,改改函数名就好了。
     第二我先写了51中的“delay

void TIM3_IRQHandler(int i)  
{
	if(i==1) 
	{
		LED0=!LED0;
	  SHI0=!SHI0;
    //TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	};
	if(i==3) 
	{
		TIM_SetAutoreload(TIM3,20000);
		LED0=!LED0;
	  SHI0=!SHI0;
//	  TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	};
	if(i==7) 
	{
		TIM_SetAutoreload(TIM3,20000);
		LED0=!LED0;
	  SHI0=!SHI0;
//	  TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	};
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
     

   但是当我用51的方法写实参的函数的时候,程序就会报错呢~

 

void spee()
{
	int i;
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
		{
			TIM3_IRQHandler_dat++;
			TIM3_IRQHandler_dat=TIM3_IRQHandler_dat%12
		}
		return TIM3_IRQHandler_dat;
}

    

   凡是含有TIM3_IRQHandler_dat的语句都会报错。

  2)调了一天实在是调不出来了,今天我就不打算在这上边浪费时间了,我就看NVIC中断优先级管理的教学视频了。

  之前的时候,写外部中断和定时器中断的时候,我倒是都都用过NVIC了,对于它的功能设置可以说是比较熟悉的了。今天就进一步的了解一下NVIC中断优先级分组以及配置。

  第一部分是NVIC中断优先级分组。

   [1]*CM4内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32F4并没有使用CM4内核的全部东西,而是只用了它的一部分。

   *STM32F40xx/STM32F41xx总共有92个中断

   *STM32F40xx/STM32F41xx92个中断里面,包括10个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级,而我们常用的就是这82个可屏蔽中断。

   [2]中断优先级管理方法:对STM32中断分组,组0-4。同时,对每个中断设置抢占优先级和响应优先级。

   *分组配置是在SCB->AIRCR寄存器的bit10~8来定义的

    [3]抢占优先级和响应优先级的区别:

     *高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
     *抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
     *抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
     *如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

     [4]特别要注意的是:一般情况下,系统代码执行过程中,只设置一次中断优先级分组。

[5]中断优先级分组函数: 

   voidNVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

  第二部分是讲的中断优先级配置。这个在之前的程序中就有写过,算是比较熟悉的了。今天也是主要的学了几个中断设置相关寄存器

   [1]中断优先级控制的寄存器组 IP[240];

   voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct);具体的用法,在前两天写定时器中断的时候应该有提到的。

   [2]中断使能寄存器组:ISER[8]

   [3]中断失能寄存器组:ICER[8] 特点及配置同[2]
   [4]中断挂起控制寄存器组:ISPR[8]
   [6]中断激活标志位寄存器组:IABR[8]

   32位寄存器,每个位控制一个中断的使能。STM32F40x只有82个可屏蔽中断,所以只使用了其中的ISER[0]~ISER[2]

  ISER[0]bit0~bit31分别对应中断0~31ISER[1]bit0~27对应中断32~63ISER[2]bit0~17对应中断64~81

   [5]中断解挂控制寄存器组:ICPR[8]

   作用:只读,通过它可以知道当前在执行的中断是哪一个.如果对应位为1,说明该中断正在执行

  (2)PWM输出的视频没有看~


   
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值