{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}
========================
让我们分析下 GPIOC->ODR ^= (1<<7); 这种方式吧,其实是有一定的风险的。
看下反汇编如下:
55: GPIOC->ODR ^= (1<<7);
//读取 GPIOC->ODR 的值,放到R0中
1. 0x0800B868 4807 LDR r0,[pc,#28] ; @0x0800B888
2. 0x0800B86A 68C0 LDR r0,[r0,#0x0C]
//将读取的在R0中的值进行改写
3. 0x0800B86C F0800002 EOR r0,r0,#0x80
//写回GPIOC->ODR
4. 0x0800B870 4905 LDR r1,[pc,#20] ; @0x0800B888
5. 0x0800B872 60C8 STR r0,[r1,#0x0C]
……
//GPIOC地址
0x0800B888 1000 DCW 0x1000
……
如果在2~5步之间有中断,改写了GPIOC->ODR的值,那么这个程序执行结果可能不是我们所希望的。
个人推荐没有副作用的方法有两个,
一. 位带操作
二.((GPIOC->ODR & GPIO_Pin_7) ? (GPIOC->BRR = GPIO_Pin_7): (GPIOC->BSRR = GPIO_Pin_7))