智能门锁第一讲

第一讲沁恒CH32V307————SayOhYeah

初识单片机

寄存器开发和标准库开发的区别

  • 寄存器开发:需要开发者详细阅读芯片手册,了解每个寄存器的位含义,配置过程繁琐,容易出错,开发效率低,难度较高。
  • 标准库开发:库函数通常有良好的命名和结构,配置外设只需调用相应的初始化函数,设置参数即可,开发效率高,难度较低。

结构体与数组之间的区别

​ 数组是只可以申请一段同类型的地址进行存储

​ 结构体可以申请的内存中可以存储不同类型的数据

GPIO的8中工作模式

  1. 输入浮空(Input Floating):引脚处于高阻态,即既不接上拉电阻也不接下拉电阻。输入电平完全由外部电路决定,适用于外部已经确定电平或者接有上拉/下拉电阻的情况。
  2. 输入上拉(Input Pull-up):内部接有上拉电阻,默认电平为高。当外部没有信号驱动时,引脚电平为高;外部拉低时,引脚电平为低。
  3. 输入下拉(Input Pull-down):内部接有下拉电阻,默认电平为低。当外部没有信号驱动时,引脚电平为低;外部拉高时,引脚电平为高。
  4. 模拟输入(Analog Input):将引脚设置为模拟输入模式,用于ADC(模数转换)或DAC(数模转换)等模拟功能。此模式下,引脚的数字输入功能被禁用,以减少功耗和干扰。
  5. 开漏输出(Open-Drain Output):输出晶体管仅接通到地(低电平),高电平靠外部上拉电阻拉高。这种模式可以实现电平转换(比如用3.3V控制5V设备)和总线连接(如I2C总线)。
  6. 推挽输出(Push-Pull Output):输出晶体管可以接通到高电平或低电平,能够直接驱动负载。这是最常用的输出模式,可以提供较强的驱动能力。
  7. 复用开漏输出(Alternate Function Open-Drain):当引脚用于外设功能(如I2C)时,工作于开漏模式。
  8. 复用推挽输出(Alternate Function Push-Pull):当引脚用于外设功能(如SPI、USART)时,工作于推挽模式。

如何使用标准库点亮一个LED灯

    GPIO_InitTypeDef GPIO_InitStructure = {0};//定义一个gpio_InitTyprDef类型的结构体
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//查找总线架构打开对应GPIO口的时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//在结构体中选择我们要使能的gpio口
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//选择使能的gpio口的输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择gpio口的频率
    
    GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化gpio口

   GPIO_SetBits(GPIOC, GPIO_Pin_2);//发出高电平
   Delay_Ms(500);//延时500ms
   GPIO_ResetBits(GPIOC, GPIO_Pin_2);//发出低电平
    Delay_Ms(500);//延时500ms

如何使用标准库的定时器让LED闪烁

单片机主时钟频率为96兆(96 000 000)相当于一秒钟可以加96 000 000

void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));//定时器2快速中断
unsigned int time_1000ms;//中断计数值
unsigned char Led_Flag;//LED闪烁标志位

void Tim3_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_TimeBaseInitStruct.TIM_ClockDivision=0;//时钟分割
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//设置为向上计数
    TIM_TimeBaseInitStruct.TIM_Period=arr;//自动重装载值,5000为500ms
    TIM_TimeBaseInitStruct.TIM_Prescaler=psc;//设置分频值

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
    TIM_ITConfig(TIM3, TIM_IT_Update|TIM_IT_Trigger, ENABLE);



    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //打开中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET)
    {
      if(++time_1000ms==1000)
      {
          time_1000ms = 0;
          Led_Flag =!Led_Flag;
          if(Led_Flag)
          {
              GPIO_SetBits(GPIOC, GPIO_Pin_2);
          }
       else {
        GPIO_ResetBits(GPIOC, GPIO_Pin_2);
    }
    }
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
}
 int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	USART_Printf_Init(115200);	
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
     //
    Tim3_Init(1000,96-1);//设置自动重装载值1秒进入一次设置分频值
	while(1)
    {

	}
}

使用标准库的串口进行收发数据

  • 配置串口三将串口3接收到的数据加一发送出来波特率是115200;

    具体步骤

    • 移植串口三的初始化函数
    • 移植串口三的中断函数
    • 声明快捷中断
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));//串口2快速中断
void Usart3_Init()//初始化usart3
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;

    USART_Init(USART3, &USART_InitStructure);
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

     NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);

     USART_Cmd(USART3, ENABLE);
}

u8 usart3_state;
void USART3_IRQHandler(void)//开启串口中断
{
    u8 temp;
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        temp=USART_ReceiveData(USART3);
        USART_SendData(USART3, temp+1);
    }
    USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
 int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	USART_Printf_Init(115200);	
    Usart3_Init();
	while(1)
    {

	}
}