【下面的代码仅给出了实现本功能必要的部分】
其中的OLED函数部分为OLED自带的库函数
本单片机上的SMCLK 设置为了 24MHz
#define TIMER_PERIOD 2400
#define DUTY_CYCLE 1200
//while(1) 前的初始化
void Frequence_Duty_init()
{
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2);
//选用P1.2 使用TA0.1 Timer Capture
Timer_A_initContinuousModeParam Counter = {0};
Counter.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
Counter.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
Counter.startTimer = true;
Counter.timerClear = TIMER_A_DO_CLEAR;
Counter.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
Timer_A_initContinuousMode(TIMER_A0_BASE, &Counter);
//开启一个连续模式的计时
Timer_A_initCaptureModeParam CaptureParam = {0};
CaptureParam.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
CaptureParam.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
CaptureParam.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
CaptureParam.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
CaptureParam.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
CaptureParam.captureOutputMode = TIMER_A_OUTPUTMODE_TOGGLE;
Timer_A_initCaptureMode(TIMER_A0_BASE,&CaptureParam);
//开启捕获模式,并开启它的中断
}
//将此函数放到 while(1) 里面
void Frequence_Duty_Display()
{
if(FreqFlag == 0)
{
if(D2 > D1)
{
HighClockSteps=(HighOverFlow-1) * 65536 + D2 - D1;
}else
{
HighClockSteps=(HighOverFlow-1) * 65536 + D2 + 65536 - D1;
}
if(D3 > D1)
{
AllClockSteps=(AllOverFlow-1)*65536 + D3 - D1;
}else
{
AllClockSteps=(AllOverFlow-1)*65536 + D3 + 65536 - D1;
}
//占空比
Duty = HighClockSteps*100.0/AllClockSteps;
Point1 = Duty - (int)Duty;
OLED_ShowNum(0,2,Duty,3,16);
OLED_ShowString(25,2,".");
OLED_ShowNum(30,2,Point1*100,2,16);
//频率
Frequency = 24000000.0/AllClockSteps; //根据自己的单片机主频修改
Point2 = Frequency - (int)Frequency;
OLED_ShowNum(0,6,Frequency,5,16);
OLED_ShowString(40,6,".");
OLED_ShowNum(45,6,Point2*100,2,16);
}
}
//此代码块加在 main.c 末尾
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
Timer_A_disableCaptureCompareInterrupt (TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);
if(FreqFlag == 1)
{
static u8 index;
if(TA0CCTL1&CM0&&(index==0))
{
TA0CCTL1|=CM_2;//更变为下降沿触发
D1=TA0R;//记录初始时间
D2=D3=0;
HighOverFlow = AllOverFlow = 0;
index=(index+1)%3;
}
else if((TA0CCTL1&CM1)&&(index==1))//下降沿
{
TA0CCTL1|=CM_1;//更改设置为上升沿触发
D2 = TA0R; //记录高电平结束时间
HighOverFlow = AllOverFlow;
index=(index+1)%3;
}
else if((TA0CCTL1&CM0)&&(index==2)) //第二次上升沿
{
//测完一个周期,等待下一个上升沿
D3 = TA0R;
FreqFlag = 0;
index=(index+1)%3;
}
}
AllOverFlow++;
Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);
}
实测效果图