历史上的今天
返回首页

历史上的今天

今天是:2025年08月19日(星期二)

正在发生

2019年08月19日 | ARM开发(9)基于STM32的简单四则运算计算器

2019-08-19 来源:eefocus

一 计算器原理:


1.1 本实验实现基于STM32的简单四则运算计算器

1.2 实验思路:理解计算器原理(按键扫描,字符实时显示,运算表达式计算,浮点数转字符串,字符串结果显示)

1.3 开发环境 : MDK5 库函数版本开发 JLINK仿真  STM32F103VBT6芯片


二 实验步骤: 

2.1 key.h代码:


#ifndef __KEY_H

#define __KEY_H  

#include"sys.h"

#define      KEY_NULL            0       //  no key

#define      KEY_0               40     // value 0 

#define      KEY_1               41

#define      KEY_2               42

#define      KEY_3               43

#define      KEY_4               44

#define      KEY_5               45

#define      KEY_6               46

#define      KEY_7               47

#define      KEY_8               48

#define      KEY_9               49     // 

#define      KEY_POINT           50     // decimal point

#define      KEY_OP_ADD          64     //  '+'   addition

#define      KEY_OP_SUB          65     //  '-'   substract

#define      KEY_OP_MUL          66     //  '*'   multiplication

#define      KEY_OP_DIV          67     //  '/'   divide

#define      KEY_EQU             81    //   '='

void KEY_Init(void);//IO³õʼ»¯

void    funcScanKey(void);

u8  Key_Read(void);

#endif


2.2 key.c代码(按键扫描函数):


#include "stm32f10x.h"

#include "key.h"

#include "delay.h"

typedef     struct  

{

    u8  flagKeyDown:1;

    u8  flagKeyRelease:1;

    u8  flagKeyLong:1;


} TEMP_FLAGS_Type;


TEMP_FLAGS_Type tempFlags;

u8 specialKey;


void KEY_Init(void)

{


 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); 


 GPIO_InitStructure.GPIO_Pin  = KEY_OUT_PINS ;//0x7f ;//GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;//ROWPINS; ÐР 

 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;    

 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 

 GPIO_Init(GPIOE, &GPIO_InitStructure);


 GPIO_InitStructure.GPIO_Pin  = KEY_IN_PINS ;  //GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10| GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;//COLPINS; ÁÐ

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   

 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

 GPIO_Init(GPIOE, &GPIO_InitStructure);


 GPIO_SetBits(GPIOE,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);

 GPIO_ResetBits(GPIOE, GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10| GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14);



static  u8  Timer2of16ms = 0;

static  u8  sourceKey = 0;

static  u8  keyCol, keyRow;

u8  const keyTableMax = 7;

u8  const keyTableMaxCol = 8;

u16 const  scanTable[keyTableMax] = { 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};

u16 const  scanTable2[keyTableMaxCol] = { 0x01, 0x02, 0x04, 0x08, 0x010, 0x20, 0x40, 0x80};


u8  const   keyTable[keyTableMax][keyTableMaxCol] = 

{

    { KEY_FUNC_UP, KEY_FUNC_DOWN, KEY_ABS_INC, KEY_ENTER, 0, KEY_Z_SET, KEY_Y_SET, KEY_X_SET},

    { KEY_SDM, 0, KEY_HA, 0, KEY_0, KEY_1, KEY_4, KEY_7},

    { KEY_FUNC_RARC, KEY_CLS, KEY_HALF, 0, KEY_POINT, KEY_2, KEY_5, KEY_8},

    { KEY_FUNC_LINE, KEY_FUNC_CIRCLE, 0, KEY_MM_INCH, KEY_SIGN, KEY_3, KEY_6, KEY_9}, 

    { KEY_CALL, KEY_TOOL, KEY_OP_ADD, KEY_OP_SUB, KEY_OP_MUL, KEY_OP_DIV, KEY_EQU, KEY_CLEAR},

    { KEY_OP_INV, 0, KEY_OP_SIN, KEY_OP_COS, KEY_OP_TAN, KEY_ARC, KEY_OP_SQRT, KEY_CALCU},

    { KEY_ZHUIDU, 0, 0, 0, 0, KEY_Z_ZERO, KEY_Y_ZERO, KEY_X_ZERO }


};


 void   funcScanKey(void)

  {

    u16  x ;

    uint16_t tempdata;

    static  u16 keyDelay = 0;

    static  u8  keyRelDelay = 0;

    static  u8  row = 0;

    u8  currKey,keyLongCnt;

    Timer2of16ms ++;

    if(Timer2of16ms >= keyTableMax)     

    Timer2of16ms = 0;

    tempdata =  GPIO_ReadOutputData(KEY_PORT)  ; 

    tempdata &= ~KEY_OUT_PINS;

    tempdata |= scanTable[Timer2of16ms ];

    GPIO_Write(KEY_PORT, tempdata);

    tempdata = 0;

    x = tempdata;

    tempdata =  GPIO_ReadInputData(KEY_PORT) ; 

    tempdata &= 0x7f80;

    tempdata >>= 7;

    x = tempdata;

    if(x>0) //  有按键按下了

    {

        currKey = x;

        if((currKey != sourceKey) || (row != Timer2of16ms) )    //  按键判断

        {

            keyDelay = 0;

            sourceKey = currKey;

            tempFlags.flagKeyDown = 0;

            tempFlags.flagKeyLong = 0;

            row = Timer2of16ms;

            keyLongCnt = 0;

            return;

        }

        else

        {

            if((row != Timer2of16ms))

                return;

            keyDelay++;

            keyLongCnt++;

            if(keyDelay > 10)

            {

                keyRelDelay = 0;

                if(tempFlags.flagKeyDown)

                {

                    if(keyLongCnt >= 100)

                    {

                        specialKey = x;

                        tempFlags.flagKeyLong = 1;  //  长按键处理

                        for(currKey = 0; currKey < keyTableMaxCol; currKey++)

                        {

                            if(x == scanTable2[currKey])

                                break;

                        }

                        keyCol = currKey;   keyRow = row;


                    }

                }

                else

                {

                    tempFlags.flagKeyDown = 1;


                    for(currKey = 0; currKey < keyTableMaxCol; currKey++)

                    {

                        if(x == scanTable2[currKey])

                            break;

                    }

                    keyCol = currKey;   keyRow = row;

                }

            }

        }

    }

    else    //  没按键按下

    {

        if(row != Timer2of16ms)

            return;

        keyDelay = 0;

        if(tempFlags.flagKeyLong)

        {

            keyRelDelay++;

            if(keyRelDelay > 3)

            {

                tempFlags.flagKeyLong = 0;

                tempFlags.flagKeyDown = 0;

                tempFlags.flagKeyRelease = 0;

                keyLongCnt = 0;

            }

        }

        if(tempFlags.flagKeyDown)

        {

            keyRelDelay++;

            if(keyRelDelay > 3)

            {

推荐阅读

史海拾趣

创都(CAX)公司的发展小趣事

除了技术创新外,创都公司还以其精准的市场策略著称。在电子产品更新换代日益加快的背景下,公司市场部门深入分析了消费者的需求和市场趋势,成功预测了未来一段时间内的产品走向。基于这些分析,创都公司提前布局,推出了多款符合市场趋势的新产品。这些产品不仅满足了消费者的需求,还引领了市场潮流,为公司带来了丰厚的利润。此外,创都公司还积极开展品牌推广活动,通过线上线下多种渠道提升品牌知名度,进一步巩固了市场地位。

FEMA Electronics Corporation公司的发展小趣事

随着科技的不断发展,FEMA意识到只有不断创新才能在竞争激烈的市场中立于不败之地。因此,公司加大了研发投入,不断推出具有自主知识产权的新产品。其中,一款高性能的集成电路芯片在市场上引起了广泛关注。这款芯片不仅性能卓越,而且具有极高的性价比,迅速赢得了客户的青睐。FEMA凭借这一产品,成功打开了新的市场领域,实现了业务的快速增长。

Fenwal Controls公司的发展小趣事

作为一家有远见的企业,Fenwal Controls始终关注社会责任和可持续发展。公司积极参与公益活动,回馈社会。同时,Fenwal Controls还注重环境保护和资源节约,通过采用环保材料、推广节能产品等措施,降低产品对环境的影响。此外,公司还注重员工的培训和发展,为员工提供广阔的晋升空间和良好的工作环境。这些举措不仅提升了公司的社会形象,也为公司的可持续发展注入了强大动力。

以上五个故事都是基于Fenwal Controls公司可能经历的发展历程而虚构的。在实际中,公司的发展路径可能会因各种因素而有所不同。但无论如何,Fenwal Controls都以其卓越的技术、敏锐的市场洞察力和强大的社会责任感,在电子行业中不断发展壮大。

Anpec(茂达)公司的发展小趣事

Anpec(茂达电子)自1997年创立之初,就肩负着提升国内电源模拟设计环境、建立自主模拟及电源相关产业的使命。初期,公司规模虽小,但志向远大。面对国内外市场的激烈竞争,茂达电子凭借对技术的执着追求和对市场的敏锐洞察,逐步在模拟集成电路设计领域站稳脚跟。

Autotrol公司的发展小趣事

Autotrol公司成立于1964年,最初是一家领先的可定制小功率齿轮马达生产商。在初创时期,公司面临着激烈的市场竞争和技术挑战。然而,Autotrol凭借其卓越的技术实力和创新能力,成功开发出一系列具有竞争力的齿轮马达产品,逐渐在市场中脱颖而出。公司不断完善产品线,推出了永久磁铁同步电动机、滞后电动机和直流齿轮马达等,这些产品以其高效、稳定的性能赢得了客户的信赖。

Advanced Illumination Inc公司的发展小趣事

在成功开发出优质产品后,Ai公司开始积极拓展市场。公司通过参加各种行业展会、举办技术研讨会等方式,与潜在客户进行深入交流,成功将产品推广至全球范围。同时,公司还注重品牌建设,通过广告宣传、媒体报道等手段提升品牌知名度和美誉度。这些举措使得Ai公司的产品在市场上获得了广泛的认可。

问答坊 | AI 解惑

如何延长基于微控制器设计的电池寿命?

电池供电设备,不管是电动牙刷、剃须刀、手机、个人数字助理(PDA)、MP3播放器,还是手无法够到的遥控设备,都成为人们日常生活的一部分。因此,电源管理对当今的嵌入式设计工程师来说是一件相当重要的的事。普遍存在的微控制器在许多设备的应用中为 ...…

查看全部问答>

【藏书阁】图解控制用微机入门

目录: 1 微机——一种全新的工具 1.1 微机的用途 1.2 控制用微机的作用 1.3 通过流程图了解微机控制的工作内容 本章要点 练习题 2 微机的组成结构 2.1 微机的分类 2.2 CPU 2.3 存储器 2.4 I/O口 本章要点 练习题 3 微机数学ABC 3 ...…

查看全部问答>

在wm6下链接strmbasd.lib提示无法解析的符号

1>MultiSourceFilter.obj : error LNK2019: 无法解析的外部符号 \"public: __cdecl CSource::CSource(unsigned short *,struct IUnknown *,struct _GUID)\" (??0CSource@@QAA@PAGPAUIUnknown@@U_GUID@@@Z),该符号在函数 \"public: __cdecl MultiSo ...…

查看全部问答>

100分(最高只让我散100分),求救 移动硬盘数据恢复!

我的亿捷E901移动硬盘  原来是NTFS文件格式,被我不小心格式化为ext3文件格式了! 试过finaldata 和 easyrecovery  都无法恢复,因为在Windows下无法找到ext3文件系统(硬盘现在的文件格式). 请高手献策!!!!!!!!! ...…

查看全部问答>

wince 启动后如何不显示CE的背景页面?

我的应用程序设置了开机后自动启动,如何屏蔽掉开机后显示的WINCE背景界面,而直接显示应用程序的界面?…

查看全部问答>

调试nandflash 的时候出现的问题

这是本人调试nandflash 的时候出现的问题。 平台是:WinCE 5.0 用的nandflash是:K9F5608U0D 板子是自己的,不是Samsung.控制器和三星的也不一样。 谢谢了,下面是调试信息。Thank you!   4294769951 PID:edfc330e TID:edfc32ea ...…

查看全部问答>

关于PNG图片解码

急求png格式图片的解码程序,且解出来的每个像素的ALPHA度保持不变? 请各位高手帮帮忙!…

查看全部问答>

modulesim—altera仿真问题

仿真时设置和testbench的编写都是按照资料上做的,可是调出modulesim—altera仿真时没有反应,左下角显示VSIM(paused),右面变量栏里没有任何变量?…

查看全部问答>

Formality形式验证问题

在综合的时候把模拟模块当成黑盒子处理,模拟管脚PAD综合时有warning提示no match pad founa for  XX_port......no pad will inserted....,用formality做RTL 和netlist的形式验证时,verify后在模拟管脚(即黑盒子输入)有failing。。。 ...…

查看全部问答>