项目实现功能
  • 项目实现功能
  1. 状态指示灯正常闪烁(LED1)
    2 按键控制LED2打开关闭
  2. 串口打印字符串
  3. LCD显示电量,以及超声波避障功能
  4. LCD显示组员信息
  5. 设计界面,越美观越好工
重要步骤说明
  • LCD屏幕显示汉字
  1. 打开字符取模软件,选项设置阴码,逐行,qo顺向,输出16进制,c51格式,行前缀空,行前缀空为逗号
  2. 确定后输入取模的汉字,生成字模,复制代码到lcd.c里的font.h里
  3. 取模16号字体放到const typFNT_GB16 tfont16[]=里 取模16号字体放到 const typFNT_GB24 tfont24[]=里
  4. 修改复制内容为 “已”,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x0F,0xFF,0xE0,0x00,0x00,0x60,0x00,0x00,格式
  5. 使用Show_Str(56,37,BLUE,BLACK,(u8*)”显示内容必须取过模”,16,0);显示汉字 参数为显示位置x,y,字体颜色和背景,显示内容
  • LCD屏幕显示图片
  1. 找到一个jpg图片,用画图打开,重新调整大小,保存
  2. 打开图片取模软件,输出灰度16位真彩色,最大宽度高度与刚图片一直,高位在前其他不选,打开图片点击保存
  3. 工程里新建pic.c文件,确定后产生的代码复制到pic.c文件
  4. 复制代码”=”前面图片数组的比如const unsigned char gImage_2[1250]={
  5. main.c中添加extern const unsigned char gImage_2[1250];
  6. 使用Paint_Bmp(76,82,25,25,gImage_2);显示图片 参数为显示位置x,y图片大小,图片数组名字
点亮LED灯

led.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "led.h"
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.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _LED_H_
#define _LED_H_

#include "stm32f10x.h"


#define LED1_ON (GPIO_ResetBits(GPIOC,GPIO_Pin_8))
#define LED1_OFF (GPIO_SetBits(GPIOC,GPIO_Pin_8))

#define LED2_ON (GPIO_ResetBits(GPIOC,GPIO_Pin_9))
#define LED2_OFF (GPIO_SetBits(GPIOC,GPIO_Pin_9))
void LED_Config(void);
#endif

延迟

delay.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
#include "delay.h"
#include "sr04.h"
#include "motor.h"
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.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef _DELAY_H_
#define _DELAY_H_

#include "stm32f10x.h"


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);
#endif

按键

key.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
#include "key.h"
#include "delay.h"
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.h
1
2
3
4
5
6
7
8
9
#ifndef _KEY_H_
#define _KEY_H_

#include "stm32f10x.h"
#define KEY1 (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0))
#define KEY2 (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1))
void KEY_Config(void);
u8 KEY_GetValue(void);
#endif

ADC模块

adc.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
#include "adc.h"
// 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.h
1
2
3
4
5
6
7
#ifndef _ADC_H_
#define _ADC_H_

#include "stm32f10x.h"
void ADC_Config(void);
u16 ADC_GetValue(void);
#endif

电机模块

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
#include "motor.h"

/**
* @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
#ifndef __LCD_H
#define __LCD_H

#include "stm32f10x.h"

//延时在proteus仿真中必须用nop才准确
#define delay_ms(x) Delay_us(x*1000)

#define SPI_CTRL GPIOB //定义TFT数据端口
#define SPI_SCLK GPIO_Pin_13 //PB13--->>TFT --SCL/SCK
#define SPI_MISO GPIO_Pin_14
#define SPI_MOSI GPIO_Pin_15 //PB15 MOSI--->>TFT --SDA/DIN

#define SPI_MOSI_SET SPI_CTRL->BSRR=SPI_MOSI
#define SPI_SCLK_SET SPI_CTRL->BSRR=SPI_SCLK

#define SPI_MOSI_CLR SPI_CTRL->BRR=SPI_MOSI
#define SPI_SCLK_CLR SPI_CTRL->BRR=SPI_SCLK

#define LCD_TYPE GPIOB //GPIO组类型
#define LCD_CS 11 //片选引脚 PB11
#define LCD_RS 10 //寄存器/数据选择引脚 PB10
#define LCD_RST 12 //复位引脚 PB12

#define LCD_CS_SET LCD_TYPE->BSRR=1<<LCD_CS //片选端口 PB11
#define LCD_RS_SET LCD_TYPE->BSRR=1<<LCD_RS //数据/命令 PB10
#define LCD_RST_SET LCD_TYPE->BSRR=1<<LCD_RST //复位 PB12

#define LCD_CS_CLR LCD_TYPE->BRR=1<<LCD_CS //片选端口 PB11
#define LCD_RS_CLR LCD_TYPE->BRR=1<<LCD_RS //数据/命令 PB10
#define LCD_RST_CLR LCD_TYPE->BRR=1<<LCD_RST //复位 PB12



#define LCD_W 240
#define LCD_H 320
#define USE_HORIZONTAL 0//定义液晶屏顺时针旋转方向 0-0度旋转,1-90度旋转,2-180度旋转,3-270度旋转

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重要参数

//画笔颜色
#define UNKNOWBLUE 0x2D7D //自己添加的一种蓝色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
//GUI颜色

#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
//以上三色为PANEL的颜色

#define LIGHTGREEN 0X841F //浅绿色
#define LIGHTGRAY 0XEF5B //浅灰色(PANNEL)
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)


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[]);//显示图片函数





#endif

串口配置

usart.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
#include "usart.h"
//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重定向
#include "stdio.h"
int fputc (int c,FILE*Stream)
{
Usart_SendData(c) ;
return c;
}


usart.h
1
2
3
4
5
6
7
8
#ifndef _USART_H_
#define _USART_H_

#include "stm32f10x.h"
void Usart_Config(void);
void Usart_SendData(u8 data);
u8 Usart_ReceiveData();
#endif

测距传感器

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
#include "sr04.h"
#include "delay.h"

//初始化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.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef	__SR04_H
#define __SR04_H

#include "stm32f10x.h"

//TR:PC5 ECHO:PC6
#define SR04_TR_PeriphClock RCC_APB2Periph_GPIOC
#define SR04_TR_PORT GPIOC
#define SR04_TR_PIN GPIO_Pin_5

#define SR04_ECHO_PeriphClock RCC_APB2Periph_GPIOC
#define SR04_ECHO_PORT GPIOC
#define SR04_ECHO_PIN GPIO_Pin_6

void Sr04_Config(void);
void Sr04_SendTTL(void);
void Sr04_RecvEcho(void);
uint32_t Sr04_GetLength(void);

#endif

mian函数
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
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "stdio.h"
#include "lcd.h"
#include "adc.h"
#include "motor.h"
#include "sr04.h"
//extern const unsigned char gImage_pic[9800];
//extern const unsigned char gImage_1[5000];
extern const unsigned char gImage_2[1250];
extern const unsigned char gImage_3[1250];
extern const unsigned char gImage_4[1250];
extern const unsigned char gImage_5[1250];
u32 safelen=30;
int main()
{
u8 key=0;
u8 flag=0;
u8 power=0;
u32 len=0;
char buff[20]={0};
char buff1[20]={0};
char buff2[20]={0};
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//占先2位+次级2位

LED_Config();//LED初始化
KEY_Config();//按键初始化
Usart_Config();//串口初始化
Motor_Config();//电机初始化
Sr04_Config();//sro4避障传感器初始化
Delay_Config();//滴答定时器初始化
ADC_Config();//ADC初始化
LCD_Init();//LCD屏初始化,驱动带的
printf("李晓\r\n");
LED1_OFF;
LED2_ON;
// gui_circle(80,80,BLUE,30,0);//画圆
// GUI_DrawPoint(80,80,RED);//画点
//LCD_ShowString(80,10,16,(u8*)"hello",0);//显示字母或数字
// Show_Str(80,10,BLUE,WHITE,(u8*)"李晓",16,0);//显示汉字(包括字母数字)
// Paint_Bmp(0,0,70,70,gImage_pic);//显示图片
// LCD_Clear(u16 Color); //清屏
//第一张页面
Show_Str(73,87,BLUE,WHITE,(u8*)"系统已启动",16,0);//显示汉字(包括字母数字)
Show_Str(41,139,BLUE,WHITE,(u8*)"正在为您展示本次项目",16,0);//显示汉字(包括字母数字)
Show_Str(81,191,BLUE,WHITE,(u8*)".......",16,0);//显示汉字(包括字母数字)
LCD_Clear(BLACK); //清屏

//第二张页面成员
Show_Str(76,51,BLUE,BLACK,(u8*)"小组成员",16,0);//显示汉字(包括字母数字)
Show_Str(85,85,BLUE,BLACK,(u8*)"李晓",16,0);//显示汉字(包括字母数字)
Show_Str(85,120,BLUE,BLACK,(u8*)"李东林",16,0);//显示汉字(包括字母数字)
Show_Str(85,153,BLUE,BLACK,(u8*)"张龙强",16,0);//显示汉字(包括字母数字)
Show_Str(85,188,BLUE,BLACK,(u8*)"赵龙元",16,0);//显示汉字(包括字母数字)
Show_Str(85,219,BLUE,BLACK,(u8*)"杨志伟",16,0);//显示汉字(包括字母数字)
Show_Str(85,250,BLUE,BLACK,(u8*)"蔡彬源",16,0);//显示汉字(包括字母数字)
LCD_Clear(BLACK); //清屏
while(1)
{ //LED1闪烁
if(timeled[0]>timeled[1])
{
if(flag==0)
LED1_ON;
if(flag==1)
LED1_OFF;
flag=!flag;
timeled[0]=0;
}

Show_Str(56,37,BLUE,BLACK,(u8*)"避障项目演示",16,0);//显示汉字(包括字母数字)
//显示电量
if(timeadc[0]>timeadc[1])
{
power=ADC_GetValue();
printf("电量:%d\r\n",power);
sprintf(buff,"当前电量:\%d\r\n",power);
Paint_Bmp(76,82,25,25,gImage_2);//显示图片
Show_Str(101,82,BLUE,BLACK,(u8*)buff,16,0);

timeadc[0]=0;
}
//显示自动避障和距离
// Show_Str(120,240,BLUE,WHITE,(u8*)"自动避障",16,0);//显示汉字(包括字母数字)
len=Sr04_GetLength();
printf("距离:%d\r\n",len);
Paint_Bmp(76,115,25,25,gImage_3);//显示图片
sprintf(buff1,"当前距离:%d ",len);
sprintf(buff2,"安全距离为:%d",safelen);
Show_Str(101,115,BLUE,BLACK,(u8*)buff1,16,0);//显示汉字(包括字母数字)
Paint_Bmp(76,152,25,25,gImage_4);//显示图片
Show_Str(101,152,BLUE,BLACK,(u8*)buff2,16,0);//显示汉字(包括字母数字)
Paint_Bmp(76,188,25,25,gImage_5);//显示图片
if(len>safelen)
{
Show_Str(101,188,BLUE,BLACK,(u8*)"当前状态:安全",16,0);//显示汉字(包括字母数字)
Motor_SetSpeed(90,90,90,90);//直行
}
else
{
Show_Str(101,188,BLUE,BLACK,(u8*)"当前状态:过近",16,0);//显示汉字(包括字母数字)
Motor_SetSpeed(-50,-50,50,50); //右转
}

Show_Str(44,239,BLUE,BLACK,(u8*)"避障系统正常运行",16,0);//显示汉字(包括字母数字)




//按键控制LED2打开关闭
key=KEY_GetValue();
if(key==1)
{
LED2_ON;
}
if(key==2)
{
LED2_OFF;
}

}
}