1.存储器结构
程序存存储器,数据存储器,寄存器和输入输出端口,被组织在同一个4G的线性地址空间中;
可以通过地址的方法访问对应的存储器或寄存器;
比如 0X12 34 56 78在内存中存储
低地址------------------------------------------>高地址
大端存储:0x12 | 0x34 | 0x56 | 0x78 //顺序相同,大端在低地址位,栈先存储大端
小端存储:0x78 | 0x56 | 0x34 | 0x12 //顺序逆序,大端在低地址位,栈先存储小端
2.启动方式
在STM32F10XXX里,可以通过BOOT[1:0]引脚选择三种不同启动方式
原理图:
VCC3V3是3.3v电源,连接1,2BOOT0为高电平,连接2,3BOOT0为低电平,BOOT1类似
stm32f103c8核心板:
BOOT0:0
BOOT1:0
启动方式:主闪存存储器,flash;
固件库的启动文件:
cl:互联型产品,stm32f105/107系列
vl:超值型产品,stm32100系列
xl:超高密度产品,stm32f101/103系列
flash容量大小
ld: 低密度产品,小于64kb
md:中等密度产品,64kb和128kb
hd:高密度产品,大于128kb
3.时钟系统
(1)时钟系统框图:
HSI:内部高速时钟
HSE:外部高速时钟
PLL:锁循环
LSE:外部低速时钟,可以提供给RTC;通过RTCSEL选择;
LSI:内部低速时钟,可以给RTC或者看门狗(IWDG)提供时钟
注意定时器2~7;
CFGR设置系统时钟
系统自设置的时钟频率:
3.GPIO
(1)GPIO介绍:
功能:
输入(Input):
浮空 _IN_FLOATING:外设高电平,输入高电平,外设为低电平,输入低电平,无输入时不确定,易受外界影响;
模拟 _AIN:输入信号不是数字量,是模拟量。
上拉 _IPU:接上上拉电阻,当无输入时为高电平
下拉 _AIN:接上下拉电阻,当无输入时为低电平
输出(Output):
推挽输出:有一定的驱动能力,可以真正地输出高低电平;
开漏输出:没有驱动能力,想要驱动设备要接上拉电阻,只能输出低电平;
(2)GPIO函数介绍:
void GPIO_DeInit(GPIO_TypeDef* GPIOx); void GPIO_AFIODeInit(void); void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //设置为高电平 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //复位设置为低电平 void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); void GPIO_EventOutputCmd(FunctionalState NewState); void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState); void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
初始化函数,第一个为引脚类型,PA,PB.......;第二个是一个结构体。
typedef struct { uint16_t GPIO_Pin; //第几个引脚 GPIOSpeed_TypeDef GPIO_Speed; //频率 GPIOMode_TypeDef GPIO_Mode; //8大输入输出方式 }GPIO_InitTypeDef;
GPIOSpeed_TypeDef GPIO_Speed; //频率
typedef enum { GPIO_Speed_10MHz = 1, GPIO_Speed_2MHz, GPIO_Speed_50MHz }GPIOSpeed_TypeDef;
GPIOMode_TypeDef GPIO_Mode; //8大输入输出方式
typedef enum { GPIO_Mode_AIN = 0x0, //模拟输入 GPIO_Mode_IN_FLOATING = 0x04, //浮空输入 GPIO_Mode_IPD = 0x28, //下拉输入 GPIO_Mode_IPU = 0x48, //上拉输入 GPIO_Mode_Out_OD = 0x14, //开漏输出 GPIO_Mode_Out_PP = 0x10, //推挽输出 GPIO_Mode_AF_OD = 0x1C, //复用开漏 GPIO_Mode_AF_PP = 0x18 //复用推挽 }GPIOMode_TypeDef;
还有好多函数,可以查找固件库手册;
开启时钟函数:
大多数都是APB1和APB2时钟,我们以APB2为例;
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) { /* Check the parameters */ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { RCC->APB2ENR |= RCC_APB2Periph; } else { RCC->APB2ENR &= ~RCC_APB2Periph; } }
里面有两个参数,第一个为选择打开哪一个外设时钟,第二个为打开还是关闭;
This parameter can be any combination of the following values:
* RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
* RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
* RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3,
* RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4,
* RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2,
* RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP,
* RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
* RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14
ENABLE (打开)or DISABLE(关闭)