在前一篇文章中我们已经学习到可以通过直接访问存储地址来读写外设寄存器,下面复习下将 gpio a3 设为输出模式的代码:
* (volatile uint32_t *) (0x40020000 + 0) &= ~(3 < < 6); // clear bit range 6-7* (volatile uint32_t *) (0x40020000 + 0) |= 1 < moder &= ~(3u < moder |= (mode & 3) < < (pin * 2); // set new mode}现在重写上面将 gpio a3 设为输出模式的代码:
gpio_set_mode(gpioa, 3 /* pin */, gpio_mode_output); // set a3 to outputmcu 有好多个 gpio 外设(也常被叫做’banks’):a、b、c…k,在数据手册 2.3 节可以看到,它们映射的存储空间相隔 1kb,gpioa 起始地址为 0x40020000,gpiob 起始地址为 0x40020400,以此类推:
#define gpio(bank) ((struct gpio *) (0x40020000 + 0x400 * (bank)))我们可以给引脚进行编号,既包含组号,也包含序号。为了做到这一点,我们用一个 2 字节的 uint16_t 类型的数,高字节表示组号,低字节表示序号:
#define pin(bank, num) ((((bank) - 'a') < > 8)通过这种方法,我们可以指定任意 gpio 引脚:
uint16_t pin1 = pin('a', 3); // a3 - gpioa pin 3uint16_t pin2 = pin('g', 11); // g11 - gpiog pin 11现在,我们用这个方法再次改写 gpio_set_mode() 函数:
static inline void gpio_set_mode(uint16_t pin, uint8_t mode) {struct gpio *gpio = gpio(pinbank(pin)); // gpio bankuint8_t n = pinno(pin); // pin numbergpio- >moder &= ~(3u < moder |= (mode & 3) < < (n * 2); // set new mode}这样再设置 gpio a3 为输出模式就很明了了:
uint16_t pin = pin('a', 3); // pin a3gpio_set_mode(pin, gpio_mode_output); // set to output至此我们已经为 gpio 外设创建了一个有用的初始化 api,其它外设,比如串口,也可以用相似的方法来实现。这是一种很好的编程实践,可以让代码清晰可读。
比特率,波特率,比特和波特的关系是什么?
桁架机器人容易操纵吗?
TCL推出平板Plus 10主打移动化体验,并支持三种工作模式
模态计算精度影响因素分析
撒花!武汉森木磊石科技有限公司新版官方网站上线啦!
STM32裸机编程的基础知识(2)
诺基亚8最新消息:诺基亚8无边框+骁龙835,配置、性能、拍照全方位升级
循环工作定时控制器电路设计
如何制作一张会发光的贺卡?
Windows 8将决定微软未来市场地位
土壤紧实度测定仪的应用及性能
人工智能2019:争议依然如影随形
RealChain基金会建立欧洲区块链合作
小米MIX缩小版Nano真的存在?小米市场总监从辟谣到删微博看不明白
腾讯给全体员工每人一台价值16999元的华为折叠屏手机
长征五号 B 遥二运载火箭运抵文昌航天发射场,中国空间站天和核心舱预计 4 月发射
工信部:前三季度电子信息制造业持增长态势,处于领先水平
未来可穿戴设备必将取代手机,成为新的电子消费品的主力
台湾电子产业现危机,物联网或成下一个突破口
利用可充电薄膜存储器件设计电源