提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
接着上一篇文章A9G模块获取GPS数据的内容,这篇文章继续将其组合成一个小实验可供大家参考使用。本篇文章所涉及的内容是在STM32F103平台上并且是移植了FreeRTOS的基础上实现的(文章底部附网盘资料),获取GPS定位然后通过屏幕输入号码,将经纬度发送到到指定手机上,实验效果如下:
stm32A9G_发送GPS数据到指定号码
提示:以下是本篇文章正文内容,下面案例可供参考
代码
以下是文章的main()函数,整体框架很简单就是两个任务一个负责30秒读取一次GPS数据并且转换成经纬度坐标,一个任务用于LCD触摸的检测和屏幕显示的处理。硬件的连接和初始化可以我写的上一篇文章:https://blog.csdn.net/MOS_JBET/article/details/134377687,百度网盘获取资料后会看到MyApp文件,主要的应用程序都单独在这文件夹中的两个文件的gui.c和A9G_GPS.c中实现了。
#include "sys.h"
/**************************** 任务句柄 ********************************/
/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为NULL。
*/
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t Touch_Task_Handle = NULL;
static TaskHandle_t GPS_Task_Handle = NULL;
/******************************* 全局变量声明 ************************************/
/*
* 当我们在写应用程序的时候,可能需要用到一些全局变量。
*/
extern uint8_t Delay_1s;
char numberBuffer[12] = {0};// 数字存储缓冲区
uint8_t bufferIndex = 0;
u8 PageStart_Flag = 0, PageGPS_Flag = 0, PageTemp_Flag = 0, PageNum_Flag = 0;
float latitude, longitude;
void Touch_test(void);
/********************************** 内核对象句柄 *********************************/
/*
* 信号量,消息队列,事件标志组,软件定时器这些都属于内核的对象,要想使用这些内核
* 对象,必须先创建,创建成功之后会返回一个相应的句柄。实际上就是一个指针,后续我
* 们就可以通过这个句柄操作这些内核对象。
*
* 内核对象说白了就是一种全局的数据结构,通过这些数据结构我们可以实现任务间的通信,
* 任务间的事件同步等各种功能。至于这些功能的实现我们是通过调用这些内核对象的函数
* 来完成的
*
*/
/******************************* 全局变量声明 ************************************/
/*
* 当我们在写应用程序的时候,可能需要用到一些全局变量。
*/
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建任务 */
static void Touch_Task(void* pvParameters);/* Touch_Task任务实现 */
static void GPS_Task(void* pvParameters);/* GPS_Task任务实现 */
static void BSP_Init(void);/* 用于初始化板载相关资源 */
/*****************************************************************
* @brief 主函数
* @param 无
* @retval 无
* @note 第一步:开发板硬件初始化
第二步:创建APP应用任务
第三步:启动FreeRTOS,开始多任务调度
****************************************************************/
int main(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
/* 开发板硬件初始化 */
BSP_Init();
/* 创建AppTaskCreate任务 */
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
(const char* )"AppTaskCreate",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
/* 启动任务调度 */
if(pdPASS == xReturn)
vTaskStartScheduler(); /* 启动任务,开启调度 */
else
return -1;
while(1); /* 正常不会执行到这里 */
}
/***********************************************************************
* @ 函数名 : AppTaskCreate
* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
* @ 参数 : 无
* @ 返回值 : 无
**********************************************************************/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
taskENTER_CRITICAL(); //进入临界区
/* 创建Touch_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )Touch_Task, /* 任务入口函数 */
(const char* )"Touch_Task",/* 任务名字 */
(uint16_t )1024, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )3, /* 任务的优先级 */
(TaskHandle_t* )&Touch_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("创建Touch_Task任务成功!\r\n");
/* 创建GPS_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )GPS_Task, /* 任务入口函数 */
(const char* )"GPS_Task",/* 任务名字 */
(uint16_t )1024, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )2, /* 任务的优先级 */
(TaskHandle_t* )&GPS_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("创建GPS_Task任务成功!\r\n");
vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
taskEXIT_CRITICAL(); //退出临界区
}
/**********************************************************************
* @ 函数名 : Touch_Task
* @ 功能说明: Touch_Task任务主体
* @ 参数 :
* @ 返回值 : 无
********************************************************************/
static void Touch_Task(void* parameter)
{
while (1)
{
//printf("Touch_Task\r\n");
Touch_test(); //电容屏测试
vTaskDelay(1);
}
}
/**********************************************************************
* @ 函数名 : Touch_Task
* @ 功能说明: Touch_Task任务主体
* @ 参数 :
* @ 返回值 : 无
********************************************************************/
static void GPS_Task(void* parameter)
{
while (1)
{
printf("GPS_Task\r\n");
Gui_Page_GPS();
vTaskDelay(10);
}
}
/***********************************************************************
* @ 函数名 : BSP_Init
* @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
* @ 参数 :
* @ 返回值 : 无
*********************************************************************/
static void BSP_Init(void)
{
u8 i = 0, Error;
/*
* STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
* 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
* 都统一用这个优先级分组,千万不要再分组,切忌。
*/
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
delay_init(); //延时函数初始化
uart_init(115200); //串口初始化为115200
printf("\nSTM32_A9G_智能硬件\n");
A9G_uart2_init(115200); // A9G初始化
LED_Init(); //LED端口初始化
LCD_Init();
KEY_Init();
tp_dev.init();
Gui_Page_Start();
}
//按键后端处理
void Touch_test(void)
{
static u8 t=0;
static u8 i=0;
u8 j = 0;
tp_dev.scan(0);
//起始界面触摸处理
if(PageStart_Flag == 1 && PageNum_Flag == 0 && PageGPS_Flag == 0 && PageTemp_Flag == 0)
{
//拨号按键触摸
if(tp_dev.x[t]>175&&tp_dev.x[t]<305&&tp_dev.y[t]>355&&tp_dev.y[t]<485)
{
vTaskDelay(5);
i++;
if(i > 20)
{
i = 0;
LCD_Fill(175, 355, 305, 485, GREEN);
vTaskDelay(10);
LCD_Fill(175, 355, 305, 485, WHITE);
LCD_Clear(WHITE);
PageNum_Flag = 1;
PageStart_Flag = 0;
Gui_PassWord_Page();
}
}
}
//拨号界面触摸处理
if(PageNum_Flag == 1 && PageGPS_Flag == 0 && PageTemp_Flag == 0)
{
if(tp_dev.x[t]>20&&tp_dev.x[t]<155&&tp_dev.y[t]>460&&tp_dev.y[t]<540)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(21, 460, 155, 540, GREEN); // 按键1 绿色提示
vTaskDelay(10);
LCD_Fill(21, 460, 155, 540, WHITE); // 按键1 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '1';
LCD_ShowTitle(bufferIndex*30+50,210,32,17,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>156&&tp_dev.x[t]<311&&tp_dev.y[t]>460&&tp_dev.y[t]<540)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(156, 460, 311, 540, GREEN); // 按键2 绿色提示
vTaskDelay(10);
LCD_Fill(156, 460, 311, 540, WHITE); // 按键2 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '2';
LCD_ShowTitle(bufferIndex*30+50,210,32,18,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>312&&tp_dev.x[t]<460&&tp_dev.y[t]>460&&tp_dev.y[t]<540)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(312, 460, 460, 540, GREEN); // 按键3 绿色提示
vTaskDelay(10);
LCD_Fill(312, 460, 460, 540, WHITE); // 按键3 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '3';
LCD_ShowTitle(bufferIndex*30+50,210,32,19,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>20&&tp_dev.x[t]<155&&tp_dev.y[t]>541&&tp_dev.y[t]<621)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(20, 541, 155, 621, GREEN); // 按键4 绿色提示
vTaskDelay(10);
LCD_Fill(20, 541, 155, 621, WHITE); // 按键4 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '4';
LCD_ShowTitle(bufferIndex*30+50,210,32,20,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>156&&tp_dev.x[t]<311&&tp_dev.y[t]>541&&tp_dev.y[t]<621)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(156, 541, 311, 621, GREEN); // 按键5 绿色提示
vTaskDelay(10);
LCD_Fill(156, 541, 311, 621, WHITE); // 按键5 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '5';
LCD_ShowTitle(bufferIndex*30+50,210,32,21,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>312&&tp_dev.x[t]<460&&tp_dev.y[t]>541&&tp_dev.y[t]<621)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(312, 541, 460, 621, GREEN); // 按键6 绿色提示
vTaskDelay(10);
LCD_Fill(312, 541, 460, 621, WHITE); // 按键6 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '6';
LCD_ShowTitle(bufferIndex*30+50,210,32,22,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>20&&tp_dev.x[t]<155&&tp_dev.y[t]>622&&tp_dev.y[t]<702)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(20, 622, 155, 702, GREEN); // 按键7 绿色提示
vTaskDelay(10);
LCD_Fill(20, 622, 155, 702, WHITE); // 按键7 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '7';
LCD_ShowTitle(bufferIndex*30+50,210,32,23,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>156&&tp_dev.x[t]<311&&tp_dev.y[t]>622&&tp_dev.y[t]<702)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(156, 622, 311, 702, GREEN); // 按键8 绿色提示
vTaskDelay(10);
LCD_Fill(156, 622, 311, 702, WHITE); // 按键8 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '8';
LCD_ShowTitle(bufferIndex*30+50,210,32,24,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>312&&tp_dev.x[t]<460&&tp_dev.y[t]>622&&tp_dev.y[t]<702)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(312, 622, 460, 702, GREEN); // 按键9 绿色提示
vTaskDelay(10);
LCD_Fill(312, 622, 460, 702, WHITE); // 按键9 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '9';
LCD_ShowTitle(bufferIndex*30+50,210,32,25,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>20&&tp_dev.x[t]<155&&tp_dev.y[t]>703&&tp_dev.y[t]<783)
{
vTaskDelay(5);
i++;
if(i > 20)
{
i = 0;
LCD_Fill(20, 703, 155, 783, GREEN); // 按键Delete 绿色提示
vTaskDelay(10);
LCD_Fill(20, 703, 155, 783, WHITE); // 按键Delete 绿色提示
if(bufferIndex >= 1)
{
bufferIndex--;
LCD_ShowTitle((bufferIndex+1)*30+50,210,32,10,RED,WHITE);
}
Gui_PassWord_Page();
}
}
if(tp_dev.x[t]>156&&tp_dev.x[t]<311&&tp_dev.y[t]>703&&tp_dev.y[t]<783)
{
vTaskDelay(5);
i++;
if(i > 10)
{
i = 0;
LCD_Fill(156, 703, 311, 783, RED); // 按键0 绿色提示
vTaskDelay(10);
LCD_Fill(156, 703, 311, 783, WHITE); // 按键0 绿色提示
Gui_PassWord_Page();
if(bufferIndex < sizeof(numberBuffer) - 1)
{
numberBuffer[bufferIndex++] = '0';
LCD_ShowTitle(bufferIndex*30+50,210,32,16,RED,WHITE);
}
else
{
memset(numberBuffer, 0, sizeof(numberBuffer));
bufferIndex = 0;
for(j = 0; j < sizeof(numberBuffer); j++)
LCD_ShowTitle(j*30+50,210,32,10,RED,WHITE);
}
}
}
if(tp_dev.x[t]>312&&tp_dev.x[t]<460&&tp_dev.y[t]>703&&tp_dev.y[t]<783)
{
vTaskDelay(5);
i++;
if(i > 15)
{
i = 0;
LCD_Fill(312, 703, 460, 783, GREEN); // 按键Send 绿色提示
vTaskDelay(10);
LCD_Fill(312, 703, 460, 783, WHITE); // 按键Send 绿色提示
Gui_PassWord_Page();
LCD_ShowTitle(120,100,64,49,GREEN,WHITE); //发
LCD_ShowTitle(210,100,64,50,GREEN,WHITE); //送
LCD_ShowTitle(300,100,64,32,GREEN,WHITE); //中
printf("%s", numberBuffer);
A9G_SendIfo(numberBuffer);
}
}
if(tp_dev.x[t]>20&&tp_dev.x[t]<155&&tp_dev.y[t]>380&&tp_dev.y[t]<460)
{
vTaskDelay(5);
i++;
if(i > 20)
{
i = 0;
LCD_Fill(20, 380, 155, 460, GREEN); // 按键Back 绿色提示
vTaskDelay(10);
LCD_Fill(20, 380, 155, 460, WHITE); // 按键Back 绿色提示
PageGPS_Flag = 0;
PageNum_Flag = 0;
PageTemp_Flag = 0;
PageStart_Flag = 1;
Gui_Page_Start();
}
}
}
}
总结
本篇文章涉及的内容是课程设计相关的内容,希望能给大家提供一点思路。
链接:https://pan.baidu.com/s/1HEwlgRrdafTooL16TifHMw?pwd=3jgg
提取码:3jgg
–来自百度网盘超级会员V4的分享