近来由于工作需要重拾proteus仿真功能,遇到诸多问题,下面从点灯开始说起。
本文使用的是 keil 软件 和 proteus 软件,搭建内容不再详述。
- 仿真放置图形
- 配置引脚
- 代码编写
仿真放置图形
这里直接选择左方的器件选择模式
搜索stm32f103c8, res(电阻),button(按键) ,led-red(红色led)添加进入元件库
按图示摆放即可
配置引脚
这里有小伙伴放置连线后找不到如何配置引脚,说明一下,在终端模式中有VCC,GROUND,还有BIDIR(双端口),INPUT(输入端口)和OUTPUT(输出端口)就是上图的引脚添加连线即可。
批量添加标注:光有引脚还得加标注proteus才知道谁和谁是一对儿。在这个原理图设计界面空按键盘A,出现如下所示
字符串一栏输入NET=PA# 点击确定再依次点击之前布置好的引脚即可。
代码编写
打开keil,打开一个工程。这里stm32相较于51单片机的内容更加复杂更多的使用内置的函数,推荐大家网上直接下载配置好的工程模板。
这里有其他博客的下载链接:工程模板
先清空自带的led.c 和 led.h 文件,输入下面的内容
#include "led.h"
#include "stm32f10x.h"
void LED_Init(void)
{
//声明一个结构体,名字是GPIO_InitStructure
GPIO_InitTypeDef GPIO_InitStructure;
//使能GPIOC的时钟,ENABLE代表使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOC
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; // 选中端口 0 1 2 3
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; // 最大反转速度
GPIO_Init(GPIOA,&GPIO_InitStructure); // 初始化
}
#ifndef __LED_H
#define __LED_H
void LED_Init(void);
#endif
这个具体知识点学点c语言结构体和函数就行了。
再向HAREWARE文件夹添加相应的key.c和key.h文件,像下面这样写
#ifndef __KEY_H
#define __KEY_H
void Key_Init(void);
uint8_t Key_GetNum(void);
#endif
#include "stm32f10x.h" // Device header
#include "key.h"
#include "delay.h"
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOC
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
uint8_t Key_GetNum(void)
{
uint8_t Key_Num = 0; // 相当于一个unsigned char类型
// S1
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0)
{
delay_ms(20);
Key_Num = 1;
}
// S2
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == 0)
{
delay_ms(20); // 简易消抖
Key_Num = 2;
}
// S3
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)
{
delay_ms(20);
Key_Num = 3;
}
// S4
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)
{
delay_ms(20);
Key_Num = 4;
}
return Key_Num;
}
引用的头文件delay.h是该工程模板自带的,直接使用即可。
上述代码我们将GPIOA口的0 1 2 3口配置成上拉输入的方式,GPIOB口的0 1 2 3口配置成推挽输出的方式。
最后在main.c文件中就很简单了,我们判断按键扫描函数的返回值即可。
#include "stm32f10x.h"
#include "led.h" // led
#include "delay.h" // 延时
#include "key.h" // 按键
int main(void)
{
delay_init();
LED_Init();
Key_Init();
while(1){ //主循环
switch(Key_GetNum())
{
case 1: GPIO_SetBits(GPIOB,GPIO_Pin_0); break;
case 2: GPIO_SetBits(GPIOB,GPIO_Pin_1); break;
case 3: GPIO_SetBits(GPIOB,GPIO_Pin_2); break;
case 4: GPIO_SetBits(GPIOB,GPIO_Pin_3); break;
default: GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3); break;
}
}
}
大家写的时候,如果对某些函数有疑问,选中函数右键选择go to definition即可。通用函数学习方法。
这些参数怎么用,有什么限制写得很清楚。
点击build按钮,无报错后,进入proteus双击stm32f103c8芯片,选择keil工程夹下的OBJ文件夹,里面有后缀为hex的十六进制文件,载入到芯片即可。