历史上的今天
今天是: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)
{
史海拾趣
|
电池供电设备,不管是电动牙刷、剃须刀、手机、个人数字助理(PDA)、MP3播放器,还是手无法够到的遥控设备,都成为人们日常生活的一部分。因此,电源管理对当今的嵌入式设计工程师来说是一件相当重要的的事。普遍存在的微控制器在许多设备的应用中为 ...… 查看全部问答> |
|
目录: 1 微机——一种全新的工具 1.1 微机的用途 1.2 控制用微机的作用 1.3 通过流程图了解微机控制的工作内容 本章要点 练习题 2 微机的组成结构 2.1 微机的分类 2.2 CPU 2.3 存储器 2.4 I/O口 本章要点 练习题 3 微机数学ABC 3 ...… 查看全部问答> |
|
1>MultiSourceFilter.obj : error LNK2019: 无法解析的外部符号 \"public: __cdecl CSource::CSource(unsigned short *,struct IUnknown *,struct _GUID)\" (??0CSource@@QAA@PAGPAUIUnknown@@U_GUID@@@Z),该符号在函数 \"public: __cdecl MultiSo ...… 查看全部问答> |
|
我的亿捷E901移动硬盘 原来是NTFS文件格式,被我不小心格式化为ext3文件格式了! 试过finaldata 和 easyrecovery 都无法恢复,因为在Windows下无法找到ext3文件系统(硬盘现在的文件格式). 请高手献策!!!!!!!!! ...… 查看全部问答> |
|
这是本人调试nandflash 的时候出现的问题。 平台是:WinCE 5.0 用的nandflash是:K9F5608U0D 板子是自己的,不是Samsung.控制器和三星的也不一样。 谢谢了,下面是调试信息。Thank you! 4294769951 PID:edfc330e TID:edfc32ea ...… 查看全部问答> |
|
仿真时设置和testbench的编写都是按照资料上做的,可是调出modulesim—altera仿真时没有反应,左下角显示VSIM(paused),右面变量栏里没有任何变量?… 查看全部问答> |
|
在综合的时候把模拟模块当成黑盒子处理,模拟管脚PAD综合时有warning提示no match pad founa for XX_port......no pad will inserted....,用formality做RTL 和netlist的形式验证时,verify后在模拟管脚(即黑盒子输入)有failing。。。 ...… 查看全部问答> |




