程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

STM32F103 PWM配置

在《STM32F103定时器配置》中我们介绍了PWM的产生原理,本节介绍介绍如何编码实现PWM的输出。

一、PWM相关寄存器

TIMx如果要产生PWM,除了我们上一节提到的如下寄存器:

还需要使用到:

  • 捕获/比较模式寄存器(TIMx_CCM1/2);
  • 捕获/比较使能寄存器(TIMx_CCER);
  • 捕获/比较寄存器(TIMx_CCR1~4);
  • 刹车和死区寄存器(TIMx_BDTR)(只有高级定时器用到)。

注意:这里捕获指的是输入捕获,比较指的时输出比较。

1.1 捕获/比较模式寄存器(TIMx_CCMR1/2

捕获/比较模式寄存器一共有两个:

  • TIMx_CCMR1:控制通道1和2;
  • TIMx_CCMR2:控制通道3和4;

这里以 TIMx_CCM1寄存器为例进行介绍:

1.2 捕获/比较使能寄存器(TIMx_CCER

TIMx_CCER寄存器每4位描述一个通道;

其中:

  • CCxE:输入/捕获x输出使能位,我们需要重点关注;
  • CCxP:输入/捕获x输出极性。

1.3 捕获/比较寄存器(TIMx_CCR1~4

捕获/比较模式寄存器一共有4个,依次用于描述每一个通道,这里以TIMx_CCR1为例;

1.4 刹车和死区寄存器(TIMx_BDTR

TIMx_BDTR寄存器需要重点关注位15主输出使能位;

二、PWM生成源码

2.1 PWM初始化步骤

PWM生成配置流程如下:

(1) TIMx时钟使能:通过配置RCC_APB1ENR/RCC_APB2ENR寄存器使能TIMx时钟;

(2) GPIO功能复用:配置GPIO(比如TIM1通道1PA8)为复用功能推挽输出模式;

(3) 配置TIMx时基单元;

  • 配置TIMx_ARR寄存器自动重装载的值;
  • 配置TIMx_PSC寄存器预分频系数;

(4) 配置PWM相关寄存器;

  • 配置TIMx_CCMRx寄存器:

    • 输入捕获/比较输出选择(CCxS):配置为比较输出(用于实现PWM输出功能);
    • 输出比较模式(CCxM):配置为PWM模式1或者PWM模式2;
  • 配置TIMx_CCER寄存器:

    • 输入捕获/比较输出使能(CCxE):即开启比较输出功能,这样才能输出PWM
  • 针对高级定时器配置TIMx_BDTR寄存器位15:使能PWM输出;

(5) 允许TIMx工作:配置TIMx_CR10

(6) 修改TIMx_CCRx寄存器可以改变占空比。

2.2 源码实现

2.2.1 PWM初始化

PWM初始化函数TIM_PWM_Init定义如下:

/**************************************************************************************************************
 *
 *		 Description:   高级定时器1和8   APB2预分频系数=1 则计数器的时钟频率为 APB2  否则APB2*2
 *						 通用定时器2~7    APB1预分频系数=1 则计数器的时钟频率为 APB1  否则APB1*2
 *       Parameter  :    timx           TIMER1~TIMER5 8
                         DEFAULT_PSC    默认预分频系数 
                                        计数器的时钟频率 =  Fclk/(PSC[15:0]+1)   Fclk单位MHZ    
                         time           中断时间 = (ARR+1)/计数器的时钟频率       单位us
                                        中断频率 = Fclk*1000/((PSC+1)*(ARR+1))  单位kHZ
 *						 frequent       频率: 1~360  单位khz
						 Channel		通道		  PWM_CH1~4
 *
 **************************************************************************************************************/ 
void TIM_PWM_Init(TIMn timn,u8 frequent,PWM_CHANNEL Channel)         //PWM初始化                  
{
    u16 arr;							    //存放自动重装载的值
	u8 fclk;                                //存放定时器时钟频率  MHZ
	u16 DEFAULT_PSC = 1;					//默认预分频系数为1
	u8 REMAP=0x00;                          //映射情况 0x00默认 0x01  0x02:  0x03  自己设置   
	if(timn==0||timn==7) 	                //定时器1或8   
	{
		 fclk = 72;                        //默认APB2 1倍频
	}
	else 
	{
	     fclk =72;						   //默认APB1 2倍频
	}
	arr = fclk*1000/(DEFAULT_PSC+1)/frequent-1;
	//**************************************************************************************** 
	if(timn==0)                        //定时器1
	{
	  RCC->APB2ENR |=1<<11;                 //高级定时器1时钟使能
	  TIM1->BDTR|=1<<15;                    //主输出(pwm)使能(必须)
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA8,GPO_MULPUSH_PULL_50,HIGH);     //复用推挽输出,最大速度50MHZ    主输出
			gpio_init(PB13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ	 互补输出
			break;
		 case  PWM_CH2:
          	gpio_init(PA9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<6);                   //位7:6清零   
		 AFIO->MAPR   |= REMAP<<6;                   //TIM1部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<6);                   //位7:6清零   
		 AFIO->MAPR   |= REMAP<<6;                   //TIM1完全映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PE9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PE8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PE11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PE10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PE13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PE12,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PE14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  }
	}
	//********************************************************************************************   
	else if(timn==1)                   //定时器2
	{
	  RCC->APB1ENR |=1<<0;                  //定时器2时钟使能  
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x02)									   //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<8);                   //位9:8清零   
		 AFIO->MAPR   |= REMAP<<8;                   //TIM2部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB10,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB11,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  } 
	}   
	//*****************************************************************************************************************       
    else if(timn==2)                   //定时器3
	{
	  REMAP=0x03; 
	  RCC->APB1ENR |=1<<1;                  //定时器3时钟使能 
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x02)									   //部分映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<10);                   //位11:10清零   
		 AFIO->MAPR   |= REMAP<<10;                   //TIM3部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PB4,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB5,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else if(REMAP==0x03)									   //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟
		 AFIO->MAPR   &=~(0x3<<10);                   //位11:10清零   
		 AFIO->MAPR   |= REMAP<<10;                   //TIM3部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PC6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PC7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PC8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PC9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }	  
	  } 
	  else
	  {
	    ASSERT(0);
	  }  

	}   
    //*********************************************************************************************************	    
	else if(timn==3)                   //定时器4
	{
	  RCC->APB1ENR |=1<<2;                  //定时器4时钟使能  
	  if(REMAP==0x00)          //默认情况下
	  {
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PB6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PB7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PB8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PB9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else if(REMAP==0x01)	     //完全映射
	  {
	     RCC->APB2ENR |= 1<<0;                       //使能I/O复用时钟  
		 AFIO->MAPR   |= REMAP<<12;                  //TIM4部分映射 
	     switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PD12,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PD13,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PD14,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PD15,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	  }
	  else
	  {
	    ASSERT(0);
	  } 
	}  
	//*********************************************************************************************************** 	              
    else if(timn==4)                   //定时器5
	{
	  RCC->APB1ENR |=1<<3;                  //定时器5时钟使能
	  switch(Channel)
		 {
		 case  PWM_CH1:
          	gpio_init(PA0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PA1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PA2,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PA3,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 }
	}    
	//********************************************************************************************************
	else if(timn==7)      
	{
	   RCC->APB2ENR |=1<<13;                //定时器8时钟使能
	   TIM8->BDTR|=1<<15;                    //主输出(pwm)使能(必须) 
	   switch(Channel)
	   {  
	   case  PWM_CH1:
          	gpio_init(PC6,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		  	gpio_init(PA7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH2:
          	gpio_init(PC7,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
		    gpio_init(PB0,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH3:
          	gpio_init(PC8,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			gpio_init(PB1,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 case  PWM_CH4:
            gpio_init(PC9,GPO_MULPUSH_PULL_50,HIGH);    //复用推挽输出,最大速度50MHZ
			break;
		 } 
	}	           
	else
	{
	   ASSERT(0);
	}                           
    TIMx[timn]->PSC  = DEFAULT_PSC;       //预分频值
    TIMx[timn]->ARR  = arr;		    	  //重新装载的值
	switch(Channel)
	{
	  case PWM_CH1:
	        TIMx[timn]->CCMR1 |=0x07<<4;    //PWM2输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;  //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;       //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F;       //低电平有效 CH1使能  如是TIM1则互补输出使能
	        TIMx[timn]->CCR1  =0;           //初始化占空比为0
			break;
	 case PWM_CH2:
	        TIMx[timn]->CCMR1 |=0x07<<12;    //PWM2输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F<<4;     //低电平有效 CH2使能  如是TIM1则互补输出使能
	        TIMx[timn]->CCR2  =0;            //初始化占空比为0
			break;
	 case PWM_CH3:
	        TIMx[timn]->CCMR2 |=0x07<<4;     //PWM3输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER |=  0x0F<<8;     //低电平有效 CH3使能	如是TIM1则互补输出使能
	        TIMx[timn]->CCR3  =0;            //初始化占空比为0
			break;
	 case PWM_CH4:
	        TIMx[timn]->CCMR2 |=0x07<<12;    //PWM4输出模式设置
			//TIMx[timn]->CCMR1 |=0X01<<3;   //输出比较预装载使能 1:更新事件时装载
			//TIMx[timn]->CR1 = 1<<7;        //自动重装在预装载允许位
			TIMx[timn]->CCER =  0x03<<12;     //低电平有效 CH2使能
	        TIMx[timn]->CCR4  =0;            //初始化占空比为0
			break;
	}
	
    //TIMx[timn]->DIER = 1<<0;				//允许更新(溢出)中断   UIE=1;
      TIMx[timn]->CR1  = 1<<0;              //使能计数器 开始计数
}

亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。

日期姓名金额
2023-09-06*源19
2023-09-11*朝科88
2023-09-21*号5
2023-09-16*真60
2023-10-26*通9.9
2023-11-04*慎0.66
2023-11-24*恩0.01
2023-12-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
2024-09-06*强8.8
2024-09-09*波1
2024-09-10*口1
2024-09-10*波1
2024-09-12*波10
2024-09-18*明1.68
2024-09-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(335)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2023-12-05 Rockchip RK3588 - 移植uboot 2017.09 & linux 6.1(友善之家脚本方式)
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示