鉴于上面代码逻辑运算太难懂,下面用VS运行C++代码说明,分两种:
1--指定某一类io口,比如是GPIOF就用5代替,然后循环各个(0~15)io口:
// 配置寄存器EXTICR循环io口代码测试.cpp :
//
#include <iostream>
int main()
{
int EXTI_PinSourcex=0;
uint32_t tmp = 0x00; tmp;
uint32_t EXTICR[4];
for (EXTI_PinSourcex; EXTI_PinSourcex < 0x10; EXTI_PinSourcex++)
{
tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));//
EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp;
std::cout << EXTI_PinSourcex / 4 << "-" << std::hex << tmp << "-" << std::hex << EXTICR[EXTI_PinSourcex >> 0x02] << "/-";
EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)5) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));//A
std::cout << EXTI_PinSourcex << "--";
std::cout << std::hex << EXTICR[EXTI_PinSourcex >> 0x02] << "\n";
EXTICR[EXTI_PinSourcex >> 0x02] = 0xcccccccc;
// printf("%02X ", EXTICR[EXTI_PinSourcex >> 0x02]);
}
}
/*以下是常用的流操纵符:
std::dec:将输出转换为十进制,默认情况下即为十进制。
std::oct:将输出转换为八进制。
std::hex:将输出转换为十六进制,小写字母形式。
std::hex|std::uppercase:将输出转换为十六进制,大写字母形式。
std::showbase:在输出八进制和十六进制时,显示前缀0和0x。
std::noshowbase:在输出八进制和十六进制时,不显示前缀0和0x。
————————————————
*/
运行效果(输出分别是:哪一个EXTICR寄存器--临时变量:配置寄存器的哪一段设F(1111)--寄存器哪一段清0(0000)--哪一个io口--第EXTI_PinSourcex >> 0x02个EXTICR寄存器配置值)(假设了寄存器的原值是0xcccccccc,不代表任何含义):
圈住的为GPIOF_9
2--模拟源代码,IO口是GPIOD_11参数宏定义,直接调用函数:
// SYSCFG_EXTILineConfig.cpp :
//
#include <iostream>
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);//函数声明
int main()
{
#define EXTI_PortSourceGPIOA ((uint8_t)0x00)
#define EXTI_PortSourceGPIOB ((uint8_t)0x01)
#define EXTI_PortSourceGPIOC ((uint8_t)0x02)
#define EXTI_PortSourceGPIOD ((uint8_t)0x03)
#define EXTI_PortSourceGPIOE ((uint8_t)0x04)
#define EXTI_PortSourceGPIOF ((uint8_t)0x05)
#define EXTI_PortSourceGPIOG ((uint8_t)0x06)
#define EXTI_PortSourceGPIOH ((uint8_t)0x07)
#define EXTI_PortSourceGPIOI ((uint8_t)0x08)
#define EXTI_PortSourceGPIOJ ((uint8_t)0x09)
#define EXTI_PortSourceGPIOK ((uint8_t)0x0A)
//-----
#define EXTI_PinSource0 ((uint8_t)0x00)
#define EXTI_PinSource1 ((uint8_t)0x01)
#define EXTI_PinSource2 ((uint8_t)0x02)
#define EXTI_PinSource3 ((uint8_t)0x03)
#define EXTI_PinSource4 ((uint8_t)0x04)
#define EXTI_PinSource5 ((uint8_t)0x05)
#define EXTI_PinSource6 ((uint8_t)0x06)
#define EXTI_PinSource7 ((uint8_t)0x07)
#define EXTI_PinSource8 ((uint8_t)0x08)
#define EXTI_PinSource9 ((uint8_t)0x09)
#define EXTI_PinSource10 ((uint8_t)0x0A)
#define EXTI_PinSource11 ((uint8_t)0x0B)
#define EXTI_PinSource12 ((uint8_t)0x0C)
#define EXTI_PinSource13 ((uint8_t)0x0D)
#define EXTI_PinSource14 ((uint8_t)0x0E)
#define EXTI_PinSource15 ((uint8_t)0x0F)
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource11);
}
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)//函数定义
{
//typedef struct
//{
// uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */
// uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */
// uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 *///ÍⲿÖжÏÅäÖüĴæÆ÷
// uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */
// uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */
//} SYSCFG;
//
uint32_t tmp = 0x00;
uint32_t *EXTICR = new uint32_t[4]();// EXTICR四个寄存器
// int* pia2 = new int[10]();
tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));//
EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp;
std::cout <<EXTI_PinSourcex / 4 << "-" << std::hex << EXTICR[EXTI_PinSourcex >> 0x02] << "/-";//哪一个EXTICR寄存器--寄存器哪一段清0(0000)
EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));//6---GPIOG,0----GPIOA
std::cout << static_cast<int>(EXTI_PinSourcex) << "-" << std::hex << tmp << "--";//哪一个io口--临时变量:配置寄存器的哪一段设F(1111)
std::cout << std::hex << EXTICR[EXTI_PinSourcex >> 0x02] << "\n";//第EXTI_PinSourcex >> 0x02个EXTICR寄存器配置值
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
/*以下是常用的流操纵符:
std::dec:将输出转换为十进制,默认情况下即为十进制。
std::oct:将输出转换为八进制。
std::hex:将输出转换为十六进制,小写字母形式。
std::hex|std::uppercase:将输出转换为十六进制,大写字母形式。
std::showbase:在输出八进制和十六进制时,显示前缀0和0x。
std::noshowbase:在输出八进制和十六进制时,不显示前缀0和0x。
————————————————
*/
//std::cout在处理uint8_t变量类型的时候默认输出字符,刚好数字0-10对应的ascii字符都是不可打印的!解决:
//使用static_cast<int>
//
//如果是定义的全局变量或者静态变量,未初始化的话就是0.如果是局部变量,那就是以前残留在堆栈里的随机值。
//1、局部变量。
//局部变量在没有显式初始化时,其值C语言规范没做要求,可以是随机值,也可以是编译器随意给定的值。
//比如gcc编译器的局部变量就是随机值,可能为任何值。而微软的编译器,如VC或VS,则会初始化为全c,即0xCCCCCCCC。
运行效果:(输出分别是:哪一个EXTICR寄存器--临时变量:配置寄存器的哪一段设F(1111)--寄存器哪一段清0(0000)--哪一个io口--第EXTI_PinSourcex >> 0x02个EXTICR寄存器配置值)(假设了寄存器的原值是0x00000000,为复位值):
GPIOD_11
部分相关单片机代码截图(GPIOF_9):
手册部分: