STM32红外寻迹小车(寄存器版)
最近学习了STM32,想通过制作一辆小车来加深对STM32的理解,在平时学习时经常用正点原子提供的源代码稍加该装就行,但是正点原子没有提供关于红外寻迹模板的相关程序。尽管网上很多关于STM32的红外寻迹的资料和源代码,但是几乎没有寄存器版本的源代码。有些博主有寄存器版的程序源码但是得花钱才能下载。那么今天我就分享一下制作寻迹小车的经验和程序源码。
一、红外寻迹小车原理
循迹模块我用的是红外传感器。黑线的检测原理是红外发射管发射光线到路面,红外光遇到白底则被反射,接收管接收到反射光,经施密特触发器整形后输出低电平;当红外光遇到黑线时则被吸收,接收管没有接收到反射光,经施密特触发器整形后输出高电平。简单的说就是当红外寻迹模板遇见黑线时会产生一个高电平,遇见白线时会返回一个低电平。所以根据原理设计思路为当左侧红外传感器遇见黑线时左拐,右边红外传感器遇见黑线时右拐。这样就可以完成
寻迹 | 黑线寻迹 | 白线寻迹 |
---|---|---|
原理 | 左侧红外传感器遇见黑线时左拐,右边红外传感器遇见黑线时右拐。 | 当左侧红外传感器遇见黑线时右拐,右侧红外传感器遇见黑线时左拐。 |
二、寻迹小车设计注意事项
(1)因为硬件条件有限,反应速度不是很快会有一定的误差,所以小车的速度要尽量慢下来,从而弥补硬件的不足让小车有足够的反应时间。
(2)在设置两个红外传感器的IO口模式时要设置为浮空输入,这样才能通过程序读取IO口的状态来判断。
(3)在测试小车时尽量在光线较暗的条件下来测试小车,避免光线过亮影响测试。
(4)红外寻迹模块的OUT不能接在有上拉电阻的IO口。
三、寻迹小车程序
1.新建工程在工程文件下新建MOTER、TIMER、XUNJI这3个文件夹,然后在各自文件夹下建立相关文件小写的.c和.h文件。
2.timer.c的程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "timer.h" void TIM3_Int_Init(u16 arr,u16 psc)//初识化定时器3 { RCC->APB1ENR|=1<<1; //TIM3时钟使能 TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟 TIM3->DIER|=1<<0; //允许更新中断 TIM3->CR1|=0x01; //使能定时器3 MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2 } void TIM3_PWM_Init(u16 arr,u16 psc) { //此部分需手动修改IO口设置 RCC->APB1ENR|=1<<1; //TIM3时钟使能 RCC->APB2ENR|=1<<3; //使能PORTB时钟 RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOB->CRL&=0XFFFFFFF0; //PB0输出 GPIOB->CRL|=0X0000000B; //复用功能输出 GPIOA->CRL&=0XF0FFFFFF; //PA6输出 GPIOA->CRL|=0X0B000000; //复用输出 TIM3->ARR=arr; //设定计数器自动重装值 TIM3->PSC=psc; //预分频器不分频 TIM3->CCMR1|=6<<4; //CH1 PWM2模式 TIM3->CCMR1|=1<<3; //CH1预装载使能 TIM3->CCMR2|=6<<4; //CH3预装载使能 TIM3->CCMR2|=1<<3; //CH3输出使能 TIM3->CCER|=1<<0; //OC1 输出使能 TIM3->CCER|=1<<8; TIM3->CR1=0x0080; //ARPE使能 TIM3->CR1|=0x01; //使能定时器3 STBY=1; }
timer.h代码如下:
1
2
3
4
5
6
7
8
9
10#ifndef __TIMER_H #define __TIMER_H #include "sys.h" #define left TIM3->CCR1 #define right TIM3->CCR3 void TIM3_Int_Init(u16 arr,u16 psc); void TIM3_PWM_Init(u16 arr,u16 psc); #endif
moter.c代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34RCC->APB2ENR|=1<<2; //使能PORTA时钟 RCC->APB2ENR|=1<<3; //使能PORTB时钟 RCC->APB2ENR|=1<<4; //使能PORTC时钟 GPIOA->CRL&=0XFF0FFFFF; GPIOA->CRL|=0X00300000; GPIOA->ODR|=1<<5; GPIOA->CRL&=0X0FFFFFFF; GPIOA->CRL|=0X30000000; GPIOA->ODR|=1<<7; GPIOB->CRL&=0XFFFFFF0F; GPIOB->CRL|=0X00000030; GPIOB->ODR|=1<<1; GPIOB->CRL&=0XFFFFF0FF; GPIOB->CRL|=0X00000300; GPIOB->ODR|=1<<2; GPIOB->CRL&=0XFFFF0FFF; GPIOB->CRL|=0X00003000; GPIOB->ODR|=1<<3; GPIOB->CRL&=0XFFF0FFFF; GPIOB->CRL|=0X00030000; GPIOB->ODR|=1<<4; GPIOC->CRL&=0XFFF0FFFF; GPIOC->CRL|=0X00030000; GPIOC->ODR|=1<<4; GPIOC->CRL&=0XFF0FFFFF; GPIOC->CRL|=0X00300000; GPIOC->ODR|=1<<5;
moter.h代码如下:
1
2
3
4
5
6
7
8
9
10
11
12#ifndef __MOTER_H #define __MOTER_H #include "sys.h" //电机端口定义(PWMA PB0 PWMB PA6) #define AIN2 PBout(1) #define AIN1 PBout(2) #define STBY PBout(3) #define BIN2 PCout(5) #define BIN1 PCout(4) void MOTER_Init(void); //初始化 #endif
xunji.c代码如下:
1
2
3
4
5
6
7
8
9
10#include "xunji.h" void XUNji_init(void) { RCC->APB2ENR|=1<<4; //使能PORTC时钟 GPIOC->CRL&=0XF0FFFFFF; GPIOC->CRL|=0X08000000;//PC6浮空输入 GPIOC->CRL&=0X0FFFFFFF; GPIOC->CRL|=0X80000000;//PC7浮空输入 }
xunji.h代码如下
1
2
3
4
5
6
7
8#ifndef __XUNJI_H #define __XUNJI_H #include "sys.h" #define left_led PCin(6) #define right_led PCin(7) void XUN_Init(void); //初始化 #endif
这段代码中很容易犯错误为#define left_led PCout(6) #define right_led PCout(7)
因为我们要读取IO口的状态,所以不能用out必须用in,写成#define left_led PCin(6)和#define right_led PCin(7)
test.c代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#include "sys.h" #include "delay.h" #include "usart.h" #include "moter.h" #include "timer.h" #include "xunji.h" void HOU(void)//定义后退函数 { AIN1=0; AIN2=1; BIN1=0; BIN2=1; } void STOP(void)//停 { AIN1=0; AIN2=0; BIN1=1; BIN2=1; } void YOU(void)//右拐 { AIN1=1; AIN2=0; BIN1=1; BIN2=1; } void ZUO(void)//左拐 { AIN1=0; AIN2=0; BIN1=1; BIN2=0; } void GO(void)//前进 { AIN1=1; AIN2=0; BIN1=1; BIN2=0; } int main(void) { Stm32_Clock_Init(9); //系统时钟设置 uart_init(72,115200); //串口初始化为115200 delay_init(72); //延时初始化 TIM3_PWM_Init(899,0); //不分频。PWM频率=72000/(899+1)=80Khz MOTER_Init(); void XUN_Init(); left=400; right=400; while(1) { if(left_led == 1 && right_led == 1)//左右寻迹探头识别到黑线 { GO();//前进 } else { if(left_led == 1 && right_led == 0)//小车右边出线,左转修正 { ZUO();//左转 } if(left_led == 0 && right_led == 1)//小车左边出线,右转修正 { YOU();//右转 } } } }
以上就是我在调试寻迹小车时的程序,和得到的一些注意事项。分享给大家希望对大家有所帮骤。如果有问题希望大家评论区留言我及时改正。
最后
以上就是明亮蜜粉最近收集整理的关于STM32红外寻迹小车STM32红外寻迹小车(寄存器版)的全部内容,更多相关STM32红外寻迹小车STM32红外寻迹小车(寄存器版)内容请搜索靠谱客的其他文章。
发表评论 取消回复