本章节是制作教程,教你连接硬件,烧录程序,然后你就拥有一部YY手机了。
关于程序的原理,请参考我上传的源码,源码中有详细的注释(基础功能相关的程序请参考书籍,如USART等资源的使用)。后续章节中,也会有关于不常用模块的使用教程。
第一步·硬件连接
为了方便二次开发、扩展应用,YY手机硬件方案中预留出了SPI总线接口和I2C总线接口,方便读者连接其他传感器或单片机。
具体连接方式为:
·4x4矩阵键盘连接PORTA。
·1602的8位数据位的低四位连接PORTB的低四位,高四位连接PORTC的高四位。RS连接PD5,R/W连接PD6,E连接PD7。
·GPRS模块连接USART接口(PD0和PD1)。
·麦克风的信号口连接GPRS模块的MIC+接口。VCC和GND正常接。
第二步·刷上示例代码。具体方式参考我的博客,blog.csdn.net/daqianc/article/details/53199571。当然可以采用别的方式。
恭喜你,你现在应该有一个YY手机了。对着代码尽情玩耍吧。
(上面照片在制作过程中拍摄,与最终用户界面不同)
下面对代码做一些简单的说明。
首先,程序以模块化方式编写。每个模块都有各自对应的函数,以完成本模块的基本功能。
第二,主函数负责调动初始的功能选择操作,包括:打电话、发短信、发邮件、拍照片。在主函数循环中,串口中断打开,此时可以接电话。当进入某一功能的流程中后,串口中断关闭,不能接电话。这主要是为了逻辑简单而偷懒。
第三,在程序开始时有长约一分钟的初始化时间,是用来让GPRS模块注册并附着GPRS网络的。在信不不强的地区时长可能不够,尽管手机使用起来没有异常,但是功能会失效。
第四,GPRS模块命令处理需要时长,处理完之后通常会返回信息,例如“OK”等。例如在给附着GPRS网络的命令之后,会有大概五秒的等候时长。在本程序中为了简化,没有等待串口接收“OK”,而是等一个模糊的时长。这显然不是最好的,因为有的时候等候的时长超过了设置的值,这时如果用户进行了下一步操作,则两条指令都会失效,并且会对后面的操作产生影响;有兴趣的读者可以自己修改完善这方面的程序。
以下是完整代码
/*
* 1602LCD.c
*
说明:
所有const uchar table_xxx[] 的字符串常亮定义,都是用来显示的
所有uchar AT_xxx[] 的字符串定义,都是要通过串口发送给GSM模块的AT指令
仅在空闲(没有正在进行的任务)时可以接电话,正在执行其他任务时串口中断关闭,导致不可接电话
* Created: 2016/10/8 15:07:04
* Author : DaqianC
*/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 11059200UL
#include <util/delay.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
//一些关于1602屏的操作宏定义
#define LCDRS_SET (PORTD |= 0x20)
#define LCDRS_CLR (PORTD &= 0xdf)
#define LCDRW_SET (PORTD |= 0x40)
#define LCDRW_CLR (PORTD &= 0xbf)
#define LCDEN_SET (PORTD |= 0x80)
#define LCDEN_CLR (PORTD &= 0x7f)
//三个全局数组长度的宏定义
#define LIST_NUM_LENGTH 20
#define LIST_STR_LENGTH 150
#define LIST_RC_LENGTH 70
unsigned char array_num[LIST_NUM_LENGTH];//全局数组,用于存储数字输入模式下从键盘输入的数字串(ASCII码值)
unsigned char array_str[LIST_STR_LENGTH];//全局数组,用于存储字符输入模式下从键盘输入的字符串
volatile unsigned char array_rc[LIST_RC_LENGTH];//作为串口接收缓冲池
volatile unsigned char array_rc_index = 0;//作为串口接收缓冲池的TOP
const unsigned char table_Home[] = " YY PHONE";//凡是const uchar=table_...的,都是用来显示的字符串
const unsigned char table_option[] = " A B C D";
//1602显示屏相关函数声明
void lcd_write_cmd(uchar cmd);//向1602屏发送指令
unsigned char read_cmd(void);//读取1602的指令
void lcd_write_data(uchar inf);//向1602屏发送要显示的内容
void init_lcd(void);//初始化1602屏
void clear_display(void);//清空显示
void display_string(const unsigned char*);//显示一个字符串
void lcd_delete(void);//从光标处删除上一个字符
//USART相关函数声明
void USART_init(void);//初始化USART
unsigned char receive_byte(void);//接收一个字符
void USART_transmit_byte(unsigned char data);//发送一个字符
void USART_transmit_str(unsigned char* str);//发送一个字符串
void USART_RX_Proc(void);//处理串口接收缓冲池中的字符串
//GSM模块相关函数声明
void GSM_init(void);//初始化GSM模块
void GSM_SMS(void);//发送短信
void GSM_call(void);//打电话
void GSM_RcCall(void);//接电话
void GSM_mail(v