基于STM32设计的简易手机

发布时间:2024-07-24  

一、项目介绍

基于STM32设计的简易手机可以作为智能手表的模型进行开发,方便老人和儿童佩戴。项目主要是为了解决老年人或儿童使用智能手表时可能遇到的困难,例如操作困难、功能复杂等问题。


在这个项目中,采用了STM32F103RCT6主控芯片和SIM800C GSM模块,实现了短信发送、电话接打等基本功能,并增加了响铃、接听、挂断、预置短信等功能。当检测到新的电话来时,会通过蜂鸣器通知用户,并通过按键进行接电话和挂电话,使操作更加简单易懂。手机还提供4个按键,可以向预先指定的联系人发送4条预置短信,更方便快捷。

image-20230617103157135

image-20230617103208773

img

image-20230607220310330

二、设计思路

2.1 设计目的

实现基于STM32F103RCT6主控芯片的简易手机系统,包括短信发送、电话接打、蜂鸣器通知、按键控制等功能。

2.2 系统硬件设计

系统主要由STM32F103RCT6主控芯片、SIM800C GSM模块、蜂鸣器、LCD显示屏、按键等组成。

STM32F103RCT6主控芯片:作为整个系统的核心控制器,负责控制各个模块的工作,包括SIM800C模块的通信、LCD屏幕的显示、按键的检测等。

SIM800C GSM模块:作为系统与外部通信的核心模块,负责实现短信发送、电话接打等功能。

蜂鸣器:当检测到新的电话来时,通过蜂鸣器通知用户。

LCD显示屏:用于显示系统状态、短信内容、电话号码等信息。

按键:包括接听键、挂断键、短信发送键等,用于实现系统的各种功能。

2.3 系统软件设计

本系统的软件设计主要包括以下几个方面:

(1)SIM800C模块驱动程序的编写,实现短信发送、电话接打等功能。

(2)LCD显示程序的编写,实现信息的显示和操作界面的设计。

(3)按键程序的编写,实现按键的检测和功能的实现。

(4)系统状态机的设计,实现系统状态的切换和各个状态之间的转换。

2.4 系统实现

【1】硬件实现

根据设计方案,完成了硬件电路的设计和制作。其中,STM32F103RCT6主控芯片与SIM800C模块通过串口进行通信,LCD显示屏通过SPI接口进行通信。

【2】软件实现

(1)SIM800C模块驱动程序的编写

根据SIM800C模块的AT指令集,编写了相应的驱动程序,实现了短信发送、电话接打等功能。

  • 初始化SIM800C模块,设置串口通信参数。

  • 发送AT指令,检测SIM800C模块是否正常工作。

  • 实现短信发送功能,包括设置短信内容、发送短信等操作。

  • 实现电话接打功能,包括拨号、接听、挂断等操作。

(2)LCD显示程序的编写

根据LCD显示屏的驱动芯片ST7735S的规格书,编写了相应的LCD显示程序,实现了信息的显示和操作界面的设计。

  • 初始化LCD显示屏,设置SPI通信参数。

  • 实现信息的显示功能,包括电话号码、短信内容等信息的显示。

  • 实现操作界面的设计,包括菜单、按键状态等信息的显示。

(3)按键程序的编写

根据硬件设计中按键的接线方式,编写了相应的按键程序,实现了按键的检测和功能的实现。具体实现过程如下:

  • 初始化按键,设置按键的引脚方向和上下拉电阻。

  • 实现按键的检测功能,包括按键的按下和松开的检测。

  • 实现按键功能的实现,包括接听、挂断、短信发送等功能。

(4)系统状态机的设计

根据系统的功能和状态,设计了相应的状态机,实现系统状态的切换和各个状态之间的转换。具体实现过程如下:

  • 设计系统的状态,包括待机状态、拨号状态、通话状态、短信发送状态等。

  • 实现状态之间的转换,包括按键触发、SIM800C模块的响应等。

  • 实现状态机的循环,不断检测系统状态并执行相应的操作。


三、代码实现

下面是基于STM32F103RCT6设计简易手机的完整代码实现:


cpp

 #include "stm32f10x.h"

 #include "stdio.h"

 #include "string.h"


 #define SIM800C_BAUDRATE 9600 // SIM800C模块波特率

 #define PHONE_NUMBER "123456789" // 需要拨打的电话号码


 uint8_t gsm_buffer[100]; // 存储GSM模块返回的数据

 uint8_t phone_number[15]; // 存储当前来电的电话号码

 volatile uint8_t is_calling = 0; // 是否正在通话中的标志位

 volatile uint8_t call_answered = 0; // 是否接听了电话的标志位


 void init_usart1(uint32_t baudrate)

{

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);


     GPIO_InitTypeDef gpio_init_struct;

     gpio_init_struct.GPIO_Pin = GPIO_Pin_9;

     gpio_init_struct.GPIO_Mode = GPIO_Mode_AF_PP;

     gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_Init(GPIOA, &gpio_init_struct);


     gpio_init_struct.GPIO_Pin = GPIO_Pin_10;

     gpio_init_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

     GPIO_Init(GPIOA, &gpio_init_struct);


     USART_InitTypeDef usart_init_struct;

     usart_init_struct.USART_BaudRate = baudrate;

     usart_init_struct.USART_WordLength = USART_WordLength_8b;

     usart_init_struct.USART_StopBits = USART_StopBits_1;

     usart_init_struct.USART_Parity = USART_Parity_No;

     usart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

     usart_init_struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

     USART_Init(USART1, &usart_init_struct);

     USART_Cmd(USART1, ENABLE);

 }


 void send_usart1_data(uint8_t *data, uint16_t size)

{

     for (int i = 0; i < size; i++)

     {

         USART_SendData(USART1, data[i]);

         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)

         {

         }

     }

 }


 uint8_t receive_usart1_data(void)

{

     while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)

     {

     }

     return USART_ReceiveData(USART1);

 }


 void clear_usart1_buffer(void)

{

     memset(gsm_buffer, 0, sizeof(gsm_buffer));

 }


 void init_sim800c(void)

{

     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"AT ", strlen("AT "));

     delay_ms(100);


     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"AT+CMGF=1 ", strlen("AT+CMGF=1 "));

     delay_ms(100);


     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"AT+CLIP=1 ", strlen("AT+CLIP=1 "));

     delay_ms(100);


     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

 }


 void call_phone(void)

{

     clear_usart1_buffer();

     sprintf((char *)gsm_buffer, "ATD%s; ", PHONE_NUMBER);

     send_usart1_data(gsm_buffer, strlen(gsm_buffer));

 }


 void hangup_phone(void)

{

     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"ATH ", strlen("ATH "));

 }


 void send_message(uint8_t *phone_number, uint8_t *message)

{

     clear_usart1_buffer();

     sprintf((char *)gsm_buffer, "AT+CMGS="%s" ", phone_number);

     send_usart1_data(gsm_buffer, strlen(gsm_buffer));

     delay_ms(100);


     clear_usart1_buffer();

     send_usart1_data(message, strlen((char *)message));

     delay_ms(100);


     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"x1A", strlen("x1A"));

 }


 void process_incoming_call(void)

{

     clear_usart1_buffer();

     send_usart1_data((uint8_t *)"ATH ", strlen("ATH ")); // 先挂断当前通话

     delay_ms(1000); // 延时一段时间,等待模块处理完毕


     if (strcmp((char *)phone_number, PHONE_NUMBER) == 0) // 判断号码是否需要接听

     {

         is_calling = 1; // 表示正在通话中

         call_answered = 0; // 表示还未接听

         send_usart1_data((uint8_t *)"ATA ", strlen("ATA ")); // 接听电话

     }

     else

     {

         send_usart1_data((uint8_t *)"ATH ", strlen("ATH ")); // 挂断电话

     }

 }


 void EXTI9_5_IRQHandler(void)

{

     if (EXTI_GetITStatus(EXTI_Line6) != RESET) // 判断是否为按键中断

     {

         if (is_calling == 1) // 如果正在通话中

         {

             if (call_answered == 0) // 如果还未接听电话

             {

                 clear_usart1_buffer();

                 send_usart1_data((uint8_t *)"ATA ", strlen("ATA ")); // 接听电话

                 call_answered = 1; // 已接听标志位置1

             }

             else // 如果已经接听电话

             {

                 clear_usart1_buffer();

                 send_usart1_data((uint8_t *)"ATH ", strlen("ATH ")); // 挂断电话

                 is_calling = 0; // 已接听标志位置0

             }

         }

         else // 如果不在通话中,则发送预设短信

         {

             GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 开启短信发送指示灯

             for (int i = 0; i < 4; i++)

             {

                 uint8_t message[50];

                 switch (i)

                 {

                     case 0:

                         sprintf((char *)message, "Hello! This is message 1.");

                         break;

                     case 1:

                         sprintf((char *)message, "Hi! How are you? This is message 2.");

                         break;

                     case 2:

                         sprintf((char *)message, "Good morning! This is message 3.");

                         break;

                     case 3:

                         sprintf((char *)message, "Good evening! This is message 4.");

                         break;

                 }

                 send_message(phone_number, message);

                 delay_ms(5000); // 延时5s

             }

             GPIO_SetBits(GPIOA, GPIO_Pin_0); // 关闭短信发送指示灯

         }

         EXTI_ClearITPendingBit(EXTI_Line6); // 清除中断标志位

     }

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>