Bootstrap

Second_day

0\ 因咸鱼上超低价买的板子的核心板有点问题,所以不得不先用正点的mini了之后再换回洋桃,(其实是没有问题的,因为我没有编译直接下载,屮浪费了我好长时间)

一、 STLINK(jtag)下载

  • 注意PB3、4,PA14、15、13没有复用为其他功能
  • 下载前一定要先编译,不然下的是之前的!!!!!!!!!!!!!!!

二、点灯

/*  首先在rcc.h中找到开启所用到的时钟所用到的函数,开启时钟(主要用到AHB、APB2、APB1)
然后同理根据库函数配置GPIO并定义用到的结构体。
*/
int main(void)
{

//    Led_Init();   
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出负载能力更强
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;   
GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    while(1){
         GPIO_WriteBit(GPIOB,GPIO_Pin_1,(BitAction)(1)); //LED1接口输出高
}}
 

在这里插入图片描述

三、滴答定时器(计数到0时申请中断)

  • SysTick叫做系统滴答时钟、系统定时器,属于Cortex-M3内核中的一个外设(外围设备),被捆绑在NVIC(中断)中,用来产生SYSTICK异常(异常号:15)

  • 当SysTick是一个24bit 向下递减的计数器,计到0时,从RELOAD寄存器中自动装载定时初值。

  • 自动重装载

  • SysTick定时器和普通定时器在STM32微控制器中有一些明显的区别,主要体现在以下几个方面:

    1.内置位置和用途:

    2.SysTick定时器:SysTick是STM32微控制器内置的一个系统级定时器,专门用于提供系统级的时基和延时功能。它不依赖于外部时钟源,而是使用系统的主时钟(通常是AHB时钟)作为时钟源。
    3.普通定时器:普通定时器(如TIM1、TIM2等)是专门设计用于生成PWM信号、测量脉冲宽度、产生定时中断等应用的定时器。它们可以选择多种时钟源,并且具有更灵活的定时功能和计数器控制。

    4.功能和应用场景:

    5.SysTick定时器:主要用于实现操作系统的时基管理、延时函数的实现等。它通常用于生成固定周期的中断,作为系统的基础定时器。
    6.普通定时器:用于更复杂的定时任务,例如PWM输出控制、捕获外部信号、生成特定频率的时钟等。它们的功能更加多样化和灵活,可以根据具体需求配置不同的模式和计数器设置。

    7.中断优先级:

    8.SysTick定时器:SysTick定时器的中断具有固定的优先级,通常比其他普通定时器的中断优先级更高。这使得它特别适合于系统级的基本任务管理,例如操作系统的任务调度。
    9.普通定时器:普通定时器的中断优先级可以根据应用需求进行配置,更适合于特定的定时和计数功能。

    10.配置和使用:

    11.SysTick定时器:配置简单,通常通过调用一次SysTick_Config函数完成初始化,设置一个固定的中断周期。它的主要功能是提供基本的定时功能,适用于简单的时基管理和延时需求。
    12.普通定时器:配置相对复杂,需要根据具体的应用需求选择时钟源、模式、计数器设置等。普通定时器更适合于需要更精确的定时和计数功能的场合。

    总结来说,SysTick定时器是STM32中的一个基础系统定时器,专注于提供系统级的基本定时功能和延时功能;而普通定时器则更灵活多样,适合于复杂的定时和计数任务。选择使用哪种定时器取决于具体的应用需求和功能要求。

#include "stm32f10x.h"  

static volatile uint32_t msTicks; // 全局变量,用于存储毫秒计数

// SysTick中断处理函数
void SysTick_Handler(void)
{
    msTicks++; // SysTick定时器每计满1毫秒,msTicks加1
}

// 初始化SysTick定时器
void SysTick_Init(void)
{
    SysTick_Config(SystemCoreClock / 1000); // 设置每隔1毫秒触发一次SysTick中断
}

// 延时函数,延时指定的毫秒数
void Delay_ms(uint32_t ms)
{
    uint32_t start = msTicks; // 记录延时开始时的毫秒计数值

    while ((msTicks - start) < ms)
    {
        // 等待,直到msTicks增加到需要的延时毫秒数
    }
}

int main(void)
{
    // 初始化SysTick定时器
    SysTick_Init();

    while (1)
    {
        // 在这里可以调用Delay_ms函数进行延时
        Delay_ms(1000); // 延时1秒钟

        // 这里是需要执行的主程序代码
    }
}

四、GPIO作输入

在这里插入图片描述


int main (void){//主程序
//	RCC_Configuration();
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitTypeDef GPIOA_ST;GPIO_InitTypeDef GPIOB_ST;
    GPIOB_ST.GPIO_Mode= GPIO_Mode_Out_PP ;
    GPIOB_ST.GPIO_Speed  = GPIO_Speed_50MHz;
    GPIOB_ST.GPIO_Pin=GPIO_Pin_0;
    GPIOA_ST.GPIO_Mode=  GPIO_Mode_IPU;
    GPIOA_ST.GPIO_Pin=GPIO_Pin_0;
    GPIO_Init(GPIOA,&GPIOA_ST);
    GPIO_Init(GPIOB,&GPIOB_ST);
	while(1){
	if(	!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)){
            
      delay_ms(20);
    
//       GPIO_SetBits(GPIOB,GPIO_Pin_0);不如writebit灵活
      
     
      
      while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)){}
     GPIO_WriteBit( GPIOB,GPIO_Pin_0 , (BitAction) (1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0)));
    
    }
		

	}
}

五、FLASH

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 实际调运库函数实现很简单
//读取
uint32_t MyFLASH_ReadWord(uint32_t Address )
{

return *((volatile u32 *)(Address));

}
uint16_t MyFLASH_ReadHalfWord(uint32_t Address )
{

return *((volatile u16 *)(Address));

}
uint8_t MyFLASH_ReadByte(uint32_t Address )
{

return *((volatile u8 *)(Address));

}

//闪存擦除(前后开关锁)
void MyFLASH_ErasePage(u32 Page_Address )
{

FLASH_Unlock();
FLASH_ErasePage(Page_Address);//or   FLASH_EraseAllPages();
FLASH_Lock();

}

//写入字/半字(前后开关锁)
void MyFLASH_Write(u32 Address, u32 Data)

{
FLASH_Unlock();
FLASH_ProgramWord(Address, Data);//FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
写入半字时高4位为FFFF低4位为写入数据
FLASH_Lock();
}
  • STM32微控制器中的“半字”(Half-word)通常指的是16位(2字节)的数据类型。在STM32系列中,内存中的数据通常以字(Word)为单位进行存储和访问,一个字是32位(4字节)。因此,STM32中的半字实际上是指两个字节的数据,因为微控制器的内存和总线结构是按照字节寻址的,所以即使你在程序中只使用了16位数据类型,它也会占用2个字节的存储空间。
//写入前先要擦除
u16 Store_Data[512];

void Store_Init(void)//每次重新上电后都会通过此函数向Sram传输储存的数据
{   if(MyFLASH_ReadHalfWord(0x0800FC00)!=0xA5A5)//确保第一次未存入数据时
    {
          MyFLASH_ErasePage( 0x0800FC00);//调用擦除,然后写入标志位
          MyFLASH_Write(0x0800FC00,0xA5A5);
        for(u16 i=1 ;i<512;i++)//将数据存入flash
          {
                MyFLASH_Write(0x0800FC00+i*2,0x0000);//确保没用到的也都置为0
          
          }
    }
    
     for(u16 i=0 ;i<512;i++)//将数据传给SRAM
          {
                Store_Data[i]= MyFLASH_ReadHalfWord(0x0800FC00+i*2);
          
          }  
    
    
}

  void Store_Save(void)
  {
     
         MyFLASH_ErasePage(0x0800FC00);
          for(u16 i=0 ;i<512;i++){
              MyFLASH_Write(0x0800FC00+i*2,Store_Data[i]);//Store_Data[0]为标志位不能使用
          
          }   
  
  }
  
    

在这里插入图片描述

六、蜂鸣器驱动

  • 确保结束时为高电平状态,防止三极管一直导通烧坏蜂鸣器。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;