stm32f103c8t6 实现计算器
时间: 2023-10-16 22:02:48 浏览: 220
首先,STM32F103C8T6是一种32位的ARM Cortex-M3微控制器,具有优秀的性能和丰富的外设。要实现一个计算器,我们可以利用STM32F103C8T6的高性能和丰富的外设来设计和实现。
首先,我们需要设计一个合适的用户界面,可以使用LCD显示屏或者OLED显示屏来显示数字和计算结果。然后,我们可以利用STM32F103C8T6的GPIO引脚连接键盘矩阵,用于用户输入数字和运算符。通过矩阵扫描和按键映射,我们可以获取用户的输入。
接下来,我们可以使用STM32F103C8T6的定时器和中断功能来实现计算器的按键响应和计算逻辑。我们可以为每个数字和运算符分配一个特定的中断处理函数,当用户按下相应的按键时,会触发对应的中断处理函数。在中断处理函数中,我们可以对用户输入进行处理,并根据用户的操作进行相应的计算。
在计算逻辑方面,我们可以使用C语言编写对数字和运算符的处理函数,例如实现加减乘除等运算。我们可以使用变量和数组来保存用户的输入和计算结果,并在LCD显示屏上实时显示。
最后,我们需要编写主循环程序,在循环中不断检测是否有按键按下,并根据按键的种类调用相应的中断函数进行处理。同时,我们还可以添加一些额外的功能,如清除输入、取反、小数点等。
总的来说,通过充分利用STM32F103C8T6的性能和外设,我们可以实现一个功能完善的计算器,具有良好的用户界面和计算逻辑。
相关问题
stm32f103c8t6实现计算器
### 使用STM32F103C8T6实现计算器功能
为了在STM32F103C8T6上实现一个简单的计算器功能,可以按照以下方式构建代码结构。此方案涉及矩阵键盘输入处理以及通过串口显示计算结果。
#### 头文件定义
首先创建必要的头文件用于声明函数原型和其他全局变量:
```c
#ifndef CALCULATOR_H_
#define CALCULATOR_H_
#include "stm32f10x.h"
#include "matrix_keyboard.h" // 假设已经实现了矩阵键盘接口
#include "usart.h"
void Calculator_Init(void);
float Calculate(char operator, float operand1, float operand2);
#endif /* CALCULATOR_H_ */
```
#### 初始化设置
初始化部分负责配置系统时钟、GPIO端口、USART模块和SysTick定时器等资源:
```c
// 定义一些宏来简化操作符识别过程
#define ADD '+'
#define SUB '-'
#define MUL '*'
#define DIV '/'
void SystemClock_Config(void){
// 配置系统时钟为内部RC振荡器作为源频率[^2]
}
void GPIO_Configuration(void){
// 对应于LED指示灯或其他外设的GPIO引脚配置
}
void USART_Configuration(void){
// 设置USART参数以便与PC通信并交换数据
}
```
#### 主循环逻辑
主程序会持续监听来自矩阵键盘的操作数及运算指令,并调用相应的子程序完成四则运算任务之后再经由UART传输回显信息至终端界面展示出来。
```c
int main(void){
char inputOperator;
float num1=0,num2=0,result;
HAL_Init(); // 初始化HAL库
SystemClock_Config();
GPIO_Configuration();
USART_Configuration();
while (true) {
if(KEY_GetKey(&inputOperator)){ // 获取当前按下的键值
switch(inputOperator){ // 判断是否为有效算术符号
case '0'...'9': // 数字字符范围
// 将ASCII码转换成实际数值累加到num1或num2中...
break; // 继续等待下一个按键
default : // 运算符或者其他特殊命令
result = Calculate(inputOperator , num1 , num2 );
sprintf((char*)aTxBuffer,"Result:%.2f\r\n",result);
HAL_UART_Transmit(&huart1,(uint8_t *)aTxBuffer,strlen((const char*)aTxBuffer),50);
// 清零准备下一轮计算
memset(aRxBuffer,'\0',sizeof(aRxBuffer));
num1=num2=result=0;
}
}
}
}
```
#### 计算服务例程
提供了一个辅助性的`Calculate()`方法用来执行具体的数学运算工作:
```c
float Calculate(char op,float a,float b){
switch(op){
case ADD :
return a+b ;
case SUB :
return a-b ;
case MUL :
return a*b ;
case DIV :
if(b!=0)return a/b ;else{return -1;} //除以零错误处理
default:
return -1; //非法操作符返回负一表示异常情况
}
}
```
stm32f103c8t6实现简易计算器
以下是基于STM32F103C8T6的简易计算器的实现方法:
1. 首先需要连接5110屏幕和4*4键盘到STM32F103C8T6开发板上。
2. 然后需要编写程序,实现基本的多位加减乘除功能。可以使用C语言编写程序,并使用Keil或者其他编译器进行编译。
3. 在程序中需要定义键盘输入的方式,并将输入的数字和运算符存储在变量中。
4. 然后需要编写算法,根据输入的数字和运算符进行计算,并将结果显示在5110屏幕上。
5. 最后需要测试程序,确保计算器能够正确地进行加减乘除运算。
以下是一个基于STM32F103C8T6的简易计算器的代码示例:
```c
#include "stm32f10x.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define ROW1 GPIO_Pin_0
#define ROW2 GPIO_Pin_1
#define ROW3 GPIO_Pin_2
#define ROW4 GPIO_Pin_3
#define COL1 GPIO_Pin_4
#define COL2 GPIO_Pin_5
#define COL3 GPIO_Pin_6
#define COL4 GPIO_Pin_7
void delay_ms(uint16_t nms)
{
uint32_t i;
for(i=0;i<nms*1000;i++);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = ROW1|ROW2|ROW3|ROW4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = COL1|COL2|COL3|COL4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void LCD5110_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void LCD5110_WriteByte(uint8_t data,uint8_t command)
{
uint8_t i;
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
if(command==0)
GPIO_SetBits(GPIOA,GPIO_Pin_1);
else
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
for(i=0;i<8;i++)
{
if(data&0x80)
GPIO_SetBits(GPIOA,GPIO_Pin_5);
else
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
data<<=1;
}
}
void LCD5110_Init(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0);
delay_ms(10);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
delay_ms(10);
GPIO_SetBits(GPIOA,GPIO_Pin_0);
LCD5110_WriteByte(0x21,1);
LCD5110_WriteByte(0xc8,1);
LCD5110_WriteByte(0x06,1);
LCD5110_WriteByte(0x13,1);
LCD5110_WriteByte(0x20,1);
LCD5110_WriteByte(0x0c,1);
}
void LCD5110_Clear(void)
{
uint16_t i;
for(i=0;i<504;i++)
LCD5110_WriteByte(0,0);
}
void LCD5110_Set_XY(uint8_t X,uint8_t Y)
{
LCD5110_WriteByte(0x40|Y,1);
LCD5110_WriteByte(0x80|X,1);
}
void LCD5110_Write_Char(uint8_t c)
{
uint8_t line;
uint8_t ch = 0;
uint16_t i;
for(i=0;i<5;i++)
{
ch = FontLookup[c-32][i];
LCD5110_WriteByte(ch,0);
}
}
void LCD5110_Write_String(uint8_t X,uint8_t Y,char *s)
{
LCD5110_Set_XY(X,Y);
while(*s)
{
LCD5110_Write_Char(*s++);
}
}
void LCD5110_Write_Num(uint8_t X,uint8_t Y,uint32_t num)
{
char str[10];
sprintf(str,"%d",num);
LCD5110_Write_String(X,Y,str);
}
uint8_t KeyScan(void)
{
uint8_t keyvalue = 0xff;
GPIO_ResetBits(GPIOA,ROW1);
if(GPIO_ReadInputDataBit(GPIOB,COL1)==0)
keyvalue = 1;
if(GPIO_ReadInputDataBit(GPIOB,COL2)==0)
keyvalue = 2;
if(GPIO_ReadInputDataBit(GPIOB,COL3)==0)
keyvalue = 3;
if(GPIO_ReadInputDataBit(GPIOB,COL4)==0)
keyvalue = 10;
GPIO_SetBits(GPIOA,ROW1);
GPIO_ResetBits(GPIOA,ROW2);
if(GPIO_ReadInputDataBit(GPIOB,COL1)==0)
keyvalue = 4;
if(GPIO_ReadInputDataBit(GPIOB,COL2)==0)
keyvalue = 5;
if(GPIO_ReadInputDataBit(GPIOB,COL3)==0)
keyvalue = 6;
if(GPIO_ReadInputDataBit(GPIOB,COL4)==0)
keyvalue = 11;
GPIO_SetBits(GPIOA,ROW2);
GPIO_ResetBits(GPIOA,ROW3);
if(GPIO_ReadInputDataBit(GPIOB,COL1)==0)
keyvalue = 7;
if(GPIO_ReadInputDataBit(GPIOB,COL2)==0)
keyvalue = 8;
if(GPIO_ReadInputDataBit(GPIOB,COL3)==0)
keyvalue = 9;
if(GPIO_ReadInputDataBit(GPIOB,COL4)==0)
keyvalue = 12;
GPIO_SetBits(GPIOA,ROW3);
GPIO_ResetBits(GPIOA,ROW4);
if(GPIO_ReadInputDataBit(GPIOB,COL1)==0)
keyvalue = 14;
if(GPIO_ReadInputDataBit(GPIOB,COL2)==0)
keyvalue = 0;
if(GPIO_ReadInputDataBit(GPIOB,COL3)==0)
keyvalue = 15;
if(GPIO_ReadInputDataBit(GPIOB,COL4)==0)
keyvalue = 13;
GPIO_SetBits(GPIOA,ROW4);
return keyvalue;
}
int main(void)
{
uint8_t keyvalue = 0xff;
uint8_t num1 = 0,num2 = 0;
uint8_t op = 0;
uint32_t result = 0;
char str[10];
GPIO_Configuration();
LCD5110_GPIO_Configuration();
LCD5110_Init();
LCD5110_Clear();
while(1)
{
keyvalue = KeyScan();
if(keyvalue!=0xff)
{
if(keyvalue>=0&&keyvalue<=9)
{
if(op==0)
{
num1 = num1*10+keyvalue;
sprintf(str,"%d",num1);
LCD5110_Write_String(0,0,str);
}
else
{
num2 = num2*10+keyvalue;
sprintf(str,"%d",num2);
LCD5110_Write_String(0,1,str);
}
}
else if(keyvalue>=10&&keyvalue<=13)
{
op = keyvalue;
LCD5110_Write_Char(op+47);
}
else if(keyvalue==14)
{
num1 = 0;
num2 = 0;
op = 0;
result = 0;
LCD5110_Clear();
}
else if(keyvalue==15)
{
switch(op)
{
case 10:
result = num1+num2;
break;
case 11:
result = num1-num2;
break;
case 12:
result = num1*num2;
break;
case 13:
result = num1/num2;
break;
default:
break;
}
sprintf(str,"%d",result);
LCD5110_Write_String(0,2,str);
}
}
}
}
```
阅读全文