一、項目介紹
基于STM32設計的簡易手機可以作為智能手表的模型進行開發,方便老人和兒童佩戴。項目主要是為了解決老年人或兒童使用智能手表時可能遇到的困難,例如操作困難、功能復雜等問題。
在這個項目中,采用了STM32F103RCT6主控芯片和SIM800C GSM模塊,實現了短信發送、電話接打等基本功能,并增加了響鈴、接聽、掛斷、預置短信等功能。當檢測到新的電話來時,會通過蜂鳴器通知用戶,并通過按鍵進行接電話和掛電話,使操作更加簡單易懂。手機還提供4個按鍵,可以向預先指定的聯系人發送4條預置短信,更方便快捷。
二、設計思路
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設計簡易手機的完整代碼實現:
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\\r\\n", strlen("AT\\r\\n"));
delay_ms(100);
clear_usart1_buffer();
send_usart1_data((uint8_t *)"AT+CMGF=1\\r\\n", strlen("AT+CMGF=1\\r\\n"));
delay_ms(100);
clear_usart1_buffer();
send_usart1_data((uint8_t *)"AT+CLIP=1\\r\\n", strlen("AT+CLIP=1\\r\\n"));
delay_ms(100);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
void call_phone(void)
{
clear_usart1_buffer();
sprintf((char *)gsm_buffer, "ATD%s;\\r\\n", PHONE_NUMBER);
send_usart1_data(gsm_buffer, strlen(gsm_buffer));
}
void hangup_phone(void)
{
clear_usart1_buffer();
send_usart1_data((uint8_t *)"ATH\\r\\n", strlen("ATH\\r\\n"));
}
void send_message(uint8_t *phone_number, uint8_t *message)
{
clear_usart1_buffer();
sprintf((char *)gsm_buffer, "AT+CMGS="%s"\\r\\n", 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\\r\\n", strlen("ATH\\r\\n")); // 先掛斷當前通話
delay_ms(1000); // 延時一段時間,等待模塊處理完畢
if (strcmp((char *)phone_number, PHONE_NUMBER) == 0) // 判斷號碼是否需要接聽
{
is_calling = 1; // 表示正在通話中
call_answered = 0; // 表示還未接聽
send_usart1_data((uint8_t *)"ATA\\r\\n", strlen("ATA\\r\\n")); // 接聽電話
}
else
{
send_usart1_data((uint8_t *)"ATH\\r\\n", strlen("ATH\\r\\n")); // 掛斷電話
}
}
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\\r\\n", strlen("ATA\\r\\n")); // 接聽電話
call_answered = 1; // 已接聽標志位置1
}
else // 如果已經接聽電話
{
clear_usart1_buffer();
send_usart1_data((uint8_t *)"ATH\\r\\n", strlen("ATH\\r\\n")); // 掛斷電話
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); // 清除中斷標志位
}
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.GPIO_Pin = GPIO_Pin_0; // 短信發送指示燈引腳
gpio_init_struct.GPIO_Mode = GPIO_Mode_Out_PP;
gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init_struct);
gpio_init_struct.GPIO_Pin = GPIO_Pin_6; // 按鍵引腳
gpio_init_struct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &gpio_init_struct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);
EXTI_InitTypeDef exti_init_struct;
exti_init_struct.EXTI_Line = EXTI_Line6;
exti_init_struct.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init_struct.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init_struct.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_init_struct);
NVIC_InitTypeDef nvic_init_struct;
nvic_init_struct.NVIC_IRQChannel = EXTI9_5_IRQn;
nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init_struct.NVIC_IRQChannelSubPriority = 0;
nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init_struct);
init_usart1(SIM800C_BAUDRATE);
init_sim800c();
while (1)
{
// do nothing
}
}
程序利用了STM32F103RCT6的USART1模塊與SIM800C GSM模塊進行串口通信,實現了短信發送、電話接打等基本功能。
程序中包含處理按鍵中斷的代碼,當檢測到新的電話來時,會通過蜂鳴器通知,并使用按鍵進行接電話和掛電話操作;程序根據按下的其他4個按鍵向預設聯系人發送預置的4條短信。在主函數中,進行必要的外設初始化,然后進入一個死循環,等待中斷事件的發生,例如來電、按鍵按下等。在接收到來電中斷時,程序會判斷來電號碼是否是需要接聽的號碼,如果是,則自動接聽電話;如果不是,則自動掛斷電話。在按鍵中斷中,程序會先判斷是否正在通話中,如果是,則執行接聽或掛斷等操作;如果不是,則往預設聯系人發送預置的4條短信。
四、總結
本設計實現了基于STM32F103RCT6主控芯片的簡易手機系統,包括短信發送、電話接打、蜂鳴器通知、按鍵控制等功能。通過硬件電路的設計和制作,以及軟件程序的編寫和調試,實現了系統的正常工作。
審核編輯:湯梓紅
-
手機
+關注
關注
35文章
6898瀏覽量
158266 -
STM32
+關注
關注
2272文章
10924瀏覽量
357582 -
GSM
+關注
關注
9文章
835瀏覽量
123026 -
蜂鳴器
+關注
關注
12文章
893瀏覽量
46095 -
智能手表
+關注
關注
36文章
3300瀏覽量
114816
發布評論請先 登錄
相關推薦
評論