在完成OLED屏显示驱动的情况下,结合RTC的计时功能即可完成电子时钟的制作。
为实现计时值的显示,为其配置的数值显示函数为:
void OLED_ShowNum(uint8_t x,uint8_ty,uint32_t num,uint8_t len,uint8_t size2)
{
uint8_t t,temp;
uint8_t enshow=0;
for(t=0;t<len;t++){
temp=(num/oled_pow(16,len-t-1))%16;
if(enshow==0&&t<(len-1)){
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,'',size2);
continue;
}
else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
实现电子时钟功能的主程序为:
int32_t main(void)
{
RTC_InitTypeDef RTC_InitStruct;
RTC_TimeTypeDef RTC_TimeStruct;
RTC_AlarmTypeDef RTC_AlarmStruct;
RCC_Configuration();
LogInit();
RCC_HSE_FLT_CLOSE);
RCC_LSE_Enable(RCC_LSE_MODE_OSC, RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL);
RTC_InitStruct.DateStruct.Day= 0x21;
RTC_InitStruct.DateStruct.Month= RTC_Month_June;
RTC_InitStruct.DateStruct.Week= RTC_Weekday_Monday;
RTC_InitStruct.DateStruct.Year= 0x21;
RTC_InitStruct.TimeStruct.Hour= 0x2;
RTC_InitStruct.TimeStruct.Minute= 0x58;
RTC_InitStruct.TimeStruct.Second= 0x59;
RTC_InitStruct.TimeStruct.AMPM = 1;
RTC_InitStruct.TimeStruct.H24 = 0;
RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSE;
RTC_Init(&RTC_InitStruct);
RTC_AlarmStruct.RTC_AlarmMask= RTC_AlarmMask_WeekMON | RTC_AlarmMask_WeekTUE |
RTC_AlarmMask_WeekWED | RTC_AlarmMask_WeekTHU |RTC_AlarmMask_WeekFRI;RTC_AlarmStruct.RTC_AlarmTime.Hour= 6;
RTC_AlarmStruct.RTC_AlarmTime.Minute= 0x45;
RTC_AlarmStruct.RTC_AlarmTime.Second= 0;RTC_SetAlarm(RTC_Alarm_A,&RTC_AlarmStruct);
RTC_AlarmCmd(RTC_Alarm_A,ENABLE); RTC_ITConfig(RTC_IT_ALARMA| RTC_IT_INTERVAL, ENABLE);
OLED_gpio();
OLED_Init();
OLED_Clear();
OLED_ShowString(40,0,"CW32F030",16);
OLED_ShowString(28,3," : :",16);
while(1)
{
RTC_GetTime(&RTC_TimeStruct);
OLED_ShowNum(28,3,RTC_TimeStruct.Hour,2,16);
OLED_ShowNum(52,3,RTC_TimeStruct.Minute,2,16);
OLED_ShowNum(80,3,RTC_TimeStruct.Second,2,16);
delay(500);
}
}
经程序的编译与下载,其显示效果如图1所示。
图1 电子时钟
为便于测试ADC数据采集功能,在开发板上配置电位器来输出共测试用的模拟电压,其电路如图2所示。
图2 信号模拟
ADC数据采集的端口初始化函数为:
void ADC_PortInit(void)
{
REGBITS_SET( CW_SYSCTRL->AHBEN, YSCTRL_AHBEN_GPIOA_Msk );
REGBITS_SET( CW_SYSCTRL->APBEN2, YSCTRL_APBEN2_ADC_Msk );
//set PA01 as AIN1 INPUT
PA01_ANALOG_ENABLE();
}
BTIM初始化函数为:
void BTIM_init(void)
{
BTIM_TimeBaseInitTypeDefBTIM_InitStruct;
__RCC_BTIM_CLK_ENABLE();
__disable_irq();
NVIC_EnableIRQ(BTIM1_IRQn);
__enable_irq();
BTIM_InitStruct.BTIM_Mode= BTIM_Mode_TIMER;
BTIM_InitStruct.BTIM_OPMode =BTIM_OPMode_Repetitive;
BTIM_InitStruct.BTIM_Period = 8000;
BTIM_InitStruct.BTIM_Prescaler =BTIM_PRS_DIV8;
BTIM_TimeBaseInit(CW_BTIM1,&BTIM_InitStruct);
BTIM_ITConfig(CW_BTIM1,BTIM_IT_OV, ENABLE);
BTIM_Cmd(CW_BTIM1, ENABLE);
}
BTIM中断处理函数为:
void BTIM1_IRQHandler(void)
{
static unsigned int count2=0;
if(BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
{
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV);
count2++;
timecount++;
if(count2>500)
{
count2=0;
PB00_TOG();
}
}
}
RCC时钟配置函数为:
void RCC_Configuration(void)
{
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, 8);
__RCC_FLASH_CLK_ENABLE();
RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL);
RCC_SystemCoreClockUpdate(64000000);
}
进行ADC数据采集的配置处理函数为:
void ADC_Configuration(void)
{
ADC_SingleChTypeDef ADC_SingleInitStruct;
__RCC_ADC_CLK_ENABLE();
__RCC_GPIOB_CLK_ENABLE();
PB00_ANALOG_ENABLE();
ADC_SingleInitStruct.ADC_Chmux = ADC_ExInputCH8;
ADC_SingleInitStruct.ADC_DiscardEn = ADC_DiscardNull;
ADC_SingleInitStruct.ADC_InitStruct.ADC_AccEn = DC_AccDisable;
ADC_SingleInitStruct.ADC_InitStruct.ADC_Align = DC_AlignRight;
ADC_SingleInitStruct.ADC_InitStruct.ADC_ClkDiv = DC_Clk_Div16;
ADC_SingleInitStruct.ADC_InitStruct.ADC_DMAEn = DC_DmaDisable;
ADC_SingleInitStruct.ADC_InitStruct.ADC_InBufEn = DC_BufEnable;
ADC_SingleInitStruct.ADC_InitStruct.ADC_OpMode =ADC_SingleChOneMode;
ADC_SingleInitStruct.ADC_InitStruct.ADC_SampleTime = ADC_SampTime5Clk;
ADC_SingleInitStruct.ADC_InitStruct.ADC_TsEn = DC_TsDisable;
ADC_SingleInitStruct.ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA;
ADC_SingleInitStruct.ADC_WdtStruct.ADC_WdtAll = DC_WdtDisable;
ADC_SingleChOneModeCfg(&ADC_SingleInitStruct);
ADC_Enable();ADC_SoftwareStartConvCmd(ENABLE);
}
实现数字电压检测的主程序为:
int main(void)
{
float temp;
unsigned int tempv,tempu;
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
OLED_gpio();
OLED_Init();
OLED_Clear();
OLED_ShowString(28,0,"CW32F030",16);
OLED_ShowCHinese(28,2,0);
OLED_ShowCHinese(48,2,1);
OLED_ShowCHinese(68,2,2);
OLED_ShowString(28,5,"U=. V",16);
ADC_Configuration();
BTIM_init();
while(1)
{
if(timecount>200)
{
timecount=0;
ADC_SoftwareStartConvCmd(ENABLE);
while(ADC_GetITStatus(ADC_IT_EOC))
{
ADC_ClearITPendingBit(ADC_IT_EOC);
adcvalue=ADC_GetConversionValue();
temp=(float)adcvalue*(3.3/40.96);
tempv=temp;
LED_ShowNum(44,5,tempv/100,1,16);
tempu=tempv%100;
OLED_ShowNum(60,5,tempu,2,16);
}
}
}
}
经程序的编译与下载,其显示效果如图3和图4所示。
图3 数据采集
图4 满量程
更多回帖