新人报到!
刚刚接触STM32,最近在做一个测量PWM方波的频率计(测量范围:1HZ~10MHZ,精度要求在0.1%),为了达到精度要求,在低频段(1HZ~1000HZ)用了输入捕获,测量在两个上升沿之间的时间;在高频段(1000HZ~10MHZ)用外部中断计数(方波上升沿触发外部中断)。要求测量结果在TFT-LCD上显示5位有效数字,低频部分以HZ为单位,高频部分以KHZ为单位。实现思想是:同时进行外部中断测量和输入捕获过程,定时器定时1s,在1s内测量外部中断的次数,如果外部中断的次数>1000,则显示外部中断的测量结果。如果外部中断的次数<1000,则用输入捕获测量的结果显示。下面是我的程序:现在遇到了一个问题,外部中断和输入捕获的中断均进不去,只有定时器溢出的中断能进去。
外部中断和输入捕获的中断处理程序中的printf都没有输出,请各位帮忙看看问题出在哪?谢谢各位!
主程序:
int main(void) {
//u16 led0pwmval=0;
//u8 dir=1;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72);//延时函数初始化
uart_init(72,9600);
LCD_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,"FRE-COUNTER");
LCD_ShowString(20,130,"FRE:");
LCD_ShowString(60,90,"ATOM@ALIENTEK");
PWM_Init(9,71); //不分频。PWM频率=72000Khz/(10*72)=0.1Mhz
Capture_Init(60000,2399);//分频,30Khz的计数频率,捕获频率=72000KHZ/(60000*2400)=0.5HZ
EXTIX_Init(); //外部中断初始化
Timerx_Init(10000,7199);//10Khz的计数频率,计数到10000为1s
//高频(1000HZ~10Mhz),用外部中断计数,以KHZ为单位
if(flag==1)
{
if((flow>=1000)&&(flow<9999))//1000HZ~9999HZ
{
//浮点数显示
temp=(float)flow*(1.0/1000);//以KHZ为单位的浮点数
temp0=temp;//temp0保存原浮点数的值
temp1=temp0;//temp1保存浮点数的整数部分
LCD_ShowNum(100,130,temp1,1,16);
temp-=(u16)temp;//减掉整数部分
LCD_ShowString(120,130,".");//显示小数点
LCD_ShowNum(140,130,temp*1000,4,16);//显示小数部分
LCD_ShowString(220,130,"KHZ");
}
else if((flow>=10000)&&(flow<100000))//10000HZ~99999HZ
{
//浮点数显示
。。。。。
}
else if((flow>=100000)&&(flow<1000000))//100000HZ~999999HZ
{
//浮点数显示
。。。。。
}
else//1M~10M的频率
{
//浮点数显示
。。。。。
}
}
else//flag=0,低频用输入捕获,1HZ~1000HZ
{
if((cnt>30)&&(cnt<=300))//100HZ~999HZ
{
//浮点数显示
。。。。。
}
else if((cnt>300)&&(cnt<=3000))//10HZ~99HZ
{
//浮点数显示
。。。。。
}
else//1HZ~9HZ
{
//浮点数显示
。。。。。
}
}
while(1)
{
delay_ms(100);
}
}
外部中断子程序:
void EXTI0_IRQHandler(void)
{
COUNT++;
LED1=0;
EXTI->  R=1<<0; //清除LINE0上的中断标志位
printf("COUNT = %d\r\n",COUNT);
}
//外部中断初始化程序
//初始化PA0为中断输入.
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD
GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
GPIOA->CRL|=0X00000008;
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
MY_NVIC_Init(1,1,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2
}
输入捕获子程序:
//定时器2通道1输入捕获配置
//arr:自动重装值
//psc:时钟预分频数
void Capture_Init(u16 arr,u16 psc)
{
//此部分需手动修改 IO口设置
RCC->APB2ENR|=1<<0; //辅助功能IO时钟开启
RCC->APB1ENR|=1<<0; //TIM2 时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
TIM2->ARR=arr; //设定计数器自动重装值,刚好1ms
TIM2->  SC=psc; //预分频器
GPIOA->CRL&=0XFFFFFFF0;//PA0 输出
GPIOA->CRL|=0X00000004;//复用功能输出
GPIOA->ODR|=1<<0;//PA0 上拉
TIM2->SMCR|=0x00D4;
TIM2->CCMR1|=1<<0;//CC1S=01 选择输入端
TIM2->CCMR1|=3<<4; //IC1F=0011配置输入滤波器
TIM2->CCER|=0<<1; //CC1P=0 选择有交转换边沿
TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频
TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中
TIM2->DIER|=1<<1; //允许更新捕获中断
TIM2->CR1|=0x01; //使能定时器2
MY_NVIC_Init(1,2,TIM2_IRQChannel,2);//抢占1,子优先级3,组2
}
//定时器2中断服务程序
void TIM2_IRQHandler(void)
{
cnt = TIM2->CCR1;//读取CCR1也可以清CC1IF标志位//clk为在两个上升沿之间的计数器计数个数
cnt0=(float)cnt*(1.0/1);//将clk个数转化为浮点数
cntf=30000.0/cnt0;//求出低频频率,浮点数
printf("CNT = %d\r\n",cnt);
TIM2->SR&=~(1<<1);//清除中断标志位
}
|