> 文章列表 > 【WCH】STM32F103转CH32F203工程驱动DS1302案例

【WCH】STM32F103转CH32F203工程驱动DS1302案例

【WCH】STM32F103转CH32F203工程驱动DS1302案例

【WCH】STM32F103转CH32F203工程驱动DS1302案例


  • 📌相关篇《STM32基于标准库工程驱动DS1302》
  • 📍《关于CH32F203程序下载方式说明》
  • 🎈有关CH32F203资料手册以及SDK资料:https://www.wch.cn/products/CH32F103.html
  • 📌《【WCH】基于STM32F1标准库程序烧录到CH32F203中运行方法》
  • ✨本文仅对驱动DS1302内容案例进行移植说明,有关STM32F103转CH32F203工程请查看上面的相关篇内容。
  • 🔖本移植工程资源也在相关篇中有所提供。
  • ⚡从STM32F103工程移植到CH32F203时钟频率在system_stm32f10x.c文件中新增了CH32的96MHz的相关时钟配置参数。

【WCH】STM32F103转CH32F203工程驱动DS1302案例

  • 🔧 96MHz频率配置的相关代码
#elif defined SYSCLK_FREQ_96MHz/********************************************************************** @fn      SetSysClockTo96_HSE** @brief   Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.** @return  none*/
static void SetSysClockTo96(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;}while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}if(HSEStatus == (uint32_t)0x01){/* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;/*  CH32F20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz)*  CH32F20x_D8-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz)*  CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz(HSE=32Mhz)*/
//        RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE |
//                                    RCC_PLLMULL ) );
//        RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12 );/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE | RCC_CFGR_PLLMULL12);/* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;/* Wait till PLL is used as system clock source */while((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{/** If HSE fails to start-up, the application will have wrong clock* configuration. User can add here some code to deal with this error*/}
}
  • 🌴将原来STM32f103型号的项目,切换为CH32F203型号的即可。
    【WCH】STM32F103转CH32F203工程驱动DS1302案例

  • 🛠烧录配置
    【WCH】STM32F103转CH32F203工程驱动DS1302案例

  • 📜工程程序烧录到CH32F203后串口打印数据信息:
    【WCH】STM32F103转CH32F203工程驱动DS1302案例

📝main主程序代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "DS1302.h"int main(void)
{DS1302_Time_t time = {0};const char *WEEK[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };delay_init();            //延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);   //串口初始化为115200DS1302_Init();   //DS1302引脚初始化
//		DS1302_WriteTime();//用于设置时间到DS1302中时,启用。while (1){DS1302_GetTime(&time);printf("Current Time: %02d-%02d-%02d %02d:%02d:%02d T:%s\\r\\n", time.year, time.month, time.day, time.hour, time.minute, time.second,WEEK[time.week-1]);delay_ms(2000);delay_ms(2000);}
}

DS1302驱动代码

  • 🔖驱动代码依旧是原来使用STM32的代码,没有做任何修改。
  • 🌿DS1302.c文件
#include "DS1302.h"
#include "delay.h"
#include "usart.h"
/*
DS1302接口:GPIOA_5 ->DS1302_RSTGPIOA_6 ->DS1302_DATGPIOA_7 ->DS1302_CLK
*/
//struct TIMEData TimeData;
//DS1302地址定义
#define DS1302_SEC_ADDR           0x80		//秒数据地址
#define DS1302_MIN_ADDR           0x82		//分数据地址
#define DS1302_HOUR_ADDR          0x84		//时数据地址
#define DS1302_DAY_ADDR           0x86		//日数据地址
#define DS1302_MONTH_ADDR         0x88		//月数据地址
#define DS1302_WEEK_ADDR          0x8a		//星期数据地址
#define DS1302_YEAR_ADDR          0x8c		//年数据地址
#define DS1302_CONTROL_ADDR       0x8e		//控制数据地址
#define DS1302_CHARGER_ADDR       0x90 		//充电功能地址			 
#define DS1302_CLKBURST_ADDR      0xbe//初始时间定义
static u8 time_buf[8] = {0x20,0x23,0x04,0x14,0x11,0x22,0x10,0x06};//初始时间2023年4月14号11点22分10秒 星期五
u8 sec_buf=0;  //秒缓存
u8 sec_flag=0; //秒标志位//DS1302初始化函数
void DS1302_Init() 
{/*1.GPIOC时钟*/RCC->APB2ENR |= 1<<2;/*2. 配置GPIOA_5/6/7模式*/GPIOA->CRL &= 0X000FFFFF;//先将 GPIOA 口的 CRL 寄存器的低 20 位清零,这样可以确保只修改 CRL 的高 12 位,不影响其他位。GPIOA->CRL |= 0X33300000;//将 GPIOA 口的前六个引脚(0~5)的模式和速率配置为推挽输出模式,最大输出速率50MHzGPIOA->ODR |=1<<6;//PA6输出高电平
}
//向DS1302写入一字节数据
void DS1302_WriteByte(u8 addr,u8 data) 
{u8 i;DS1302_RST=0; //禁止数据传输 !!!这条很重要DS1302_CLK=0; //确保写数据前SCLK为低电平DS1302_RST=1;	//启动DS1302总线	DS1302_OutPut_Mode();addr=addr&0xFE;  //最低位置零,寄存器0位为0时写,为1时读for(i=0;i<8;i++) //写入目标地址:addr{if (addr&0x01) DS1302_OUT=1;else DS1302_OUT=0;DS1302_CLK=1; //时钟上升沿写入数据DS1302_CLK=0;addr=addr>>1;}	for (i=0;i<8;i++) //写入数据:data{if(data&0x01) DS1302_OUT=1;else DS1302_OUT=0;DS1302_CLK=1;    //时钟上升沿写入数据DS1302_CLK=0;data = data >> 1;}DS1302_CLK=1;    // 将时钟电平置于高电平状态 ,处于已知状态DS1302_RST=0;	//停止DS1302总线
}//从DS1302读出一字节数据
u8 DS1302_ReadByte(u8 addr) 
{u8 i,temp;	DS1302_RST=0; //这条很重要DS1302_CLK=0; //先将SCLK置低电平,确保写数居前SCLK被拉低DS1302_RST=1; //启动DS1302总线DS1302_OutPut_Mode();//写入目标地址:addraddr=addr|0x01; //最低位置高,寄存器0位为0时写,为1时读for(i=0;i<8;i++) {if (addr&0x01) DS1302_OUT=1;else DS1302_OUT=0;DS1302_CLK=1; //写数据DS1302_CLK=0;addr = addr >> 1;}	//从DS1302读出数据:tempDS1302_InPut_Mode();for(i=0;i<8;i++){temp=temp>>1;if (DS1302_IN) temp|=0x80;else temp&=0x7F;DS1302_CLK=1;DS1302_CLK=0;}	DS1302_CLK=1;  //将时钟电平置于已知状态DS1302_RST=0;	//停止DS1302总线return temp;
}
//向DS1302写入时钟数据,用于时间校准修改
void DS1302_WriteTime() 
{DS1302_WriteByte(DS1302_CONTROL_ADDR,0x00);       //关闭写保护 DS1302_WriteByte(DS1302_SEC_ADDR,0x80);           //暂停时钟 //DS1302_WriteByte(DS1302_CHARGER_ADDR,0xa9);     //涓流充电 DS1302_WriteByte(DS1302_YEAR_ADDR,time_buf[1]);   //年 DS1302_WriteByte(DS1302_MONTH_ADDR,time_buf[2]);  //月 DS1302_WriteByte(DS1302_DAY_ADDR,time_buf[3]);    //日 DS1302_WriteByte(DS1302_HOUR_ADDR,time_buf[4]);   //时 DS1302_WriteByte(DS1302_MIN_ADDR,time_buf[5]);    //分DS1302_WriteByte(DS1302_SEC_ADDR,time_buf[6]);    //秒DS1302_WriteByte(DS1302_WEEK_ADDR,time_buf[7]);	  //周 DS1302_WriteByte(DS1302_CHARGER_ADDR,0xA5);//打开充电功能 选择2K电阻充电方式DS1302_WriteByte(DS1302_CONTROL_ADDR,0x80);//打开写保护     
}
//从DS1302读出时钟数据
void DS1302_ReadTime(void)  
{time_buf[1]=DS1302_ReadByte(DS1302_YEAR_ADDR);          //年 time_buf[2]=DS1302_ReadByte(DS1302_MONTH_ADDR);         //月 time_buf[3]=DS1302_ReadByte(DS1302_DAY_ADDR);           //日 time_buf[4]=DS1302_ReadByte(DS1302_HOUR_ADDR);          //时 time_buf[5]=DS1302_ReadByte(DS1302_MIN_ADDR);           //分 time_buf[6]=(DS1302_ReadByte(DS1302_SEC_ADDR))&0x7f;    //秒,屏蔽秒的第7位,避免超出59time_buf[7]=DS1302_ReadByte(DS1302_WEEK_ADDR);          //周 	
}//主函数
void DS1302_GetTime(DS1302_Time_t* time)
{ DS1302_ReadTime(); //读取时间time->year=(time_buf[0]>>4)*1000+(time_buf[0]&0x0F)*100+(time_buf[1]>>4)*10+(time_buf[1]&0x0F); //计算年份time->month=(time_buf[2]>>4)*10+(time_buf[2]&0x0F);  //计算月份time->day=(time_buf[3]>>4)*10+(time_buf[3]&0x0F);    //计算日期time->hour=(time_buf[4]>>4)*10+(time_buf[4]&0x0F);   //计算小时time->minute=(time_buf[5]>>4)*10+(time_buf[5]&0x0F); //计算分钟time->second=(time_buf[6]>>4)*10+(time_buf[6]&0x0F); //计算秒钟time->week=(time_buf[7]&0x0F);                       //计算星期}
  • 🌿DS1302.h文件
#ifndef _DS1302_H
#define _DS1302_H#include "stm32f10x.h"
#include "sys.h"//DS1302引脚定义,可根据实际情况自行修改端口定义
#define DS1302_OutPut_Mode() {GPIOA->CRL &= 0xF0FFFFFF;GPIOA->CRL |= 0x03000000;}//将 GPIOA 口的 PA6 引脚设置成推挽输出模式,并清空了其他引脚的配置
#define DS1302_InPut_Mode()  {GPIOA->CRL &= 0xF0FFFFFF;GPIOA->CRL |= 0x08000000;}//PA7 引脚既可以作为普通的 GPIO 输出口#define DS1302_IN  PAin(6)
#define DS1302_OUT PAout(6)
#define DS1302_RST PAout(5)
#define DS1302_CLK PAout(7)typedef struct TIMEData
{u16 year;u8  month;u8  day;u8  hour;u8  minute;u8  second;u8  week;
}DS1302_Time_t;void DS1302_Init(void);
void DS1302_WriteByte(u8 addr,u8 data);
u8   DS1302_ReadByte(u8 addr);
void DS1302_WriteTime(void);
void DS1302_ReadTime(void);
void DS1302_GetTime(DS1302_Time_t* time);#endif

📚工程源码

链接: https://pan.baidu.com/s/1L0e0rf7s2u5L-7_DF1bwsw
提取码: pden