• 29_RTC实时时钟实验


    目录

    RTC工作原理框图

    配置RTC寄存器

    配置过程:

    读RTC寄存器

    RTC相关库函数讲解

    RTC配置一般步骤

    实验源码


    RTC工作原理框图

     工作原理上一篇博客有详细讲解。

    配置RTC寄存器

    必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、 RTC_ALR寄存器。另外,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是'1'时,才可以写入RTC寄存器。

    配置过程:

    1.查询RTOFF位,直到RTOFF的值变为'1”

    2.置CNF值为1,进入配置模式

    3.对一个或多个RTC寄存器进行写操作

    4.清除CNF标志位,退出配置模式

    5.查询RTOFF,直至RTOFF位变为'1'以确认写操作已经完成。

    仅当CNF标志位被清除时,写操作才能进行,这个过程至少需要3个RTCCLK周期。

    读RTC寄存器

    RTC核完全独立于RTC APB1

    软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是如此的。"这意味着,如果APB1接门曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。下述几种情况下能够发生这种情形:

    发生系统复位或电源复位系统刚从待机模式唤醒。

    系统刚从停机模式唤醒。

    所有以上情况中APB1接口被禁止时(复位、无时钟或断电)RTC核仍保持运行状态。因此,若在读取RTC寄存器时, RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置'1'。

    RTC相关库函数讲解

    RTC时钟源和时钟操作函数:

    void RCC_RTCCLKConfig(uint32_t CLKSource): //时钟源选择

    void RCC_RTCCLKCmd(FunctionalState NewState)//时钟使能

    RTC配置函数(预分频,计数值:

    void RTC_SetPrescaler(uint32_t PrescalerValue);//预分频配置: PRLH/PRLL

    void RTC_SetCounter(uint32_t CounterValue): //设置计数器值: CNTH/CNTL

    void RTC SetAlarm(uint32 tAlarmValue); //闹钟设置: ALRH/ALRL

    RTC中断设置函数:

    void RTC_ITConfig(uint16_tRTC_IT, FunctionalState NewState);//CRH

    RTC允许配置和退出配置函数:

    void RTC_EnterConfigMode(void);//允许RTC配置:CRL位 CNF

    void RTC_ExitConfigMode(void);//退出配置模式:CRL位 CNF

    同步函数:

    void RTC_WaitForLastTask(void); //等待上次操作完成: CRL位RTOFF

    void RTC_WaitForSynchro(void); //等待时钟同步: CRL位RSF

    相关状态位获取清除函数:

    FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);

    void RTC_ClearFlag(uint16_t RTC_FLAG);

    ITStatus RTC_GetITStatus(uint16_t RTC_IT);

    void RTC_ClearlTPendingBit(uint16_t RTC_IT);

    其他相关函数(BKP等)

    PWR_BackupAccessCmd();//BKP后备区域访问使能

    RCC_APB1 PeriphClockCmd();//使能PWR和BKP时钟

    RCC LSEConfig();//开启LSE, RTC选择LSE作为时钟源

    RTC配置一般步骤

    使能PWR和BKP时钟: RCC_APB1PeriphClockCmd();

    使能后备寄存器访问: PWR_BackupAccessCmd();

    配置RTC时钟源,使能RTC时钟:

    RCC_RTCCLKConfig();

    RCC_RTCCLKCmd();

    如果使用LSE,要打开LSE: RCC_LSEConfig(RCC_LSE_ON);

    设置RTC预分频系数: RTC_SetPrescaler();

    设置时间: RTC_SetCounter();

    开启相关中断(如果需要) RTC_ITConfig();

    编写中断服务函数: RTC_IRQHandler();

    部分操作要等待写操作完成和同步。

    RTC_WaltForLastTask();//等待最近一次对RTC寄存器的写操作完成

    RTC WaitForSynchro(); //等待RTC寄存器同步

    实验源码

    1. /**
    2. ******************************************************************************
    3. * @file : user_rcc_config.c
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Include 包含---------------------------------------------------------------*/
    11. #include "user_rcc_config.h"
    12. /* Typedef 类型----------------------------------------------------------------*/
    13. /* Define 定义----------------------------------------------------------------*/
    14. /* Macro 宏------------------------------------------------------------------*/
    15. /* Variables 变量--------------------------------------------------------------*/
    16. /* Constants 常量--------------------------------------------------------------*/
    17. /* Function 函数--------------------------------------------------------------*/
    18. /*!
    19. \brief RCC配置
    20. \param[in] none
    21. \param[out] none
    22. \retval none
    23. */
    24. void Rcc_config(void)
    25. {
    26. /*使能PWR时钟*/
    27. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
    28. /*使能BKP外设时钟*/
    29. RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
    30. /*使能后备寄存器才可以访问*/
    31. PWR_BackupAccessCmd(ENABLE);
    32. /*使能GPIOA时钟*/
    33. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    34. /*使能UART1时钟*/
    35. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    36. }
    37. /************************************************************** END OF FILE ****/
    1. /**
    2. ******************************************************************************
    3. * @file : user_gpio.c
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Include 包含---------------------------------------------------------------*/
    11. #include "user_gpio.h"
    12. /* Typedef 类型----------------------------------------------------------------*/
    13. /* Define 定义----------------------------------------------------------------*/
    14. /* Macro 宏------------------------------------------------------------------*/
    15. /* Variables 变量--------------------------------------------------------------*/
    16. /* Constants 常量--------------------------------------------------------------*/
    17. /* Function 函数--------------------------------------------------------------*/
    18. /*!
    19. \brief GPIO初始化函数
    20. \param[in] none
    21. \param[out] none
    22. \retval none
    23. */
    24. void Gpio_Init(void)
    25. {
    26. /*GPIO结构体*/
    27. GPIO_InitTypeDef GPIO_InitTypeDefstruct;
    28. /*UART1发送引脚配置*/
    29. GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出
    30. GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_9;
    31. GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
    32. /*写入结构体到GPIOA*/
    33. GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
    34. /*UART1接收引脚配置*/
    35. GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    36. GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_10;
    37. GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
    38. /*写入结构体到GPIOA*/
    39. GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
    40. }
    41. /************************************************************** END OF FILE ****/
    1. /**
    2. ******************************************************************************
    3. * @file : user_uart.c
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Include 包含---------------------------------------------------------------*/
    11. #include "user_uart.h"
    12. /* Typedef 类型----------------------------------------------------------------*/
    13. /* Define 定义----------------------------------------------------------------*/
    14. /* Macro 宏------------------------------------------------------------------*/
    15. /* Variables 变量--------------------------------------------------------------*/
    16. extern uint16_t USART_RX_STA;
    17. extern uint8_t USART_RX_BUF[200];
    18. /* Constants 常量--------------------------------------------------------------*/
    19. /* Function 函数--------------------------------------------------------------*/
    20. #if 1
    21. #pragma import(__use_no_semihosting)
    22. /*实现Printf代码*/
    23. struct __FILE
    24. {
    25. int handle;
    26. };
    27. FILE __stdout;
    28. void _sys_exit(int x)
    29. {
    30. x = x;
    31. }
    32. //重定义fputc函数
    33. int fputc(int ch, FILE *f)
    34. {
    35. while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
    36. USART1->DR = (u8) ch;
    37. return ch;
    38. }
    39. #endif
    40. /*!
    41. \brief UART1初始化
    42. \param[in] none
    43. \param[out] none
    44. \retval none
    45. */
    46. void Uart1_Init(u32 bound)
    47. {
    48. /*UART结构体*/
    49. USART_InitTypeDef USART_InitTypeDefstruct;
    50. /*UART结构体配置*/
    51. USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率
    52. USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
    53. USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
    54. USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
    55. USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
    56. USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
    57. /*写入USART1*/
    58. USART_Init(USART1,&USART_InitTypeDefstruct);
    59. /*使能串口1*/
    60. USART_Cmd(USART1,ENABLE);
    61. }
    62. /*!
    63. \brief UART1中断服务函数
    64. \param[in] none
    65. \param[out] none
    66. \retval none
    67. */
    68. void USART1_IRQHandler(void)
    69. {
    70. }
    71. /************************************************************** END OF FILE ****/
    1. /**
    2. ******************************************************************************
    3. * @file : user_rtc.h
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Define to prevent recursive incluson---------------------------------------*/
    11. #ifndef _USER_RTC_H__
    12. #define _USER_RTC_H__
    13. /* Include 包含---------------------------------------------------------------*/
    14. #include "stm32f10x.h"
    15. #include "user_delay.h"
    16. #include "user_uart.h"
    17. /* Typedef 类型----------------------------------------------------------------*/
    18. typedef struct
    19. {
    20. uint8_t hour; //时
    21. uint8_t min; //分
    22. uint8_t sec; //秒
    23. uint16_t year; //年
    24. uint8_t month;//月
    25. uint8_t date; //日
    26. uint8_t week; //周
    27. }Calendar;
    28. /* Define 定义----------------------------------------------------------------*/
    29. /* Macro 宏------------------------------------------------------------------*/
    30. /* Variables 变量--------------------------------------------------------------*/
    31. /* Constants 常量--------------------------------------------------------------*/
    32. /* Function 函数--------------------------------------------------------------*/
    33. uint8_t Rtc_Init(void);
    34. #endif
    35. /************************************************************** END OF FILE ****/
    1. /**
    2. ******************************************************************************
    3. * @file : user_rtc.c
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Include 包含---------------------------------------------------------------*/
    11. #include "user_rtc.h"
    12. /* Typedef 类型----------------------------------------------------------------*/
    13. /* Define 定义----------------------------------------------------------------*/
    14. /* Macro 宏------------------------------------------------------------------*/
    15. /* Variables 变量--------------------------------------------------------------*/
    16. /*时间结构体*/
    17. Calendar timer;
    18. /* Constants 常量--------------------------------------------------------------*/
    19. /*月修正数据表*/
    20. uint8_t const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};
    21. /*平年的月份日期表*/
    22. const uint8_t mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    23. /* Function 函数--------------------------------------------------------------*/
    24. /*!
    25. \brief 判断是否是闰年函数
    26. \param[in] 年份
    27. \param[in] none
    28. \retval 该年份是不是闰年.1,是.0,不是
    29. */
    30. uint8_t Is_Leap_Year(u16 year)
    31. {
    32. if(year%4==0) //必须能被4整除
    33. {
    34. if(year%100==0)
    35. {
    36. if(year%400==0)return 1;//如果以00结尾,还要能被400整除
    37. else return 0;
    38. }else return 1;
    39. }else return 0;
    40. }
    41. /*!
    42. \brief 获得现在是星期几函数
    43. \param[in] 输入公历日期得到星期(只允许1901-2099年)年月日
    44. \param[in] none
    45. \retval 星期号
    46. */
    47. uint8_t RTC_Get_Week(u16 year,u8 month,u8 day)
    48. {
    49. u16 temp2;
    50. u8 yearH,yearL;
    51. yearH=year/100; yearL=year%100;
    52. // 如果为21世纪,年份数加100
    53. if (yearH>19)yearL+=100;
    54. // 所过闰年数只算1900年之后的
    55. temp2=yearL+yearL/4;
    56. temp2=temp2%7;
    57. temp2=temp2+day+table_week[month-1];
    58. if (yearL%4==0&&month<3)temp2--;
    59. return(temp2%7);
    60. }
    61. /*!
    62. \brief 得到当前的时间函数
    63. \param[in] none
    64. \param[in] none
    65. \retval 0,成功;其他:错误代码.
    66. */
    67. u8 Rtc_Get(void)
    68. {
    69. static u16 daycnt=0;
    70. u32 timecount=0;
    71. u32 temp=0;
    72. u16 temp1=0;
    73. timecount=RTC_GetCounter();
    74. temp=timecount/86400; //得到天数(秒钟数对应的)
    75. if(daycnt!=temp)//超过一天了
    76. {
    77. daycnt=temp;
    78. temp1=1970; //从1970年开始
    79. while(temp>=365)
    80. {
    81. if(Is_Leap_Year(temp1))//是闰年
    82. {
    83. if(temp>=366)temp-=366;//闰年的秒钟数
    84. else {temp1++;break;}
    85. }
    86. else temp-=365; //平年
    87. temp1++;
    88. }
    89. timer.year=temp1;//得到年份
    90. temp1=0;
    91. while(temp>=28)//超过了一个月
    92. {
    93. if(Is_Leap_Year(timer.year)&&temp1==1)//当年是不是闰年/2月份
    94. {
    95. if(temp>=29)temp-=29;//闰年的秒钟数
    96. else break;
    97. }
    98. else
    99. {
    100. if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
    101. else break;
    102. }
    103. temp1++;
    104. }
    105. timer.month=temp1+1; //得到月份
    106. timer.date=temp+1; //得到日期
    107. }
    108. temp=timecount%86400; //得到秒钟数
    109. timer.hour=temp/3600; //小时
    110. timer.min=(temp%3600)/60; //分钟
    111. timer.sec=(temp%3600)%60; //秒钟
    112. timer.week=RTC_Get_Week(timer.year,timer.month,timer.date);//获取星期
    113. return 0;
    114. }
    115. /*!
    116. \brief 设置时钟以1970年1月1日为基准
    117. \param[in] 年月日时分秒
    118. \param[in] none
    119. \retval 1是大于2099错误,0设置成功
    120. */
    121. u8 Rtc_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
    122. {
    123. u16 t;
    124. u32 seccount=0;
    125. if(syear<1970||syear>2099)return 1;
    126. for(t=1970;t//把所有年份的秒钟相加
    127. {
    128. if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数
    129. else seccount+=31536000; //平年的秒钟数
    130. }
    131. smon-=1;
    132. for(t=0;t//把前面月份的秒钟数相加
    133. {
    134. seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加
    135. if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数
    136. }
    137. seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加
    138. seccount+=(u32)hour*3600;//小时秒钟数
    139. seccount+=(u32)min*60; //分钟秒钟数
    140. seccount+=sec;//最后的秒钟加上去
    141. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
    142. PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问
    143. RTC_SetCounter(seccount); //设置RTC计数器的值
    144. RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
    145. return 0;
    146. }
    147. /*!
    148. \brief RTC初始化
    149. \param[in] none
    150. \param[in] none
    151. \retval 1失败,0成功
    152. */
    153. uint8_t Rtc_Init(void)
    154. {
    155. /*中断结构体*/
    156. NVIC_InitTypeDef NVIC_InitStructure;
    157. uint8_t Value = 0;
    158. /*RTC只需要初初始化一次,因为断电后备份寄存器还是会保存,
    159. 这里的4040可以自己定义,根据上次初始化成功后写入的值判断
    160. 是否还需要初始化*/
    161. if (BKP_ReadBackupRegister(BKP_DR1) != 0x4040)
    162. {
    163. /*复位备份区域 */
    164. BKP_DeInit();
    165. /*设置外部低速晶振(LSE),使用外设低速晶振*/
    166. RCC_LSEConfig(RCC_LSE_ON);
    167. /*检查指定的RCC标志位设置与否,等待低速晶振就绪*/
    168. while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&Value<250)
    169. {
    170. /*等待2秒*/
    171. Value++;
    172. delay_ms(10);
    173. }
    174. if(Value >= 250)
    175. {
    176. /*初始化失败,晶振异常返回1*/
    177. return 1;
    178. }
    179. /*设置RTC时钟(RTCCLK),选择LSE作为RTC时钟32.768kHz*/
    180. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    181. /*使能RTC时钟*/
    182. RCC_RTCCLKCmd(ENABLE);
    183. /*等待最近一次对RTC寄存器的写操作完成*/
    184. RTC_WaitForLastTask();
    185. /*等待RTC寄存器同步*/
    186. RTC_WaitForSynchro();
    187. /*使能RTC秒中断*/
    188. RTC_ITConfig(RTC_IT_SEC, ENABLE);
    189. /*使能RTC秒中断*/
    190. RTC_ITConfig(RTC_IT_SEC, ENABLE);
    191. /*等待最近一次对RTC寄存器的写操作完成*/
    192. RTC_WaitForLastTask();
    193. /*允许配置*/
    194. RTC_EnterConfigMode();
    195. /*设置RTC预分频重装载值
    196. 32.768Khz/32767+1 = 1Hz*/
    197. RTC_SetPrescaler(32767);
    198. /*等待最近一次对RTC寄存器的写操作完成*/
    199. RTC_WaitForLastTask();
    200. /*设置时间*/
    201. Rtc_Set(2022,12,5,21,25,10);
    202. /*退出配置模式*/
    203. RTC_ExitConfigMode();
    204. /*备份寄存器1里写入0x4040*/
    205. BKP_WriteBackupRegister(BKP_DR1, 0x4040);
    206. }
    207. /*不需要重新配置*/
    208. else
    209. {
    210. /*等待最近一次对RTC寄存器的写操作完成*/
    211. RTC_WaitForSynchro();
    212. /*使能RTC秒中断*/
    213. RTC_ITConfig(RTC_IT_SEC, ENABLE);
    214. /*等待最近一次对RTC寄存器的写操作完成 */
    215. RTC_WaitForLastTask();
    216. }
    217. /*中断NVIC配置*/
    218. NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
    219. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//先占优先级1位,从优先级3位
    220. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//先占优先级0位,从优先级4位
    221. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能该通道中断
    222. /*写入结构体*/
    223. NVIC_Init(&NVIC_InitStructure);
    224. /*初始化*/
    225. return 0;
    226. }
    227. /*!
    228. \brief RTC时钟中断
    229. \param[in] none
    230. \param[in] none
    231. \retval none
    232. */
    233. void RTC_IRQHandler(void)
    234. {
    235. if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
    236. { /*时间写入结构体*/
    237. Rtc_Get();//更新时间
    238. /*打印当前时间*/
    239. printf("当前时间:%d-%d-%d %d:%d:%d\r\n",timer.year,timer.month,timer.date,timer.hour,timer.min,timer.sec);
    240. }
    241. /*清1s中断*/
    242. RTC_ClearITPendingBit(RTC_IT_SEC);
    243. /*等待最近一次对RTC寄存器的写操作完成*/
    244. RTC_WaitForLastTask();
    245. }
    246. /************************************************************** END OF FILE ****/
    1. /**
    2. ******************************************************************************
    3. * @file : user_mian.h
    4. * @brief : V1.00
    5. ******************************************************************************
    6. * @attention
    7. *
    8. ******************************************************************************
    9. */
    10. /* Include 包含---------------------------------------------------------------*/
    11. #include "stm32f10x.h"
    12. #include
    13. #include "user_gpio.h"
    14. #include "user_delay.h"
    15. #include "user_rcc_config.h"
    16. #include "user_uart.h"
    17. #include "user_rtc.h"
    18. /* Typedef 类型----------------------------------------------------------------*/
    19. /* Define 定义----------------------------------------------------------------*/
    20. /* Macro 宏------------------------------------------------------------------*/
    21. /* Variables 变量--------------------------------------------------------------*/
    22. //最多一次接收200个字节
    23. uint8_t USART_RX_BUF[200];
    24. //接收状态
    25. //bit15, 接收完成标志
    26. //bit14, 接收到0x0d
    27. //bit13~0, 接收到的有效字节数目
    28. uint16_t USART_RX_STA=0; //接收状态标记
    29. /* Constants 常量--------------------------------------------------------------*/
    30. /* Function 函数--------------------------------------------------------------*/
    31. int main(void)
    32. {
    33. /*配置系统中断分组为2位抢占2位响应*/
    34. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    35. /*延时函数初始化*/
    36. delay_init();
    37. /*RCC配置*/
    38. Rcc_config();
    39. /*GPIO初始化*/
    40. Gpio_Init();
    41. /*USART1初始化*/
    42. Uart1_Init(9600);
    43. /*初始化RTC*/
    44. if(Rtc_Init())
    45. {
    46. printf("初始化Rtc失败\r\n");
    47. }
    48. /*死循环*/
    49. while(1){
    50. }
    51. }
    52. /************************************************************** END OF FILE ****/

     

  • 相关阅读:
    VBA技术资料MF84:判断文件夹是否存在并创建
    mybatis初体验(细节满满)
    TensorFlow?PyTorch?Paddle?AI工具库生态之争:ONNX一统天下 ⛵
    互联网上的音频和视频服务
    lambda表达式【C++】
    React 函数式组件和类式组件区别
    为chrome浏览器单独设置代理服务器
    通过Python脚本+Jekins实现项目重启
    Semantic Kernel Java SDK,为Java应用程序提供AI功能集成
    Solidity智能合约开发 — 3.5-库合约
  • 原文地址:https://blog.csdn.net/Yuanghxb/article/details/128193775