资深版主
- 积分
- 4306
- 金钱
- 4306
- 注册时间
- 2018-6-30
- 在线时间
- 808 小时
|
本帖最后由 1208 于 2019-11-7 17:40 编辑
参考中文参考手册
思路:
1)要先打开AHB的APB2使能时钟
2)端口配置CNFO[1:0]和MODE0[1:0]模式,如推挽模式和输出速度,控制GPIOx_CRL寄存器
3)端口输出模式,如拉低电平,控制GPIOx_ODR寄存器
方法:
以GPIOD为例
通过存储映像找到AHB的0x4002 1000,再对应找到APB2ENR时钟的偏移地址: 0x18,即0x40021018
通过GPIOx_CRL寄存器,先找到存储映像GPIOD的0x4001 1400 ,选择低位GPIOx_CRL寄存器的偏移地址: 0x00,即0x40011400
控制GPIOx_ODR 寄存器,先先找到存储映像GPIOD的0x4001 1400,选择GPIOx_ODR 寄存器的地址偏移: 0C,即0x4001140C
总结:
1)置位 |=, 清0 &=~
2) *( unsigned int * )指编译器要把它看做地址,强制的数据类型转换,加*表示指针,括号外加*识别指针操作
3)( (1) << 5 )指1左移5位, &= ~( (0x0f) << (4*2) )指CNFO[1:0]和MODE0[1:0]左移4*2=8位,先变为1,后面取为0,即都置0
[mw_shl_code=c,true]int main (void)
{
//PD2亮
// 打开 GPIOD 端口的时钟
*( unsigned int * )0x40021018 |= ( (1) << 5 ); //打开RCC的APB2
// 配置IO口为输出 低寄存器控制着低八位 16个IO ,CNFO[1:0]和MODE0[1:0]控制着一个IO口
*( unsigned int * )0x40011400 &= ~( (0x0f) << (4*2) ); // CNFO[1:0]和MODE0[1:0]都置0,
*( unsigned int * )0x40011400 |= ( (3) << (4*2) ); //推挽输出模式CNFO[1:0]=00,MODE0[1:0]=11 ,0011代表2进制,即第0位,以4个为一组
// 控制 ODR 寄存器 1左移0位 ,是到GPIOD的位置
*( unsigned int * )0x4001140C &= ~(1<<2); //端口数据ODR,PD2由ODR2控制,这个位写0
//输出低电平
//GPIOA 时钟 PA8亮
*( unsigned int * )0x40021018 |= ( (1) << 2 );
// 配置IO口为输出 高寄存器控制着高八位
*( unsigned int * )0x40010804 &= ~( (0x0f) << (4*0) ); // 置0
*( unsigned int * )0x40010804 |= ( (1) << (4*0) );
// 控制 ODR 寄存器 GPIOA.8
*( unsigned int * )0x4001080C &= ~(1<<8); //低电平
}[/mw_shl_code] |
|