STM32F072RB 实作笔记(五)- 计时器加上中断EXTI_IRQHandler(一)

中断技巧增加平行处理的能力

写单晶片程式有意思的地方除了那种“掌控”的感觉外,接着就是有那种“处理复杂事件的能力”!
基本的程式是循序进行,时间就会被耽搁。若是想要把程式并行处理,那么,“中断”插入的方法是个好帮手,这个时候就要能同时处理不同的事件。我常常比喻电脑程式就像厨房;火炉是CPU,餐盘容器是暂存器,食材就是资料;这个做菜的程序容易理解,只是这时间不容易拿捏,所以,单晶片的内部计时器就是一个好帮手。
这个M0 的计时器和中断的写法,比51族的mpu方便多了。

在这里插入图片描述
在这里插入图片描述

在M0 的C 语言里,使用中断功能要写下几个功能:

  1. 设定中断来源和 开启中断程式的向量指标
  2. 编写中断后要执行的服务程式
    a.是否接受巢式中断
    b.主程式转移进来的资料
    c.要转移出去的结果
  3. 把中断处理的结果(变数)移交回主程式。
  4. 下一次中断的开启

设定中断来源和 开启中断程式的向量指标

一个用timer 开启的中断

void Config_Timer2(void)
{
	RCC->APB1ENR |= 0x1ul;
	TIM2->PSC =47;
	TIM2->ARR = 1000-1;
	TIM2->CNT =0;
	TIM2->CR1 |= 0x1ul <<7 | 0x1ul;
	TIM2->DIER |= 0x1ul;
	
	NVIC_SetPriority(TIM2_IRQn,3);
	NVIC_EnableIRQ(TIM2_IRQn);
}

//---------------------
void TIM2_IRQHandler (void)
{
	TIM2_Ticks++;
	TIM2->SR &= ~0x1ul;
}

这是一个 UART 用的中断

void Config_uart1(void) // for BlueTooth
{
	RCC->APB2ENR |= 0x1ul <<14;
	USART1->BRR = 48000000/115200;
	USART1->CR3 |= 0x1ul <<12;
	
	USART1->CR1 |= 0x1ul << 5 | 0x1ul<<2 | 0x1ul;
	USART1->ICR |=  0x1ul <<6 ;
	USART1->CR1 |= 0x1ul << 6 | 0x1ul<< 3 ;
	
	NVIC_SetPriority(USART1_IRQn,3);
	NVIC_EnableIRQ(USART1_IRQn);
}

void USART1_IRQHandler(void) //for BlueTooth
{   };

下面的程式片段是设定了一个中断程式的应用内容:

//--------------------------------
void setIRQPin(uint8_t y,uint8_t x)  // to set the IRQ_pin of STM32 
{
	SYSCFG->EXTICR[x/4] &= ~(0xful <<((x%4)*4));
	SYSCFG->EXTICR[x/4] |= (y <<((x%4)*4));
} //******这个副程式很有用,很方便

//***** need to set PA.0.1.9.10
// PA0,PA1 -->EXTICR[0] 0.1
// PA9,PA10 -->EXTICR[2] 2.3
void Config_PA01PA910(void)
{
	RCC->AHBENR |= 0x1ul << 17;
	GPIOA->MODER &=~(0x3ul| (0x3ul << 1*2)|(0x3ul << 9*2)|(0x3ul << 10*2));

	RCC->APB2ENR |= 0x1ul;
//	SYSCFG->EXTICR[0] &= ~(0xful | 0xful << 1*4);
//	SYSCFG->EXTICR[2] &= ~((0xful<< 2*4)| (0xful << 3*4));
	setIRQPin(0,0);       //PA.0
	setIRQPin(0,1);       //PA.1
	setIRQPin(0,9);       //PA.9
	setIRQPin(0,10);       //PA.10
	
	EXTI->FTSR |= 0x1ul | 0x1ul<< 1;
	EXTI->IMR |= 0x1ul | 0x1ul<< 1;
	EXTI->PR |= 0x1ul | 0x1ul<< 1;

	EXTI->FTSR |= 0x1ul<<9 | 0x1ul<< 10;
	EXTI->IMR |= 0x1ul <<9 | 0x1ul<< 10;
	EXTI->PR |= 0x1ul<<9 | 0x1ul<< 10;

	NVIC_SetPriority(EXTI0_1_IRQn,3);
	NVIC_EnableIRQ(EXTI0_1_IRQn);
}
//-----------------------------------------
void EXTI0_1_IRQHandler(void)
{
  for (int i =0; i<1000; i++)
			__NOP;
	  printf("IRQ 5 interrup. \n\r");
	  Delay(50);
		NVIC_SetPendingIRQ(EXTI2_3_IRQn);
	  printf("IRQ 5 end. \n\r");  
}

我们翻看 F072 Reference manual : page 217,218,219 的表格,可以看到所有中断的名称,使用对象和向量的地址。如下面的三张图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最左一行是编号栏,其中有 7 个不给编号,那是系统用的。第四栏位 acronym(缩写)说明了这些中断都被规划给那些功能使用,譬如:WWDG(看门狗),EXTI(擴展中斷和事件控制,就是使用者特殊规划用的),TSC(触摸控制),DMA,Timer,I2C,SPI,UART,…,USB 等。

下图是Reference Manual上的使用范例:
在这里插入图片描述
由于这些副程式的英文字数多,Keil 都有参考编辑让你选,打错字的几率比较少。
下面这三种副程式必须要形影不离的一起使用。

    NVIC_SetPriority(USART1_IRQn,3);
	NVIC_EnableIRQ(USART1_IRQn);
	void USART1_IRQHandler(void) { 自定义执行内容 };

为了避免再发生打错字,我们从内部现有的范例 copy 这些名称 ,而这里的这个位置可以找到正确的内部定义,(在startup_stm32f072xb.s(Startup) 这个档案里)
在这里插入图片描述
在这里插入图片描述
计时器的部分,写在下一篇!(完)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值