循迹小车驱动

1.PWM

2.USART

3.GPIO

4.ADC

技术部分

EXIT

HC_SR04 中断定时器
EXIT 外部中断 属于外设 可监测GPIO口的电平信号
触发方式 上升 下降 双边 PB7与PA7不能同时使用中断 与AFIO有关中断引脚选择器只会选择其中一个
中断 暂停当前正在运行的程序。转而处理中断程序,处理完成后返回原来的位置继续经行
中断源 电平跳变 接受到数据 到达预定时间
中断有自己的优先级 抢占优先级>响应优先级,同级优先级高的先执行
中断可以嵌套
中断触发后响应方式 中断方式/事件响应
NVIC 管理中断 设优先级 NVIC可设置高N位抢占优先级 低4-N位的响应优先级
驱动 外部中断配置流程
1.开启时钟(GPIO AFIO就可以了EXIT一直开启 NVIC属于内部设备)
2.GPIO 输入模式
3.配置AFIO 选择GPIO 连接到 EXIT
4.配置中断边沿触发方式 上升下降 双边,选择响应方式 中断响应 / 事件响应
5.配置NVIC 进入CPU
6.中断函数(无参无返回值 名字固定 在启动文件中找)

TIM

TIM定时器
定时器中断 配置流程
1.开启RCC时钟
2.选择实际单元时钟源
3.配置时基单元
4.配置输出中断控制,允许中断更新到NVIC(计数器达到ARR的值 会出现一个中断)
5.配置NVIC
6.运行计数器

得到高电平的维持时间(TIM输入捕获 IC)
1.RCC开启时钟
2.GPIO初始化,设置为输入模式
3配置时基单元
4.配置输入捕获单元
5.选择从模式的触发源
6.触发后的操作
#include "stm32f10x.h"                  // Device header
extern uint16_t NUM;
int flag = 0,times;

void IC_Init(void)
{
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//输入模式不需要设置速率
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource6);//选择中断的GPIOx 和线路 数字要与输入的GPIO口的数字对应
	
	EXTI_InitTypeDef InitStructure;
	InitStructure.EXTI_Line = EXTI_Line6; //与GPIO口的数字对应
	InitStructure.EXTI_LineCmd = ENABLE;//开启中断
	InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断响应事件 为中断事件
	InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//边沿触发方式
	EXTI_Init(&InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先级分配
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel =   EXTI9_5_IRQn;//配置NVIC通道
	NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	TIM_InternalClockConfig(TIM3);//选择内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//TIM_CKD_DIVx 代表x 72M要被分为多少个
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 1000-1;//TIM_Prescaler装1000次 与CNT CCR同级
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1;//每产生义一个tips加1,加到72归零,TIM_Period+1
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//高级定时器使用 这里给0
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//时钟触发中断
	
	NVIC_InitTypeDef NVIC_InitStructure2;
	NVIC_InitStructure2.NVIC_IRQChannel = TIM3_IRQn;//来自TIM3的中断
	NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1
	NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 1;//响应优先级1
	NVIC_Init(&NVIC_InitStructure2);
	/***********IC********************************/
	
	
}


void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
	{
		NUM++;
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	}
}
void  EXTI9_5_IRQHandler(void)
{
	if(SET == EXTI_GetITStatus(EXTI_Line6))
	{
		if(flag == 0)
		{
			NUM=0;flag=1;//0为第一个双边沿,1为第二个双边沿
			TIM_SetCounter(TIM3,0);//设置TIM3的CNT为0
			TIM_Cmd(TIM3,ENABLE);//开始计时
		}
		else
		{
			TIM_Cmd(TIM3,DISABLE);
			flag = 0;
			times = NUM*1000 +TIM_GetCounter(TIM3);
		}
		EXTI_ClearITPendingBit(EXTI_Line6);//清空中断标志位
	}
}
posted @ 2024-02-24 16:52  喜欢嵌入式编程的吗喽  阅读(62)  评论(0)    收藏  举报