我尝试对STM32F103C8电路进行编程。我使用的是ST-LINK V2编程器。在运行了一个使用特殊库的代码示例后,我能够看到内置的LED亮起,但现在我想在不使用这些库的情况下对板进行编程,我不知道为什么我什么都看不见,LED一直熄灭。这是代码:
#include "stm32f10x.h" // Device header
int main(){
RCC->APB2ENR |= 1<<4;
GPIOC->CRH &= ~0xFF0FFFF;
GPIOC->CRH |= 0x00300000;
GPIOC->ODR |= 1<<13;//turn PC_13 ON
while(1){
}
}
根据PC13上有LED的信息,我认为您使用的是著名的蓝色药丸板。在该板中,LED连接是反向的,因为PC13的特殊限制——引脚应该只吸收电流,而不是电源。因此,为了打开它,您需要将0写入ODR的相应位。
通常,我反对使用幻数。但对于STM32F103,使用十六进制文字进行GPIO配置是可行的,因为一个十六进制数字唯一地定义了引脚模式。可以记住GPIO设置的十六进制文字的含义,并在一个紧凑的分配中使用它们,该分配一次定义GPIO端口的8个引脚。如果只进行一次GPIO配置,则不需要&=
或|=
运算符。
此外,更喜欢使用BSRR
而不是ODR
,因为它允许对输出引脚进行原子修改。
以下是蓝色药丸板的LED闪烁示例:
//========================================================================
// Includes
//========================================================================
#include "stm32f1xx.h"
#include <stdbool.h>
#include <stdint.h>
//========================================================================
// Local Variables
//========================================================================
volatile uint32_t sysTick = 0;
//========================================================================
// Local Function Prototypes
//========================================================================
void initialize(void);
void delayMs(uint32_t ms);
//========================================================================
// Initialization
//========================================================================
void initialize(void) {
SystemCoreClock = 8000000U;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN // Enable PortC
| RCC_APB2ENR_AFIOEN; // Enable A.F.Z
// Pin Remaps
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG is disabled
// GPIO Settings
GPIOC->CRH = 0x44244444; // LED connected to PC13
GPIOC->BSRR = (1 << 13); // LED is inverted, turn it off.
// SysTick Settings
SysTick_Config(SystemCoreClock / 1000);
// Initialization Done Signal
GPIOC->BSRR = (1 << (13 + 16));
delayMs(200);
GPIOC->BSRR = (1 << 13);
}
//========================================================================
// Main
//========================================================================
int main(void) {
initialize();
while (true) {
delayMs(500);
GPIOC->BSRR = (1 << (13 + 16));
delayMs(500);
GPIOC->BSRR = (1 << 13);
}
}
//========================================================================
// Interrupt Handlers
//========================================================================
void SysTick_Handler(void)
{
++sysTick;
}
//========================================================================
// Local Functions
//========================================================================
void delayMs(uint32_t ms) {
uint32_t start = sysTick;
while (sysTick - start < ms);
}
#include "stm32f10x.h" // Device header
int main(void){
RCC->APB2ENR |= 1<<4;
GPIOC->CRH &= 0xFF0FFFF;//clear the necessary bit
GPIOC->CRH |= 0x00300000;//set the necessary bit
GPIOC->ODR &= ~(1<<13);//turn PC_13 ON
while(1){
}
}
此代码有效。问题是PC13控制的是内置LED的阴极,而不是阳极。这就是为什么我应该写:GPIO->ODR &= ~(1 << 13);
以便打开LED。