> 文章列表 > 从0学习stm32第二天

从0学习stm32第二天

从0学习stm32第二天

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):

推挽输出:有一定的驱动能力,可以真正地输出高低电平;

开漏输出:没有驱动能力,想要驱动设备要接上拉电阻,只能输出低电平;

 深入了解8种输入输出

(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(关闭)

  4.STE32定时器

(1)定时器简单介绍:

高级控制定时器   TIM1和TIM8

 

通用定时器    TIMX(2~5)

 

基本定时器     TIMX6和TIM7

(2)定时器PWM输出:

        PWM:脉冲宽度调制(频率可以设定,占空比可动态调节)

        1)原理:

每个定时器有四个通道:OC1~OC4

有RCC给到72MHz

 PSC:预分频

1~65536所以定义时为0~65535;

CNT:计数器

若CNT为1000,那么1到1000为一个周期,然后定时器定义为500,让其前500为高电平,后500为低电平;

         2)固件库函数:

void TIM_DeInit(TIM_TypeDef* TIMx);
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

(1)定时器的初始化:

初始化函数:有两个参数第一个是选择用哪一个定时器,第二个是结构体;

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
typedef struct
{uint16_t TIM_Prescaler;      //预分屏值PSC,给到CNT,是CNT的计数频率                                uint16_t TIM_CounterMode;    //计数模式  //#define TIM_CounterMode_Up                 ((uint16_t)0x0000)向上
//#define TIM_CounterMode_Down               ((uint16_t)0x0010)向下uint16_t TIM_Period;         //计数值  周期=计数值所用时间uint16_t TIM_ClockDivision;    uint8_t TIM_RepetitionCounter;  
} TIM_TimeBaseInitTypeDef;       

(2)输出通道的初始化:

第一个参数也是选择定时器,第二个还是结构体指针;

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
typedef struct
{uint16_t TIM_OCMode;     //输出模式   
//#define TIM_OCMode_PWM1                    ((uint16_t)0x0060)
//#define TIM_OCMode_PWM2                    ((uint16_t)0x0070)uint16_t TIM_OutputState;  //输出状态
//#define TIM_OutputState_Disable            ((uint16_t)0x0000)
//#define TIM_OutputState_Enable             ((uint16_t)0x0001)uint16_t TIM_OutputNState;  //互补输出(1和8有)uint16_t TIM_Pulse;         //比较寄存器中的值uint16_t TIM_OCPolarity;    //输出极性的设置 
//#define TIM_OCPolarity_High                ((uint16_t)0x0000)
//#define TIM_OCPolarity_Low                 ((uint16_t)0x0002)uint16_t TIM_OCNPolarity;    //互不输出极性;uint16_t TIM_OCIdleState;                             uint16_t TIM_OCNIdleState;  } TIM_OCInitTypeDef;

PWM1模式:CNT<CRRx(比较寄存器),输出为有效电平

PWM2模式:相反

有效电平由极性决定;

 uint16_t TIM_OCPolarity;    //输出极性的设置 
//#define TIM_OCPolarity_High                ((uint16_t)0x0000)
//#define TIM_OCPolarity_Low                 ((uint16_t)0x0002)

设置高则有效电平为高,反之为低

(3)设置OCx的比较寄存器预装载功能

第一个参数是哪一个定时器,第二个是打开还是关闭

1,2,3,4,5,8,15

ENABLEor DISABLE

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

(4)设置自动重装在使能

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

参数同上一个

(5)开启计时器的计数功能;

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

(6)设置时钟位置:

 (7)PWM:GPIO为推挽输出模式