📄 测频.c
字号:
//测频.c : source file for the 测频 project
//
/**************************************************************************
板子:BWJL-A 060918
时间:2007年6月25-27日
输出:数码管显示
目的:测输入频率
输入:信号发生器信号
程序解释:1、关于fb:每个信号上升沿,fb都清零,只有在TIMER1计数溢出时才为1;
fb的值只有两种可能:是0或是1,程序中对其判断条件为2或是3,只是
为了程序正常运行放宽了条件,2或3没有理论意义;
2、关于19230:1/19230=52是频率大于等于52Hz时都要显示为52.00
3、关于TIMER1:此处设定为外部上升沿触发,8分频,每计一个数用时为
1/(8M/8)=0.000001s,计65536溢出,是3个周期多一点,当其溢出时,fb
为1,此时新数比旧数数值上小,
求数(周期)时要用:0xffff + number_int0_new - odd_dat来计算;
4、外部信号频率为50Hz,周期为20ms。
****************************************************************************/
#include "测频.h"
#include "测频Timer.h"
#include "测频ExtINT.h"
#define uchar unsigned char
#define uint unsigned int
/////////////////////////////////////////////////////////////////////////////
//测频
uchar led2[41]=
{0x60,0x7e,0x31,0x32,0x2e,0xa2,0xa0,0x7a,0x20,0x22,0x28,0xa4,0xe1,0x34,0xa1,0xa9,
0x40,0x5e,0x11,0x12,0x0e,0x82,0x80,0x5a,0x00,0x02,0x08,0x84,0xc1,0x14,0x81,0x89,
0xff,0xbf,0x64,0xdf,0xa1,0x68,0x34,0xf4,0xa5};
uchar led[24];
uchar fb;
uint /*number_int0_old,*/number_int0_new;//中断INT0口信号的新旧值
uint round_f;//系统周期
int f;//频率
static void io_init(void)
{
//{{WIZARD_MAP(General)
//}}WIZARD_MAP(General)
//{{WIZARD_MAP(I/O Ports)
// PortA
PORTA = 0x0;
DDRA = 0xf8;
// PortB
PORTB = 0x0;
DDRB = 0x1f;
// PortC
PORTC = 0x3c;
DDRC = 0xc3;
// PortD
PORTD = 0x0;
DDRD = 0x0;
//}}WIZARD_MAP(I/O Ports)
//{{WIZARD_MAP(Watchdog)
// Watchdog Enabled, Prescaler: OSC/16k
wdt_enable(WDTO_15MS);
//}}WIZARD_MAP(Watchdog)
//{{WIZARD_MAP(Analog Comparator)
// Analog Comparator Disabled
ACSR = 0x80;
//}}WIZARD_MAP(Analog Comparator)
}
int main(void)
{
//{{WIZARD_MAP(Initialization)
io_init();
extint_init();
timers_init();
//}}WIZARD_MAP(Initialization)
// TODO: Add extra initialization here
//{{WIZARD_MAP(Global interrupt)
sei();
//}}WIZARD_MAP(Global interrupt)
clear_led();
while(1)
{
// TODO: Add your code here
lcd_f();
led_list();led_list();led_list();led_list();led_list();led_list();
led_list();led_list();led_list();led_list();led_list();led_list();
}
}
/**********************************************
频率获取程序
**********************************************/
uint get_f(void)
{
double d=0;
static double dat1,dat2,dat3,dat_new,mid1,mid2,mid3;
if(round_f>0 && fb < 2)//fb的值只有两种可能:是0或是1,此处对其判断为2,只是为了放宽了条件,2没有理论意义
{
// if(round_f<19230) round_f = 19230;
dat_new=round_f;
dat1=dat2; dat2=dat3; dat3=dat_new;
mid1=mid2;mid2=mid3;
if(((dat1<dat2)&&(dat1>dat3))||((dat1<dat3)&&(dat1>dat2)))
mid3=dat1;
else if(((dat2<dat1)&&(dat2>dat3))||((dat2<dat3)&&(dat2>dat1)))
mid3=dat2;
else mid3=dat3;
d=(1.0*mid1+2.0*mid2+3.0*mid3)/6.0;
d=200000000/d;//单位转换,周期转换为频率,并扩大100倍,故有(10-6)*100=1000000 000
}
else d = 0;
return (uint)d;
}
/****************************************************
频率显示程序
****************************************************/
void lcd_f(void)
{
uint t;
f=get_f();
led[23]=(f/1000)%10;
led[22]=(f/100)%10+16;
led[21]=(f/10)%10;
led[20]=f%10;
t=round_f;
led[19]=(t/10000)%10;
led[18]=(t/1000)%10;
led[17]=(t/100)%10;
led[16]=(t/10)%10;
}
/**********************************************
数码管显示程序
RCK=PA5 SCK=PA6 SER=PA7
***********************************************/
void led_outbyt(char a)
{
char i,d;
for(i=0;i<8;i++)
{
cbi(PORTA,6);
d=a&0x80;
if(d)
sbi(PORTA,7);
else
cbi(PORTA,7);
a<<=1;
sbi(PORTA,6);
}
}
void led_list(void)
{
uchar i,j;
j=1;
for(i=0;i<8;i++)
{
led_outbyt(led2[led[i]]);
led_outbyt(j);
led_outbyt(led2[led[i+8]]);
led_outbyt(j);
led_outbyt(led2[led[i+16]]);
led_outbyt(j);
cbi(PORTA,5); //数据锁存
sbi(PORTA,5); //数据锁存
delay(8,1000);
j<<=1;
led_outbyt(0);led_outbyt(0);led_outbyt(0);led_outbyt(0);led_outbyt(0);led_outbyt(0);
cbi(PORTA,5); //数据锁存
sbi(PORTA,5); //数据锁存
delay(1,1000);
}
}
void clear_led(void)
{
uchar mi;
for(mi=0;mi<24;mi++)
{
led[mi]=32;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -