应该用unsigned int型,已通知修改手册。
unsigned int 应该也不行吧,前一次捕获值和后一次捕获值相减可能为负数,unsigned int会溢出 Crystalline 发表于 2025-1-11 10:31
unsigned int 应该也不行吧,前一次捕获值和后一次捕获值相减可能为负数,unsigned int会溢出 ...
不会的,使用u16的类型,16位无符号相减,只计算差值,没有负数的。 梁工 发表于 2025-1-11 11:41
不会的,使用u16的类型,16位无符号相减,只计算差值,没有负数的。
{:huaixiao:}哦哦对的对的 #include <STC8H.H>
#include <Seg.h>
#include <String.h>
uchar Seg_Buf[] = {10,10,10};
uchar pos = 0;
uint Seg_Slow_Down = 0;
uint Time_1000ms = 0;
uint Freq = 0;
uchar Time1ms = 0;
uchar count_100ms;
bit is_in_interrupt;
uchar led_light = 2;
float sum;
uchar i;
#define FILTER_SIZE 30
#define SYS_CLK 1000.0
int filter_buffer;// 存储最新的30个频率值
int filter_index = 0; // 用于指示当前存储位置
float filtered_freq = 0; // 存储滤波后的频率值
typedef struct {
long cap;
long cap_new;
long cap_old;
}Freq_Type;
Freq_Type Freq1;
Freq_Type Freq2;
Freq_Type Freq3;
long Old;
void Timer1_Isr(void) interrupt 3
{
if(++Seg_Slow_Down == 5000) {Seg_Slow_Down = 0; }
if(++Time1ms == 10){
Time1ms = 0;
if(++pos ==3) pos = 0;
}
if(Time1ms <= led_light)//亮
{
Seg_Disp(pos,Seg_Buf);
}
else
Seg_Disp(pos,10);//灭
}
void Timer1_Init(void) //100微秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9C; //设置定时初始值
TH1 = 0xFF; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
}
void System_Init()
{
P_SW2 |= 0x80; //扩展外部XFR
PWMB_PS = 0x54; //01 01 01 00 选用P54\P33\P34作为输入捕获引脚
PWMB_PSCRH = 0x2E; //预分频寄存器1000分频
PWMB_PSCRL = 0xDF;
/*必须先关闭CCER才能设置CC1*/
PWMB_CCER1 = 0x00;PWMB_CCER2 = 0x00 ;
PWMB_CCMR2 = 0x01;PWMB_CCMR3 = 0x01; PWMB_CCMR4 = 0x01; //通道6、7、8设为输入
//PWMB_CCMR2 |= 0xC0; PWMB_CCMR3 |= 0xC0; PWMB_CCMR4 |= 0xC0;//8个事件触发一次
PWMB_CCER1 = 0x10; PWMB_CCER2 = 0x11; //使能通道6、7、8
PWMB_IER = 0x1C;
PWMB_CR1 |= 0x01; //使能计数器
IP |= 0x0f; //拉低定时器1的优先级
P1M0 = 0xff; P1M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x10;
P3M0 = 0xe0; P3M1 = 0x18;
Timer1_Init();
EA = 1;
}
void Seg_Proc()
{
sum = 0;
i = 0;
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
for(i = 0;i<FILTER_SIZE;i++)
sum += filter_buffer;
if(Freq1.cap_old != Freq1.cap_new){
filtered_freq = sum / FILTER_SIZE;
filtered_freq = SYS_CLK / filtered_freq;
}
else
filtered_freq = 0;
//Freq = Freq1.cap + Freq2.cap + Freq3.cap;
// if(Freq <= 999){
// Seg_Buf = (Freq/100)?Freq/100:10;
// Seg_Buf = (Freq/10)?Freq/10%10:10;
// Seg_Buf = Freq%10;
// }
// else
// Seg_Buf = Seg_Buf = Seg_Buf = 9;
Seg_Buf = ((uint)(filtered_freq/100))?(uint)(filtered_freq/100):10;
Seg_Buf = ((uint)(filtered_freq/10))?(uint)(filtered_freq/10)%10:10;
Seg_Buf = (uint)filtered_freq%10;
}
void main()
{
System_Init();
while(1)
{
Seg_Proc();
}
}
void PWMB_ISR() interrupt 27
{
if(PWMB_SR1 & 0x04) //是CC6的中断
{
Freq1.cap_old = Freq1.cap_new;
Freq1.cap_new = PWMB_CCR6;
Freq1.cap = Freq1.cap_new - Freq1.cap_old;
filter_buffer = (Freq1.cap >= 0) ? Freq1.cap : -Freq1.cap;
filter_index = (filter_index + 1) % FILTER_SIZE;
PWMB_SR1 &= ~0x04;
}
// if(PWMB_SR1 & 0x08) //是CC7的中断
// {
// Freq2.cap_old = Freq2.cap_new;
// Freq2.cap_new = PWMB_CCR7;
// Freq2.cap = Freq2.cap_new - Freq2.cap_old;
// PWMB_SR1 &= ~0x08;
// }
// if(PWMB_SR1 & 0x10) //是CC8的中断
// {
// Freq3.cap_old = Freq3.cap_new;
// Freq3.cap_new = PWMB_CCR8;
// Freq3.cap = Freq3.cap_new - Freq3.cap_old;
// PWMB_SR1 &= ~0x10;
// }
}我现在有个问题就是他没有频率输入以后,还会保持之前的频率值,这个问题怎么解决
Crystalline 发表于 2025-1-11 19:59
我现在有个问题就是他没有频率输入以后,还会保持之前的频率值,这个问题怎么解决
...
采样窗口时间(超时),即超过一定时间没有脉冲就要归0. 你这部分计算的代码最好别放在中断里运行,会占用太多资源
页:
1
[2]