如何点亮一个LED灯?
LED有插脚封装的、贴片封装的。
它们长得完全不一样,因此我们在原理图中把它们抽象出来。
点亮LED需要通电源,同时为了保护LED,需要加个电阻减小电流。
控制LED灯的亮灭,可以手动开关LED,但在电子系统中,不可能让人来控制开关,通过编程,利用芯片的引脚去控制开关。
LED的驱动方式,常见的有4种。
有的芯片为了省电等原因,其引脚驱动能力不足,这时可以使用三极管驱动。
由此,主芯片引脚输出高电平/低电平,即可改变LED状态,而无需关注GPIO引脚输出的是3.3V还是1.2V。
所以简称输出1或0:
逻辑1–>高电平
逻辑0–>低电平
GPIO:General-purpose input/output,通用输入/输出口。
GPIO模块一般结构:
GPIO寄存器操作:
操作寄存器,不能影响到其它位
GPIO寄存器的2种操作方法:
//将bit n置为1
val = data_reg;
val = val | (1 << n);
data_reg = val;
//清除bit n
val = data_reg;
val &= ~(1<<n);
data_reg = val;
set_reg = (1 << n);
clr_reg = (1 << n);
打开原理图,搜索LED。
以PB0为例,它属于GPIOB里的第0个引脚。
怎么使能GPIOB?
将Bit 3设置为1。
频率越高,传输数据越快,波形也越陡峭,同时对外界设备的影响也越大。
访问寄存器用指针:
int a;
unsigned int*p = &a; //p等于a的地址
*p = val; //写这个地址,就是写a
val = *p; //读这个地址,就是读a
unsigned int *p = 0x40010800; //p等于某个寄存器的地址
*p = val; //写这个地址,就是写这个寄存器
val = *p; //读寄存器
void delay(int d)
{
while(d--);
}
int main()
{
unsigned int *pReg;
/* 使能GPIOB */
pReg = (unsigned int *)(0x40021000 + 0x18);
*pReg |= (1<<3);
/* 设置GPIOB0为输出引脚 */
pReg = (unsigned int *)(0x40010C00 + 0x00);
*pReg |= (1<<0);
pReg = (unsigned int *)(0x40010C00 + 0x0C);
while(1)
{
/* 设置GPIOB0输出高电平 */
*pReg |= (1<<0);
delay(100000);
/* 设置GPIOB0输出低电平 */
*pReg &= ~(1<<0);
delay(100000);
}
return 0;
}
再由启动文件:start.S调用main函数,参考keil自带的tartup_stm32f10x_hd.s
设置栈,调用main函数:
PRESERVE8
THUMB
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD 0 ; Top of Stack
DCD Reset_Handler ; Reset Handler
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT main
LDR SP, =(0X20000000+0XC000)
BL main
ENDP
END