STM32避障小车
项目实现功能
- 项目实现功能
- 状态指示灯正常闪烁(LED1)
2 按键控制LED2打开关闭 - 串口打印字符串
- LCD显示电量,以及超声波避障功能
- LCD显示组员信息
- 设计界面,越美观越好工
重要步骤说明
- LCD屏幕显示汉字
- 打开字符取模软件,选项设置阴码,逐行,qo顺向,输出16进制,c51格式,行前缀空,行前缀空为逗号
- 确定后输入取模的汉字,生成字模,复制代码到lcd.c里的font.h里
- 取模16号字体放到const typFNT_GB16 tfont16[]=里 取模16号字体放到 const typFNT_GB24 tfont24[]=里
- 修改复制内容为 “已”,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x0F,0xFF,0xE0,0x00,0x00,0x60,0x00,0x00,格式
- 使用Show_Str(56,37,BLUE,BLACK,(u8*)”显示内容必须取过模”,16,0);显示汉字 参数为显示位置x,y,字体颜色和背景,显示内容
- LCD屏幕显示图片
- 找到一个jpg图片,用画图打开,重新调整大小,保存
- 打开图片取模软件,输出灰度16位真彩色,最大宽度高度与刚图片一直,高位在前其他不选,打开图片点击保存
- 工程里新建pic.c文件,确定后产生的代码复制到pic.c文件
- 复制代码”=”前面图片数组的比如const unsigned char gImage_2[1250]={
- main.c中添加extern const unsigned char gImage_2[1250];
- 使用Paint_Bmp(76,82,25,25,gImage_2);显示图片 参数为显示位置x,y图片大小,图片数组名字
点亮LED灯
led.c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void LED_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIO时钟
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;//通用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;//配置8号引脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出速率
GPIO_Init(GPIOC,&GPIO_InitStructure);//初始化GPIOC的8号引脚
}
void LED_ON(void)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
}
void LED_OFF(void)
{
GPIO_SetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
}
led.h1
2
3
4
5
6
7
8
9
10
11
12
13
void LED_Config(void);
延迟
delay.c1
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
void Delay_nus_nop(unsigned int time)
{
while(time--)
{
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
}
}
void Delay_mus_nop(unsigned int time)
{
while(time--)
{
Delay_nus_nop(1000);
}
}
//滴答定时器初始化
//产生100us中断 -- 优先级最低
void Delay_Config(void)
{
if(SysTick_Config(4000) == 1)//定时完成之后产生中断
{
while(1);
}
}
uint32_t timecount = 0;//记录系统运行时长
u32 timeled[2]={0,100};//定义led中断时间
u32 timeadc[2]={0,100};//定义adc中断时间
/*
滴答定时器的中断 100us调用一次
*/
void SysTick_Handler(void)
{
timecount++;
timeled[0]++;
timeadc[0]++;
Sr04_RecvEcho();
Motor_Control();
}
delay.h1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Delay_nus_nop(unsigned int time);
void Delay_mus_nop(unsigned int time);
extern uint32_t timeled[2];
extern uint32_t timekey[2];
extern uint32_t timedht11[2];
extern u32 timeled[2];
extern u32 timeadc[2];
void Delay_Config(void);
按键
key.c1
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
void KEY_Config(void)
{//打开时钟 GPIOC--APB2
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC,ENABLE);
//初始化GPIO
GPIO_InitTypeDef key={0};
//浮空输入
key.GPIO_Mode=GPIO_Mode_IN_FLOATING;
key.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_Init(GPIOC,&key);
}
//按键扫描函数返回1代表按下按键1按下,2代表按键2按下
u8 KEY_GetValue(void)
{
if(KEY1==0)
{
Delay_mus_nop(5);//消抖
while(KEY1==0){}//松手检测
return 1;
}
if(KEY2==0)
{
Delay_mus_nop(5);//消抖
while(KEY2==0){}//松手检测
return 2;
}
else
return 0;
}
key.h1
2
3
4
5
6
7
8
9
void KEY_Config(void);
u8 KEY_GetValue(void);
ADC模块
adc.c1
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
// PA0
void ADC_Config(void)
{
//打开时钟GPIOA ADC1--APB2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//分频
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//初始化GPIO
GPIO_InitTypeDef gpio_Struct={0};
gpio_Struct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
gpio_Struct.GPIO_Pin=GPIO_Pin_0;
GPIO_Init (GPIOA, &gpio_Struct) ;
//初始化ADC
ADC_InitTypeDef adc_Struct={0} ;
adc_Struct.ADC_ContinuousConvMode=DISABLE;//单次模式
adc_Struct.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
adc_Struct.ADC_ExternalTrigConv=ADC_ExternalTrigInjecConv_None;//无外部触发
adc_Struct.ADC_Mode=ADC_Mode_Independent;//独立模式
adc_Struct.ADC_NbrOfChannel=1;//通道数目
adc_Struct.ADC_ScanConvMode=DISABLE;//单通道
ADC_Init (ADC1,&adc_Struct) ;
//使能
ADC_Cmd(ADC1,ENABLE);
}
//获取ADC转换结果
u16 ADC_GetValue(void)
{
//选择通道 转换顺序 采样周期
ADC_RegularChannelConfig (ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
//开启转换
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
//获取转换结果
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET){}
//获取转换结果
return ADC_GetConversionValue(ADC1);
}
adc.h1
2
3
4
5
6
7
void ADC_Config(void);
u16 ADC_GetValue(void);
电机模块
motor.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/**
* @brief 配置电机控制引脚的初始化
* @param 无
* @retval 无
*/
//四个电机的GPIO口初始化
void Motor_Config(void)
{
//开时钟
RCC_APB2PeriphClockCmd(MOTOR_IA1_PeriphClock | MOTOR_IB1_PeriphClock |
MOTOR_IA2_PeriphClock | MOTOR_IB2_PeriphClock |
MOTOR_IA3_PeriphClock | MOTOR_IB3_PeriphClock |
MOTOR_IA4_PeriphClock | MOTOR_IB4_PeriphClock , ENABLE);//打开GPIO外设时钟
GPIO_InitTypeDef GPIO_InitStructure; //定义变量
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出
GPIO_InitStructure.GPIO_Pin = MOTOR_IA1_PIN; //端口位
GPIO_Init(MOTOR_IA1_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IB1_PIN; //端口位
GPIO_Init(MOTOR_IB1_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IA2_PIN; //端口位
GPIO_Init(MOTOR_IA2_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IB2_PIN; //端口位
GPIO_Init(MOTOR_IB2_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IA3_PIN; //端口位
GPIO_Init(MOTOR_IA3_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IB3_PIN; //端口位
GPIO_Init(MOTOR_IB3_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IA4_PIN; //端口位
GPIO_Init(MOTOR_IA4_PORT, &GPIO_InitStructure); //初始化
GPIO_InitStructure.GPIO_Pin = MOTOR_IB4_PIN; //端口位
GPIO_Init(MOTOR_IB4_PORT, &GPIO_InitStructure); //初始化
//先让电机处于停止
Motor_IA1Control(0);
Motor_IB1Control(0);
Motor_IA2Control(0);
Motor_IB2Control(0);
Motor_IA3Control(0);
Motor_IB3Control(0);
Motor_IA4Control(0);
Motor_IB4Control(0);
}
/**
* @brief 1号电机的速度控制函数
* 在中断内,周期性的调用
* @param speed:速度,如果是正数,电机正转,负数电机反转,
* 速度的绝对值不能超过MOTOR_MAX_SPEED
* @retval 无
*/
void Motor_No1_Control(int speed)//cnt计数值,speed比较值,MOTOR_MAX_SPEED最大计数值(周期)
{
static uint32_t cnt = 0;
if(speed > 0) { //电机正转
Motor_IB1Control(0);
if(cnt <= speed) Motor_IA1Control(1);
else Motor_IA1Control(0);
}
else if(speed < 0){//电机反转
speed = -speed;
Motor_IA1Control(0);
if(cnt <= speed) Motor_IB1Control(1);
else Motor_IB1Control(0);
}
else {//电机停止
Motor_IA1Control(0);
Motor_IB1Control(0);
}
if(cnt < MOTOR_MAX_SPEED) cnt++;//cnt 100us加一次
else cnt = 0;
}
/**
* @brief 2号电机的速度控制函数
* 在中断内,周期性的调用
* @param speed:速度,如果是正数,电机正转,负数电机反转,
* 速度的绝对值不能超过MOTOR_MAX_SPEED
* @retval 无
*/
void Motor_No2_Control(int speed)
{
static uint32_t cnt = 0;
if(speed > 0) { //电机正转
Motor_IB2Control(0);
if(cnt <= speed) Motor_IA2Control(1);
else Motor_IA2Control(0);
}
else if(speed < 0){//电机反转
speed = -speed;
Motor_IA2Control(0);
if(cnt <= speed) Motor_IB2Control(1);
else Motor_IB2Control(0);
}
else {//电机停止
Motor_IA2Control(0);
Motor_IB2Control(0);
}
if(cnt < MOTOR_MAX_SPEED) cnt++;
else cnt = 0;
}
/**
* @brief 3号电机的速度控制函数
* 在中断内,周期性的调用
* @param speed:速度,如果是正数,电机正转,负数电机反转,
* 速度的绝对值不能超过MOTOR_MAX_SPEED
* @retval 无
*/
void Motor_No3_Control(int speed)
{
static uint32_t cnt = 0;
if(speed > 0) { //电机正转
Motor_IB3Control(0);
if(cnt <= speed) Motor_IA3Control(1);
else Motor_IA3Control(0);
}
else if(speed < 0){//电机反转
speed = -speed;
Motor_IA3Control(0);
if(cnt <= speed) Motor_IB3Control(1);
else Motor_IB3Control(0);
}
else {//电机停止
Motor_IA3Control(0);
Motor_IB3Control(0);
}
if(cnt < MOTOR_MAX_SPEED) cnt++;
else cnt = 0;
}
/**
* @brief 4号电机的速度控制函数
* 在中断内,周期性的调用
* @param speed:速度,如果是正数,电机正转,负数电机反转,
* 速度的绝对值不能超过MOTOR_MAX_SPEED
* @retval 无
*/
void Motor_No4_Control(int speed)
{
static uint32_t cnt = 0;
if(speed > 0) { //电机正转
Motor_IB4Control(0);
if(cnt <= speed) Motor_IA4Control(1);
else Motor_IA4Control(0);
}
else if(speed < 0){//电机反转
speed = -speed;
Motor_IA4Control(0);
if(cnt <= speed) Motor_IB4Control(1);
else Motor_IB4Control(0);
}
else {//电机停止
Motor_IA4Control(0);
Motor_IB4Control(0);
}
if(cnt < MOTOR_MAX_SPEED) cnt++;
else cnt = 0;
}
__Motor_SpeedTypeDef motorSpeed = {0};
/**
* @brief 4个电机的整体控制函数,在中断内,周期性的调用
* @param
* @retval 无
*/
void Motor_Control(void)
{
Motor_No1_Control(motorSpeed.s1);
Motor_No2_Control(motorSpeed.s2);
Motor_No3_Control(motorSpeed.s3);
Motor_No4_Control(motorSpeed.s4);
}
/**
* @brief 4个电机的速度设置
* @param s1、s2、s3、s4分别是要设置的四个电机的速度
* @retval 无
*/
void Motor_SetSpeed(int s1, int s2, int s3, int s4)
{
motorSpeed.s1 = s1;
motorSpeed.s2 = s2;
motorSpeed.s3 = s3;
motorSpeed.s4 = s4;
}
LCD显示屏
lcd.h—-自带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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//延时在proteus仿真中必须用nop才准确
extern u16 POINT_COLOR;
//LCD重要参数集
typedef struct
{
u16 width; //LCD 宽度
u16 height; //LCD 高度
u16 id; //LCD ID
u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
u16 wramcmd; //开始写gram指令
u16 setxcmd; //设置x坐标指令
u16 setycmd; //设置y坐标指令
}_lcd_dev;
//LCD参数
extern _lcd_dev lcddev; //管理LCD重要参数
//画笔颜色
//GUI颜色
//以上三色为PANEL的颜色
void SPIv_WriteData(u8 Data);
void LCD_Init(void);
void LCD_DisplayOn(void);
void LCD_DisplayOff(void);
void LCD_Clear(u16 Color); //清屏
void LCD_SetCursor(u16 Xpos, u16 Ypos);
void LCD_DrawPoint(u16 x,u16 y);//画点
u16 LCD_ReadPoint(u16 x,u16 y); //读点
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd);
u16 LCD_RD_DATA(void);//读取LCD数据
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue);
void LCD_WR_DATA(u8 data);
u16 LCD_ReadReg(u8 LCD_Reg);
void LCD_WriteRAM_Prepare(void);
void LCD_WriteRAM(u16 RGB_Code);
u16 LCD_ReadRAM(void);
u16 LCD_BGR2RGB(u16 c);
void LCD_SetParam(void);
void Lcd_WriteData_16Bit(u16 Data);
void LCD_direction(u8 direction );
void GUI_DrawPoint(u16 x,u16 y,u16 color);//画点
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//画线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//画矩形
void Draw_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//画三角
void Fill_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2);
void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode);
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);
void LCD_Show2Num(u16 x,u16 y,u16 num,u8 len,u8 size,u8 mode);
void LCD_ShowString(u16 x,u16 y,u8 size,u8 *p,u8 mode);
void GUI_DrawFont16(u16 x, u16 y, u16 fc, u16 bc, u8 *s,u8 mode);
void GUI_DrawFont24(u16 x, u16 y, u16 fc, u16 bc, u8 *s,u8 mode);
void GUI_DrawFont32(u16 x, u16 y, u16 fc, u16 bc, u8 *s,u8 mode);
void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode);//显示汉字
void gui_circle(int xc, int yc,u16 c,int r, int fill);//画圆
void Gui_StrCenter(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode);
void LCD_DrawFillRectangle(u16 x1, u16 y1, u16 x2, u16 y2);
void Paint_Bmp(int x0,int y0,int width,int high,const unsigned char bmp[]);//显示图片函数
串口配置
usart.c1
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
//PA9发送 PA10接收
void Usart_Config(void)
{
//打开时钟GPIO USART1--APB2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
//初始化GPIO
GPIO_InitTypeDef gpio_InStruct={0};
gpio_InStruct.GPIO_Mode=GPIO_Mode_AF_PP;//TX_复用推挽输出
gpio_InStruct.GPIO_Pin=GPIO_Pin_9 ;
gpio_InStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init (GPIOA, &gpio_InStruct) ;
gpio_InStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//Rx_浮空输入
gpio_InStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA, &gpio_InStruct) ;
//初始化串口
USART_InitTypeDef usart_InStruct={0};
usart_InStruct.USART_BaudRate=57600;//波特率
usart_InStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件控制流
usart_InStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//模式一发送和接收
usart_InStruct.USART_Parity=USART_Parity_No;//无奇偶校验
usart_InStruct.USART_StopBits=USART_StopBits_1;//1位停止位
usart_InStruct.USART_WordLength=USART_WordLength_8b;//8位停止位
USART_Init (USART1,&usart_InStruct) ;
//使能串口
USART_Cmd(USART1,ENABLE);
}
//发送单字节函数
void Usart_SendData(u8 data)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){}//判断上一次是否发送完成
USART_SendData (USART1,data);
}
//接收函数
u8 Usart_ReceiveData()
{
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET){}//判断上一次是否发送完成
USART_ReceiveData(USART1);
}
// printf重定向
int fputc (int c,FILE*Stream)
{
Usart_SendData(c) ;
return c;
}
usart.h1
2
3
4
5
6
7
8
void Usart_Config(void);
void Usart_SendData(u8 data);
u8 Usart_ReceiveData();
测距传感器
sr04.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
//初始化GPIO
void Sr04_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//开时钟
RCC_APB2PeriphClockCmd(SR04_TR_PeriphClock|SR04_ECHO_PeriphClock,ENABLE);
//配置TR
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStruct.GPIO_Pin = SR04_TR_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
//初始化GPIO
GPIO_Init(SR04_TR_PORT, &GPIO_InitStruct);
//配置ECHO
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitStruct.GPIO_Pin = SR04_ECHO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
//初始化GPIO
GPIO_Init(SR04_ECHO_PORT, &GPIO_InitStruct);
}
//TR引脚发送10us脉冲
void Sr04_SendTTL(void)
{
GPIO_SetBits(SR04_TR_PORT,SR04_TR_PIN);//拉高
Delay_nus_nop(10);
//Delay_us(10);
GPIO_ResetBits(SR04_TR_PORT,SR04_TR_PIN);//拉低
}
uint32_t echocount = 0;
uint32_t sr04length = 0;
//ECHO引脚检测和计数
//最好是1us检测一次,但是仿真中会卡死
//因此我们放到1ms进入一次的系统滴答定时器的中断服务函数内计数
void Sr04_RecvEcho(void)
{
if(GPIO_ReadInputDataBit(SR04_ECHO_PORT,SR04_ECHO_PIN) == 1)
{
echocount++;
}
if(GPIO_ReadInputDataBit(SR04_ECHO_PORT,SR04_ECHO_PIN) == 0)
{
if(echocount > 0)
{
sr04length = echocount;
}
echocount = 0;
}
}
//距离=sr04length*340m/s /2 sr04length(单位百us) 距离cm为单位
//距离=sr04length*34m/s /2
//距离=sr04length*17m/s /2
//距离=sr04length*340m/s /2
//计算距离
uint32_t Sr04_GetLength(void)
{
sr04length = (uint32_t)(sr04length*1.7);
return sr04length;
}
scr04.h1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//TR:PC5 ECHO:PC6
void Sr04_Config(void);
void Sr04_SendTTL(void);
void Sr04_RecvEcho(void);
uint32_t Sr04_GetLength(void);
mian函数
1 |
|