文档库 最新最全的文档下载
当前位置:文档库 › 2012102236+陈柳茜

2012102236+陈柳茜

2012102236+陈柳茜
2012102236+陈柳茜

四川师范大学成都学院计算机学院

嵌入式系统课程设计

简易电子计算器的设计与实现

学生姓名陈柳茜

2012102236

学号

所在学院计算机学院

专业名称计算机科学与技术技术

班级2012级网络技术方向

指导教师

刘强

成绩

四川师范大学成都学院

二○一五年六月

摘要

单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活中的各个领域,电子、科技、通信、汽车、工业等。我们这次设计的科学计算器就是利用STM32单片机制作而成。

计算器(calculator)一般是指“电子计算器”,该名词由日文传入中国。计算器是能进行数学运算的手持机器,拥有集成电路芯片,结构简单,功能较弱,但由于它使用方便、操作简单、价格低廉,因而广泛运用于商业交易中,也是必备的办公用品之一。

为了进行大量浮点数的运算,并且能很好的支持彩屏的显示,我们选用了计算能力较强的基于Cortex-M3系列的STM32单片机作为微控制器。

STM32系列是32位单片机,运算能力远比其他单片机强,基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核。时钟频率高达72MHz,远远高于51、AVR等单片机。从闪存执行代码,STM32功耗36mA,是32位市场上功耗最低的产品,相当于0.5mA/MHz。

关键词:STM32、单片机、触摸屏、计算器

目录

摘要 (1)

目录 (2)

I. 引言 (4)

II. 总体方案设计 (5)

2.1 任务与要求 (5)

2.1.1 设计要求 (5)

2.1.2.技术指标 (5)

2.2方案论证 (5)

2.2.1单片机系统的选型 (5)

2.2.2显示屏的选型 (6)

2.3系统总体设计 (6)

III. 系统硬件要求 (6)

3.1微控制器简介 (6)

3.2触摸屏模块简介 (7)

3.2.1显示部分简介 (7)

3.2.2触摸部分简介 (9)

3.2.3单片机和触摸屏接口 (10)

IV. 系统软件设计 (12)

4.1系统各个模块初始化 (12)

4.2显示模块程序设计 (13)

4.3实现运算表达式的程序设计 (17)

V. 出现的错误及解决方法 (20)

5.1出错现象 (20)

5.2解决办法 (21)

VI. 总结 (23)

VII. 附录 (24)

7.1.1使用的仪器清单 (24)

7.1.2 主要代码 (24)

参考文献: (31)

I.引言

最早的计算工具诞生在中国。

中国古代最早采用的一种计算工具叫筹策,又被叫做算筹。这种算筹多用竹子制成,也有用木头、兽骨充当材料的,约二百七十枚一束,放在布袋里可随身携带。

直到今天仍在使用的珠算盘,是中国古代计算工具领域中的另一项发明,明代时的珠算盘已经与现代的珠算盘几乎相同。

17世纪初,西方国家的计算工具有了较大的发展。英国数学家纳皮尔发明了“纳皮尔算筹”,英国牧师奥却德发明了圆柱形对数计算尺,这种计算尺不仅能做加减乘除、乘方、开方运算,甚至可以计算三角函数、指数函数和对数函数。这些计算工具为现代计算器的发展奠定了良好的基础。

1642年,年仅19岁的法国伟大科学家帕斯卡引用算盘的原理,发明了第一部机械式计算器。在他的计算器中有一些互相联锁的齿轮,一个转过十位的齿轮会使另一个齿轮转过一位,人们可以像拨电话号码盘那样,把数字拨进去,计算结果就会出现在另一个窗口中,但是只能做加减计算。1694年,莱布尼兹在德国将其改进成可以进行乘除的计算。此后,到了20世纪50年代末,电子计算器问世。

本文设计的是一种基于STM32科学计算器的设计,通过触摸屏进行人机交互,按键直接显示在触摸屏上,不需要传统的机械按键,并且可以在需要键盘的时候才调出来。传统的机械按键需要占用单片机大量的I/O口,而触摸屏只需要通过SPI接口和单片机通信。

II.总体方案设计

2.1 任务与要求

2.1.1 设计要求

采用ARM芯片设计一个具有“+、-、×、÷”基本功能的计算器

在开发板的显示屏上设计并显示一个简易的计算器界面,包括结果显示窗、0-9数字键、“+、-、×、÷、=、Del”等按键

可使用开发板上的键盘输入上述按键,并在显示窗口计算结果。

根据系统要求选择ARM芯片、存储器芯片、显示模块和电源芯片等

撰写设计报告(包括芯片选取,设备地址分配、芯片引脚连接等)

撰写设计方案,包括主要函数定义、程序流程,并附主要函数代码。

实现触摸控制,普通加、减、乘、除的计算,平方根、平方的计算

2.1.2.技术指标

精确到小数点后6位。

计算的范围为-3.4×10-38~3.4×1038。

实时显示计算表达式和结果。

2.2方案论证

2.2.1单片机系统的选型

从单片机芯片主要性能角度出发,本计算器单片机芯片选择设计采用方案一既stm32触摸板,半导体的单片机具有良好的性价比、低功耗、易开发等特点,

而且其体系和架构资料丰富,用它能够快速的开发出整个系统。

2.2.2显示屏的选型

现有的液晶显示屏的种类很多,我们选用的是2.8寸带触摸的彩屏,320×

240的分辨率,支持16位色,16位数据接口,这个就足够我们使用了。有了触

摸的控制,就可以省掉传统的机械按键,直接在屏幕上显示按键。

2.3系统总体设计

根据设计要求和模块选型系统总体方案设计如图1。本系统主要是在触摸屏

上显示各种信息文本,所以硬件电路比较简洁,不需要很多硬件。PC 机通过RS232

串行接口和STM32进行数据通信,STM32和显示屏通过16位并行接口通信,和

触摸板通过SPI 接口进行通信。

图片 1

III. 系统硬件要求

3.1微控制器简介

为了进行大量浮点数的运算,并且能很好的支持彩屏的显示,我们选用了计STM32最小

系统 PC 机 触摸屏

24C02

算能力较强的基于Cortex-M3系列的STM32F103ZET6作为微控制器。

Cortex-M3是ARM公司研发的一个系列,针对于微控制开发领域,采用ARMv7-M架构,它包括所有的16位Thumb指令集和基本的32位Thumb-2指令集架构。Thumb-2在Thumb指令集架构(ISA)上进行了大量的改进,它与Thumb 相比,具有更高的代码密度并提供16/32位指令的更高性能。

ARM的Cortex-M3处理器是最新一代的嵌入式ARM处理器,它为实现MCU的需要提供了低成本的平台、缩减的引脚数目、降低的系统功耗,同时提供卓越的计算性能和先进的中断系统响应。

ARM的Cortex-M3是32位的RISC处理器,提供额外的代码效率,在通常8和16位系统的存储空间上发挥了ARM内核的高性能。

我们采用的意法半导体公司生产的STM32F103ZET6就是基于ARM Cortex-M3内核的,具有高性能、低成本、低功耗等特点,最高主频可达72MHz,高达512K 字节的闪存和64K字节的SRAM,112个GPIO端口,4个通用定时器,2个高级控制定时器,2个基本定时器,还包含标准和先进的通信接口:多达2个I2C接口、3个SPI接口、2个I2S接口、1个SDIO接口、5个USART接口、一个USB接口和一个CAN接口。

3.2触摸屏模块简介

3.2.1显示部分简介

TFT-LCD即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal Display。TFT-LCD与无源TN-LCD、STN-LCD的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD也被叫做真彩液晶显示器。

TFT液晶显示屏的特点是亮度好、对比度高、层次感强、颜色鲜艳,但也存在着比较耗电和成本过高的不足。

TFT型的液晶显示器主要的构成包括:萤光管、导光板、偏光板、滤光板、玻璃基板、配向膜、液晶材料、薄模式晶体管等等。

TFTLCD模块采用80并口方式与外部连接,采用16位数据线该模块的80并口有如下一些信号线:

CS:TFTLCD片选信号。

WR:向TFTLCD写入数据。

RD:从TFTLCD读取数据。

D[15:0]:16位双向数据线。

RST:硬复位TFTLCD。

RS:命令/数据标志(0,读写命令;1,读写数据)。

TFTLCD模块的RST信号线直接接到STM32的复位脚上,并不由软件控制,这样可以省下来一个IO口。另外我们还需要一个背光控制线来控制TFTLCD的背光。所以,我们总共需要的IO口数目为21个。

我们这里使用的是RGB模式,RGB色彩就是常说的三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色)。之所以称为三原色,是因为在自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成,因此也称为加色模式。RGB模式又称RGB色空间。它是一种色光表色模式,它广泛用于我们的生活中,如电视机、计算机显示屏、幻灯片等都是利用光来呈色。

比如我们要显示红色,就用F800H来表示,绿色就是07E0H,蓝色001FH,三种混合起来就是白色,也就是FFFFH。

触摸屏图片如下:

图片 2

3.2.2触摸部分简介

我们一般液晶所用的触摸屏,最多的就是电阻式触摸屏了(多点触摸属于电容式触摸屏,比如M8,IPhone等支持多点触摸的手机所用的屏就是电容式的触摸屏),TFTLCD自带的触摸屏属于电阻式触摸屏,下面简单介绍下电阻式触摸屏的原理。

电阻式触摸屏利用压力感应进行控制。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据获得的位置模拟鼠标的方式运作。这就是电阻技

术触摸屏的最基本的原理。

电阻屏的特点有:

1)是一种对外界完全隔离的工作环境,不怕灰尘、水汽和油污。

2)可以用任何物体来触摸,可以用来写字画画,这是它们比较大的优势。

3)电阻触摸屏的精度只取决于A/D转换的精度,因此都能轻松达到4096*4096。

从以上介绍可知,触摸屏都需要一个AD转换器,一般来说是需要一个控制器的。TFTLCD模块选择的是四线电阻式触摸屏,这种触摸屏的控制芯片有很多,包括:ADS7843、ADS7846、TSC2046、XPT2046和AK4182等。这几款芯片的驱动基本上是一样的,也就是你只要写出了ADS7843的驱动,这个驱动对其他几个芯片也是有效的。而且封装也有一样的,完全pin to pin。所以在替换起来,很方便。

TFTLCD模块自带的触摸屏控制芯片为XPT2046。XPT2046是一款4导线制触摸屏控制器,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器。XPT2046支持从1.5V到5.25V的低电压I/O接口。XPT2046能通过执行两次A/D转换查出被按的屏幕位置,除此之外,还可以测量加在触摸屏上的压力。内部自带2.5V 参考电压可以作为辅助输入、温度测量和电池监测模式之用,电池监测的电压范围可以从0V到6V。XPT2046片内集成有一个温度传感器。在2.7V的典型工作状态下,关闭参考电压,功耗可小于0.75mW。XPT2046采用微小的封装形式:TSSOP-16,QFN-16(0.75mm厚度)和VFBGA-48。工作温度范围为-40℃~+85℃。

3.2.3单片机和触摸屏接口

如图所示为系统的触摸屏接口,

图片3

各引脚定义如下:

LCD_CS:TFTLCD片选信号。

LCD_WR:向TFTLCD写入数据。

LCD_RD:从TFTLCD读取数据。

LCD_D[15:0]:16位双向数据线。

RESET:硬复位TFTLCD。

LCED_RS:命令/数据标志(0,读写命令;1,读写数据)。LCD_BL:触摸屏背光源的控制引脚。

T_MISO:触摸屏串行数据输出端。

T_MOSI:触摸屏串行数据输入端。

T_SCK:触摸屏时钟信号端。

T_CS:触摸屏片选端。

IV.系统软件设计

4.1系统各个模块初始化

系统上电或复位后,首先进行各个模块的初始化,其流程图如图所示。

开始

系统时钟初始化

延时初始化

LCD初始化

按键初始化

触摸屏初始化

禁用JTAG、SWD

显示计算器的输

入界面

图片4

4.2显示模块程序设计

显示模块程序由LCD初始化程序和定时器中断程序,首先由LCD初始化程序将屏幕上需要显示的按键显示,再由定时器中断程序定时刷新屏幕显示表达式的区域,将输入的表达式实时显示出来。

LCD初始化流程图如下:

开始

使能GPIOB、GPIOC时钟

开启辅助时钟

设置GPIOB、GPIOC为推挽输出

向LCD 写初始化指令

开启背光源

图片5

LCD初始化程序设计:

/*********************************************

* 函数名称:void LCD_Init(void)

* 函数功能:初始化LCD

* 输入参数:无

* 输出参数:无

*********************************************/

void LCD_LED_Init(void) //LCD背光初始化设置

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_SetBits(GPIOA, GPIO_Pin_1);

}

其它模块初始化:

int main(void)

{

NVIC_Configuration(); //中断分组初始化

XT2046_Touch_Init(); //触摸屏初始化

ili9320_Init(); //液晶初始化

Buzzer_Init(); //蜂鸣器初始化

while(1)

{

Touch_Key_Scan(); //计算器处理

}

显示模块:

struct typFNT_key

{

unsigned char mesg1;

unsigned char mesg2[4];

};

struct typFNT_key key_mesg[] = //界面对应显示字符

{

'0'," .",

'1'," +",

'2'," -",

'3'," *",

'4'," /",

'5',"开方",

'6',"平方",

'7',"取余",

'8',"清零",

'9',"等于"

};

/******************************************************************** ****************************/

void TFT_keyboard_draw(void) //计算机界面绘制

{

unsigned short i=0,dat=0,S_number=0;

Unsigned short x_vale1=0,y_vlaue1=0,x_vale2=0,y_vlaue2=0;

Char strs[5]={0},strint_temp[5]={0},strint_temp2[6]={0};

GUI_CNCH16_string(85,10,(uint8_t *)"嵌入式计算机",Blue,White);

GUI_CNCH16_string(95,30,(uint8_t *)"欢迎使用",Red,White);

//-------------------------------------------------------------------------

GUI_Rectangle(10, 50, 310, 75, Black,0);

for(i=0;i<20;i++)

{

x_vale1=KEY_value1[i][0];

y_vlaue1=KEY_value1[i][1];

x_vale2=KEY_value2[i][0];

y_vlaue2=KEY_value2[i][1];

GUI_Rectangle(x_vale1, y_vlaue1, x_vale2, y_vlaue2, Black,1); //画矩形和填充

GUI_Rectangle(x_vale1, y_vlaue1, x_vale2, y_vlaue2, Red,0); //画矩形边框

if(S_number<10)

{

sprintf(strs,"%c",key_mesg[i].mesg1);

GUI_CNCH24_string(x_vale1+15, y_vlaue1,(uint8_t *)strs,White,Black);

}

else

{

for(dat=0; dat<4; dat++)

{

strint_temp[dat]=key_mesg[i-10].mesg2[dat];

}

sprintf(strint_temp2,"%s",strint_temp);

GUI_CNCH16_string(x_vale1+10, y_vlaue1+10,(uint8_t *)strint_temp2,White,Black);

}

S_number++;

}

GUI_CNCH16_string(80,223,(uint8_t *)"我们的小组",Blue,White);

}

/******************************************************************** ****************************/

4.3实现运算表达式的程序设计

当我们把表达式输入完,单片机就要对表达式进行求解,这个过程就叫做解

析表达式。

首先建立两个堆栈,分别叫做数值栈和符号栈。我们规定一个记号#,来表示栈底。下面我们就来看看如何计算一个简单的表达式:

3+5+6×7×8^2^3 (8^2指的是82)

这里运算有三种优先级“^”>“×”>“+”,如何实现优先级运算呢?递归下降算法的核心就是一下几点:

开始:

1.如果当前输入串中得到的是数字,则直接压入值栈,然后转到开始。

2.如果当前输入串中得到的是符号,那么对符号进行判断:

1)如果是第一个符号,则直接压入符号栈;

2)如果符号比上一个符号的优先级高,则压入符号栈;

3)如果符号比上一个符号的优先级低或者相等,则弹出栈进行运算,直到比上一个符号的优先级高;

5)如果符号是‘(’,则直接压入符号栈;

4)如果符号是‘)’,则依照符号栈的顺序弹出符号,计算栈中数值,把结果压入值栈,直到符号栈顶是‘(’,最后再弹出‘(’。最后转到开始。

3.如果当前输入串得到的是EOF(字符串结束符号),则计算栈中数值,直到符号栈没有符号。

对于上面的表达式就这样计算:

1.将3、‘+’、5压入堆栈;

2.现在遇到‘+’号,和上一个运算符‘+’比较,相等,则计算“3+5”,

表达式变为8+6×7×8^2^3;

3.6压入数值栈,‘×’比‘+’高,压入符号栈;

4.再将7压入数值栈,‘×’和上一个符号相同,就计算“6×7”,表达

式变为8+42×8^2^3;

5.8压入符号栈,‘^’比上一个符号高,压栈;

6.2压入符号栈,‘^’和上一个相同,计算“8^2”,表达式变为8+42

×64^3;

7.继续,8+42×262144;

8.继续,8+1.101×107;

9.最后得出结果,1.101×107。如图所示:

图片 6

可以看出,如果利用操作数堆栈和运算符堆栈的话,只要:

1.步进扫描表达式。

2.遇到操作数就压入操作数堆栈中,遇到运算符就将它的优先级与运算符堆栈栈顶运算符的优先级比较,如果它的优先级更大,就将它压入堆栈,否则就将栈顶运算符弹出来进行运算。

只要这样就可以实现优先级的运算。

对于一个合法的简单数学表达式,肯定是一个操作数跟着一个运算符,第一

相关文档