Proteus仿真STM32LED流水灯
Keil代码编写
我们先在Keil中添加一个main.c文件:
然后下载一个STM32启动器并将其添加到新建的项目下:
选择Add Existing Files to Group Source Group 1,选择All FIles,将刚刚添加的启动文件Add,Add之后Close:
接着点击魔术棒,点击Output,勾选Create HEX File,点击OK:
然后在main.c中写入寄存器代码:
#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOB_CRH (*(unsigned int *)0x40010C04)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
void SystemInit(void);
void Delay_ms(volatile unsigned int);
void A_LED_LIGHT(void);
void B_LED_LIGHT(void);
void C_LED_LIGHT(void);
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
void A_LED_LIGHT(){
GPIOA_ODR=0x0<<4; //PA4低电平
GPIOB_ODR=0x1<<9; //PB9高电平
GPIOC_ODR=0x1<<15; //PC15高电平
}
void B_LED_LIGHT(){
GPIOA_ODR=0x1<<4; //PA4高电平
GPIOB_ODR=0x0<<9; //PB9低电平
GPIOC_ODR=0x1<<15; //PC15高电平
}
void C_LED_LIGHT(){
GPIOA_ODR=0x1<<4; //PA4高电平
GPIOB_ODR=0x1<<9; //PB9高电平
GPIOC_ODR=0x0<<15; //PC15低电平
}
int main(){
int j=100;
// 开启时钟
RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
// 设置 GPIO 为推挽输出
GPIOB_CRH&= 0xffffff0f; //设置位 清零
GPIOB_CRH|=0x00000020; //PB9推挽输出
GPIOC_CRH &= 0x0fffffff; //设置位 清零
GPIOC_CRH|=0x30000000; //PC15推挽输出
GPIOA_CRL &= 0xfff0ffff; //设置位 清零
GPIOA_CRL|=0x00010000; //PA4推挽输出
// 3个LED初始化为不亮(即高点位)
GPIOB_ODR |= (1<<9);
GPIOC_ODR |= (1<<15);
GPIOA_ODR |= (1<<4);
while(j){
B_LED_LIGHT();
Delay_ms(1000000);
C_LED_LIGHT();
Delay_ms(1000000);
A_LED_LIGHT();
Delay_ms(1000000);
}
}
void SystemInit(){
}
创建Proteus项目
画好如下电路图:
然后双击芯片添加刚刚生成的头文件:
用STM32F103C8T6的GPIOA、GPIOB、GPIOC控制LED灯轮流闪烁
以下是使用 C 语言以寄存器方式编写的代码示例:
#include "stm32f10x.h"
// 延时函数
void delay(int msec) {
for (volatile int I = 0; I < msec * 1000; I++) {
// 延时计数循环
}
}
int main(void) {
// 使能 GPIOA、GPIOB 和 GPIOC 的时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
// 配置 GPIOA、GPIOB 和 GPIOC 的端口
// GPIOA 的 0~7 号管脚为输出模式,最低速度
GPIOA->CRL &= 0xFFFF0000; // 设置前 8 位为输出模式
GPIOA->CRL |= 0x00003333; // 设置为通用推挽输出
GPIOA->ODR &= 0xFFFFFF00; // 初始状态下所有 LED 熄灭
// GPIOB 的 0~5 号管脚为输出模式,最低速度
GPIOB->CRL &= 0xFFFFFF00; // 设置前 8 位为输出模式
GPIOB->CRL |= 0x00000033; // 设置为通用推挽输出
GPIOB->ODR &= 0xFFFFC0FF; // 初始状态下所有 LED 熄灭
// GPIOC 的 13~15 号管脚为输出模式,最低速度
GPIOC->CRH &= 0xFF0FFFFF; // 设置后 12 位为输出模式
GPIOC->CRH |= 0x00333330; // 设置为通用推挽输出
GPIOC->ODR &= 0xFFFF1FFF; // 初始状态下所有 LED 熄灭
while (1) {
// 点亮红色 LED(GPIOA 的 0 号管脚)
GPIOA->BSRR = GPIO_BSRR_BS0;
delay(1000); // 延时 1 秒
// 熄灭红色 LED
GPIOA->BSRR = GPIO_BSRR_BR0;
delay(1000); // 延时 1 秒
// 点亮绿色 LED(GPIOB 的 0 号管脚)
GPIOB->BSRR = GPIO_BSRR_BS0;
delay(1000); // 延时 1 秒
// 熄灭绿色 LED
GPIOB->BSRR = GPIO_BSRR_BR0;
delay(1000); // 延时 1 秒
// 点亮蓝色 LED(GPIOC 的 13 号管脚)
GPIOC->BSRR = GPIO_BSRR_BS13;
delay(1000); // 延时 1 秒
// 熄灭蓝色 LED
GPIOC->BSRR = GPIO_BSRR_BR13;
delay(1000); // 延时 1 秒
}
}
小结:在这个例子中,我们将 GPIOA 的 0~7 号管脚配置为输出模式,GPIOB 的 0~5 号管脚配置为输出模式,GPIOC 的 13~15 号管脚配置为输出模式。