STM32F407 芯片的学习 day04 移植的系统文件 时间函数 -----delay_us(), 中断的知识, 外部中断的方法 systick定时器的知识

1.延时函数移植

        1.把文件放入工程文件夹的system 里面 

     


  2.添加c文件 ;

     

 


 3.添加头文件

 


        4..在主文件当中添加 头文件  #include "delay.h"
        调用初始化函数  delay_init(168);
        调用延时函数:delay_us(); delay_ms();

代码:

#include "stm32f4xx.h"
#include 	"delay.h"


int main(void)
{
	delay_init(168);//时间初始化
		
	while(1)//防止程序跑飞
	{
			delay_us(1);//微妙
			delay_ms(1);//毫秒
	
	}
}




	

        5.还有一些 操作 (时间才能准确)   

           进去  stm32f4xx.h     搜寻  HSE_VALUE  改变值    (搜索  CTRL + F)


        

 


2. 中断的知识

抢占优先级 & 响应优先级区别:

1.高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

2.抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

3.抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

4.如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;


中断优先级分组函数

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 在主函数中只调用一次 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分为两个组

注意:

一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

 

 


外部中断:

STM32F4的每个IO都可以作为外部中断输入。  STM32F4的中断控制器支持22个外部中断/事件请求:

EXTI线0~15:对应外部IO口的输入中断。

EXTI线16:连接到PVD输出。

EXTI线17:连接到RTC闹钟事件。

EXTI线18:连接到USB OTG FS唤醒事件。

EXTI线19:连接到以太网唤醒事件。

EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。

EXTI线21:连接到RTC入侵和时间戳事件。

EXTI线22:连接到RTC唤醒事件。


 

 代码:

 
 
 
void EXTI0_IRQHandler(void)//中断响应函数
{
	delay_ms(10);	
	if(WK_UP==1)	 
	{
		BEEP=!BEEP; 
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line0); 
}	
 
void EXTI2_IRQHandler(void)//中断响应函数
{
	delay_ms(10);	
	if(KEY2==0)	  
	{				 
   LED0=!LED0; 
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line2);
 
void EXTI3_IRQHandler(void)//中断响应函数
{
	delay_ms(10);	
	if(KEY1==0)	 
	{
		LED1=!LED1;
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line3);   
}
 
void EXTI4_IRQHandler(void)//中断响应函数
{
	delay_ms(10);	
	if(KEY0==0)	 
	{				 
		LED0=!LED0;	
		LED1=!LED1;	
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line4); 
}
	   
 
void EXTIX_Init(void)//外部中断初始化
{
	NVIC_InitTypeDef   NVIC_InitStructure;//配置总中断
	EXTI_InitTypeDef   EXTI_InitStructure;//外部中断初始化函数
	
	KEY_Init();//LED 灯的初始化
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//配置时钟,配置中断功能时钟
	
     //配置外部中断  // 引脚复用映射,配置引脚功能  PE2 3 4 配置成外部中断功能
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//这个是 PA 0
	
 
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;//0 号 引脚 - 0号线
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //下降沿触发中断功能
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//外部中断使能
  EXTI_Init(&EXTI_InitStructure);//中断初始化函数 初始化配置
	
  EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line4;  PE2 3 4
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //下降沿触发中断功能
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//外部中断使能
  EXTI_Init(&EXTI_InitStructure);//中断初始化函数 初始化配置
 

    //在总中断配置中选择 外部中断0 号引脚   
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能
  NVIC_Init(&NVIC_InitStructure);//初始化
	
    //在总中断配置中选择 外部中断2 号引脚   
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能
  NVIC_Init(&NVIC_InitStructure);
	
	//在总中断配置中选择 外部中断3 号引脚   
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能
  NVIC_Init(&NVIC_InitStructure);
	
	//在总中断配置中选择 外部中断4 号引脚   
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能
  NVIC_Init(&NVIC_InitStructure);
	   
}
 
 
 
 
 
 
 
 
 
 
 
 

        

 


 3.systick 定时器

        1.什么是SysTick

  1,系统节拍时钟(SysTick)是一个简单的系统时钟节拍计数器。通常用作嵌入式操作系统(uc/os-iii,Android)的系统节拍定时。

2.复杂的嵌入式系统设计中会考虑操作系(uc/os,FreeRTOS),普通的单片机程序一个主程序就能完成任务。当单片机程序设计中不需要操作系统时,SysTick通常作为普通定时器来使用。既简单,又方便。

3.systick是内核的一部分,不是外设。


      1.  Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

2. SysTick定时器被捆绑在NVIC中,用于产生SYSTICK中断(中断号:15)。

3. Systick中断的优先级也可以设置。



 


 

 接下来我们看SysTick_Config函数什么时候返回1,什么时候返回0;
SysTick_Config函数返回0后就不会在执行if语句,执行下一条语句关闭定时器,然后执行一次定时器的回调函数SysTick_Handler();

初始化系统定时器,1S 内核触发 1000 次中断,说白了定时 1ms,能够成功

SysTick_Config(SystemCoreClock/1000);

初始化系统定时器,1S 内核触发 10 次中断,说白了定时 100ms,现象失败

SysTick_Config(SystemCoreClock/10);

初始化系统定时器,1S 内核触发 11 次中断,说白了定时 90.90ms,能够成功

SysTick_Config(SystemCoreClock/11);

总结:填写中断频率值不能小于11,否则定时时间不准确。
 

看不懂的列子:

//使用前,请先初始化:
//SysTick_Init();


static __IO uint32_t TimingDelay;//定义一个定时器
void Delay(__IO uint32_t nTime)//延时函数
{ 
   TimingDelay = nTime;
   while(TimingDelay != 0);
}
void SysTick_Handler(void)//在定时的时候自动运行这个代码   中断函数
{
    if (TimingDelay != 0x00) //定时的数 不等于 0  就一直减
     { 
       TimingDelay--;
     }
}
 int main(void)
 { 
    //中断函数的执行时间   1 ms(SystemCoreClock / 1000)
    if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK,中断时间间隔1ms  初始化systick,时钟为HCLK,  并开启中断

     {
     while (1);
     }
    //上面是开启函数

    while(1)
     { 
            Delay(200);//利用 定时器 200ms
   
     }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要了解MS5873-30BA是一款数字压力传感器,可以测量气体或液体的压力,并输出数字信号。它使用I2C接口来与微控制器通信。 以下是一个简单的STM32F407芯片MS5873-30BA驱动代码示例: ```c #include "stm32f4xx.h" #include "i2c.h" #define MS5873_ADDR 0xEC //MS5873-30BA的I2C地址 uint8_t ms5873_data[4]; //存储读取的数据 void MS5873_Init(void) { I2C_Init(); //初始化I2C接口 } void MS5873_Read_Pressure(void) { uint32_t pressure; //向MS5873-30BA发送读取压力数据的命令 I2C_Start(); I2C_SendByte(MS5873_ADDR); I2C_SendByte(0x48); I2C_Stop(); //等待MS5873-30BA处理完数据 delay_ms(10); //读取压力数据 I2C_Start(); I2C_SendByte(MS5873_ADDR | 0x01); ms5873_data[0] = I2C_ReceiveByte(); ms5873_data[1] = I2C_ReceiveByte(); ms5873_data[2] = I2C_ReceiveByte(); ms5873_data[3] = I2C_ReceiveByte(); I2C_Stop(); //将读取到的数据转换成压力值 pressure = ((uint32_t)ms5873_data[0] << 16) | ((uint32_t)ms5873_data[1] << 8) | (uint32_t)ms5873_data[2]; pressure = pressure >> 6; //输出压力值 printf("Pressure: %d Pa\r\n", pressure); } ``` 以上代码假设已经实现了I2C接口的初始化和读写函数。在`MS5873_Init()`函数中进行初始化,在`MS5873_Read_Pressure()`函数中向MS5873-30BA发送读取压力数据的命令,等待一段时间后读取数据并将其转换成压力值。最后,输出压力值。 需要注意的是,这只是一个简单的示例代码,实际使用中还需要根据具体的需求进行修改和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值