前言
实现流水灯点亮
一、点亮一个灯
首先先实现点亮一个灯
int main(void)
{
*(unsigned int *)0x40021018 = ( 1 << 3 );
*(unsigned int *)0x40010C00 &= ~( 0x0f<< (4*0));
*(unsigned int *)0x40010C00 |= (1<<4*0);
*(unsigned int *)0x40010C0C &= ~(1 << 0);
while (1);
}
void SystemInit(void)
{
return;
}
二、实现一个灯的闪烁点亮
int main(void)
{
*(unsigned int *)0x40021018 = ( 1 << 3 );
*(unsigned int *)0x40010C00 &= ~( 0x0f<< (4*0));
*(unsigned int *)0x40010C00 |= (1<<4*0);
while (1)
{
*(unsigned int *)0x40010C0C |= (1 << 0);
delay(1000);
*(unsigned int *)0x40010C0C &= ~(1 << 0);
delay(1000);
}
}
void delay(volatile unsigned int time)
{
unsigned int i, j;
for (i = 0; i < time; i++)
for (j = 0; j < time; j++)
;
}
void SystemInit(void)
{
return;
}
特别说明:
在写延时函数的时候,一定要用volatile,不使用的话根本起不到延时的作用。
三、使用寄存器编程实现三个灯的闪烁点亮
首先根据参考手册自己编写一个简易的stm32f10x.h头文件
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB1PERIPH_BASE (PERIPH_BASE)
#define APB2PERIPH_BASE (PERIPH_BASE + 0X10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0X20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define GPIOB_BASE (APB2PERIPH_BASE + 0xC00)
#define RCC_APB2ENR *(unsigned int *)(RCC_BASE + 0x18)
#define GPIOB_CRL *(unsigned int *)((GPIOB_BASE + 0x00))
#define GPIOB_CRH *(unsigned int *)((GPIOB_BASE + 0x04))
#define GPIOB_ODR *(unsigned int *)((GPIOB_BASE + 0x0C))
#define GPIOB_BSRR *(unsigned int *)((GPIOB_BASE + 0x10))
#define GPIOB_BRR *(unsigned int *)((GPIOB_BASE + 0x14))
1.使用输出数据寄存器来实现
#include "stm32f10x.h"
void delay(volatile unsigned int time);
int main(void)
{
RCC_APB2ENR |= (1 << 3);
GPIOB_CRL &= ~(0x0e << (4*0) );
GPIOB_CRL |= ( 1 << (4*0) );
GPIOB_CRL &= ~(0x0e << (4*1) );
GPIOB_CRL |= ( 1 << (4*1) );
GPIOB_CRL &= ~(0x0e << (4*5) );
GPIOB_CRL |= ( 1 << (4*5) );
while (1)
{
GPIOB_ODR &= ~(1 << 0);
delay(1000);
GPIOB_ODR |= (1 << 0);
delay(1000);
GPIOB_ODR &= ~(1 << 1);
delay(1000);
GPIOB_ODR |= (1 << 1);
delay(1000);
GPIOB_ODR &= ~(1 << 5);
delay(1000);
GPIOB_ODR |= (1 << 5);
delay(1000);
}
}
void delay(volatile unsigned int time)
{
unsigned int i, j;
for (i = 0; i < time; i++)
for (j = 0; j < time; j++)
;
}
void SystemInit(void)
{
return;
}
2.使用端口位设置/清除寄存器来实现
#include "stm32f10x.h"
void delay(volatile unsigned int time);
int main(void)
{
RCC_APB2ENR |= (1 << 3);
GPIOB_CRL &= ~(0x0e << (4*0) );
GPIOB_CRL |= ( 1 << (4*0) );
GPIOB_CRL &= ~(0x0e << (4*1) );
GPIOB_CRL |= ( 1 << (4*1) );
GPIOB_CRL &= ~(0x0e << (4*5) );
GPIOB_CRL |= ( 1 << (4*5) );
GPIOB_ODR = 0xFFFF;
while (1)
{
GPIOB_BSRR |= (1 << 16);
delay(1000);
GPIOB_BSRR &= ~(1 << (16+0));
GPIOB_BSRR |= (1 << 0);
delay(1000);
GPIOB_BSRR &= ~(1 << 0);
GPIOB_BSRR |= (1 << (16+1));
delay(1000);
GPIOB_BSRR &= ~(1 << (16+1));
GPIOB_BSRR |= (1 << 1);
delay(1000);
GPIOB_BSRR &= ~(1 << 1);
GPIOB_BSRR |= (1 << (16+5));
delay(1000);
GPIOB_BSRR &= ~(1 << (16+5));
GPIOB_BSRR |= (1 << 5);
delay(1000);
GPIOB_BSRR &= ~(1 << 5);
}
}
void delay(volatile unsigned int time)
{
unsigned int i, j;
for (i = 0; i < time; i++)
for (j = 0; j < time; j++)
;
}
void SystemInit(void)
{
return;
}
注意:对GPIOB_BSRR的第16位的置1置0操作,不能放在前后语句来执行,否则可能因为过快,还未给GPIOB的0引脚置0就已经取消置0了。其他位的操作也是一样。
总结
注意:在设置为推挽输出模式的时候,先把四位中的前三位置为0是必不可少的,因为可能因为种种原因,它的前三位并不全为0,故仅仅执行将最后一位置为1可能达不到效果。
|