(相关资料图)
在前一篇文章中我们已经学习到可以通过直接访问存储地址来读写外设寄存器,下面复习下将 GPIO A3 设为输出模式的代码:
* (volatile uint32_t *) (0x40020000 + 0) &= ~(3 < < 6); // CLear bit range 6-7* (volatile uint32_t *) (0x40020000 + 0) |= 1 < < 6; // Set bit range 6-7 to 1
这段代码有些诡秘,如果不加以注释,很难理解。我们可以把这段代码重写成更易读的形式,方法就是用一个包含 32 位域的结构体来表示整个外设。我们来看一下数据手册 8.4 节中描述的 GPIO 外设的寄存器,它们是 MODER、OTYPER、OSPEEDR、PUPDR、IDR、ODR、BSRR、LCKR、AFR,它们的偏移量分别是 0、4、8,等等,以此类推,这意味着我们可以用一个 32 位域的结构体来表示,然后这样定义 GPIOA:
struct gpio { volatile uint32_t MODER, OTYPER, OSPEEDR, PUPDR, IDR, ODR, BSRR, LCKR, AFR[2];};#define GPIOA ((struct gpio *) 0x40020000)
这样我们就可以定义一个设置 GPIO 引脚模式的函数:
// Enum values are per datasheet: 0, 1, 2, 3enum {GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG};staticinline void gpio_set_mode(struct gpio *gpio, uint8_t pin, uint8_t mode) { gpio- >MODER &= ~(3U < < (pin * 2)); // Clear existing setting gpio- >MODER |= (mode & 3) < < (pin * 2); // Set new mode}
现在重写上面将 GPIO A3 设为输出模式的代码:
gpio_set_mode(GPIOA, 3 /* pin */, GPIO_MODE_OUTPUT); // Set A3 to output
MCU有好多个 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) | (num))#define PINNO(pin) (pin & 255)#define PINBANK(pin) (pin > > 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 < < (n * 2)); // Clear existing settinggpio- >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,其它外设,比如串口,也可以用相似的方法来实现。这是一种很好的编程实践,可以让代码清晰可读。
STM32裸机编程的基础知识(2)-在前一篇文章中我们已经学习到可以通过直
CS:GO免费开箱【点击进入】老牌开箱网+超高爆率+一秒发货CSGO开箱APP【
记者从中国石油辽宁大连销售分公司了解到,2023年6月28日24时起,国内
近两年,南阳市社旗县委宣传部在守正创新中展现作为,努力开创外宣工作
1、分户供暖、集中供暖、独立供暖解释如下:集中供暖:通常是指市政集中
6月28日,广州住房公积金管理中心发布《关于贯彻落实二孩及以上家庭支
智通财经APP讯,泰达股份(000652 SZ)发布公告,为进一步落实公司“双碳
日产知道如何保持人们对Leaf的高度兴趣。毕竟,自上个世纪初推出以来,
本次展览的策展人,也是第二次担任“蔡冠深基金会当代艺术奖”评委...
6月27日,广州中医药大学在大学城校区体育馆举行2023年毕业典礼暨学位
相约大运 成就梦想 川网观大运大运村长什么样?运动员们的赛后生活是
访谈|杨轩翻译|贺哲馨做个关于美妆市场的测验:你觉得欧莱雅是……...
格隆汇6月28日丨华和控股09938HK公布截至2023年3月31日止年度收益为约2
6月28日,青岛市举办“同心向党翰墨精彩”残疾人书画展暨手语电视节...
能源转型是第十四届夏季达沃斯论坛六大核心主题之一。在“通力合作...
hello大家好,我是城乡经济网小晟来为大家解答以上问题,张文宏的十条
今日永州讯(新田融媒体记者邓提茂通讯员肖龙腾)6月27日,新田县人大
记者杜静波摄6月28日下午,省政协召开“加快推进我省储能产业发展”...
《徐政宇先生。请别悲伤》是连载于红袖添香网的一部言情小说。作者是梦
6月28日,澎湃新闻(www thepaper cn)记者从上海网安总队获悉,近期,
据国家发改委消息,根据近期国际市场油价变化情况,按照现行成品油价格
参考消息网6月28日报道据《澳大利亚人报》网站6月28日报道,根据美国民
雅诗兰黛官网比三亚便宜吗,雅斯兰黛官网这个很多人还不知道,现在让我
中国经济网北京6月28日讯截至2023年6月21日,渤海汇金资管旗下渤海汇金
2023年6月28日,中国人民银行行长易纲会见了来访的世界贸易组织总干事
保险已经成为生活中常见的话题之一,比如在回农村的时候发现很多人都买
现实生活中,有很多人都会抱怨老天不公平,觉得自己怀才不遇。其实,抱
北京大学马冠生:探索辟谣新方法,让科普深入人心,科学,马冠生,添加剂,
综合当前宏观经济形势、市场发展趋势,航空客运市场需求正持续向好今年
据俄新社报道,当地时间28日,俄罗斯联邦安全会议秘书帕特鲁舍夫在莫斯