现在需要做一个单片机的计数器。有大神愿意教的没

不需要多复杂的功能,只要能计数就行了。有大神愿意有耐心教的,这里面100积分,待会儿可以再给100

这个比较简单,但我没现成的,不知你用什么语言编程,用什么单片机?我对51比较熟,正在学AVR,就是用其内部的定时器/计数器,不让其中断,不断读取其数值并显示即可 我有一频率计程序,有简单注释,若能看懂,做计数器更容易
//用定时计数器0作为脉冲计数器,定时器1作为定时器用,定时50ms产生中断
//中断10次后(即0.5s)读计数器0的数据乘2即为所得频率值,适于频率变化较慢的场所
//先进行50ms预判断,若TH0计数值大于12,说明1S内计数值将超过65535(虽0.5S内远不超65535)
//变量ee是无符号整数不能超过65535,为防止出错,则报警
//最大可测频率约65535hz,实际上STC12C系列是1T单片机,11.0592下其最高可计数频率远大于此
#include <reg52.h>
#define unit unsigned int
#define uchar unsigned char
//定义以I/O口的功能
sbit beiguang=P3^2;//液晶屏背光
sbit rs=P1^3;//液晶屏写选择,0命令 1数据
sbit rw=P1^4;//液晶屏读写选择
sbit lcden=P1^5;//液晶屏使能
sbit fm=P1^7;//蜂鸣器
#define db P2 //定义P2为数据输出口,写数据时用db代替P2,增加液晶屏程序的通用性
//更改硬件接线时,只更改此处,而不必去更改液晶屏读写子程序
uchar aa,bb,cc;
unit dd,ee;
void Delay1ms(unsigned int i) //1ms延时程序
{
unsigned int j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void init()//初始化设置
{
TMOD=0x15;//定时器0作为计数器,定时器1作为定时器用
TH0=0;//计数器清0
TL0=0;
EA=1;//开总中断
ET1=1;//允许定时器1中断
TH1=0x4c;
TL1=0x5c;
TR0=1;//启动计数器
TR1=1;//启动定时器
aa=0;
}
void write_com(uchar com)//向液晶屏写命令
{
db=com;
rs=0;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void write_date(uchar date)//向液晶屏写数据
{
db=date;
rs=1;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void init2()//液晶屏初始化
{
beiguang=0;
rw=0;
write_com(0x38);
Delay1ms(10*12);
write_com(0x0f);
Delay1ms(10*12);
write_com(0x06);
Delay1ms(10*12);
write_com(0x01);
Delay1ms(10*12);
}
void display4(unsigned int number) //单行多位显示程序
{
uchar A1,A2,A3,A4,A5;
init2();//液晶屏初始化
A1=number/10000%10;//分离出十万,万,千,百,十,个
A2=number/1000%10;
A3=number/100%10;
A4=number/10%10;
A5=number%10;

write_com(0x80);//第1个数据的位置设定,第1行第1列
Delay1ms(10);
write_date(0x30+A1);//写数据
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);

write_com(0x87);//第6个数据'H'的位置,中间空85和86 二格
write_date('H');
Delay1ms(10);
write_date('z');
Delay1ms(10);
}
void main()//主程序很简单
{
init();//初始化
while(1)//循环程序
{
dd=bb*256+cc;//0.5S的计数值
ee=2*dd;//换算为1秒钟的计数值
if(aa==1)
{
if(TH0>12)//预判断,50ms内TH0>12,1s内计数值将超过可计数的最大值65535
fm=0;//报警
}
display4(ee);//显示
fm=1;//报警停止
}
}
void timer1()interrupt 3//注意:定时器1的中断序号为3
{
aa++;
TH1=0x4c;//11.0592Mhz
//TL1=0;//11.0592Mhz
TL1=0x5c;//实际电路振荡频率11.03705Mhz,对TL1修正
if(aa==10)//中断10次,共0.5S
{
TR0=0;//暂停计数
aa=0;
bb=TH0;//读出计数器数据
cc=TL0;
TL0=0;//计数器清0
TH0=0;
TR0=1;//重新启动
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-04-23
/********************************************************************************************

* 功 能:外部中断1低电平触发计数。
* 硬件条件:1.CPU型号:AT89S52
* 2.晶振:12.000MHz
* 3.短接BEEP_P1.3
* 4.短接KEY3_P3.3
* 5.短接LED11__P1.7
* 日 期:2014年04月23号

*********************************************************************************************/
#include "reg52.h" // 包含头文件

/* 与编译器无关的数据类型定义 */
/********************************************************************************************/
typedef unsigned char uint8; // 无符号8位整型变量
typedef signed char int8; // 有符号8位整型变量
typedef unsigned short uint16; // 无符号16位整型变量
typedef signed short int16; // 有符号16位整型变量
typedef unsigned int uint32; // 无符号32位整型变量
typedef signed int int32; // 有符号32位整型变量
typedef float fp32; // 单精度浮点数(32位长度)
typedef double fp64; // 双精度浮点数(64位长度)
/********************************************************************************************/

/* 定义位变量 */
sbit P1_3 = P1 ^ 3;
sbit P3_3 = P3 ^ 3;
sbit P1_7 = P1 ^ 7;

#define LED11_ON() (P1_7=0) // 定义"LED11_ON()"为AT89S52的P1.7脚输出低电平使LED11点亮
#define LED11_OFF() (P1_7=1) // 定义"LED11_OFF()"为AT89S52的P1.7脚输出高电平使LED11熄灭

#define BEEP_ON() (P1_3=0) // 定义"BEEP_ON()"为P1.3输出低电平,控制蜂鸣器蜂鸣
#define BEEP_OFF() (P1_3=1) // 定义"BEEP_OFF()"为P1.3输出高电平,控制蜂鸣器不蜂鸣

#define KEY3 P3_3 // 定义"KEY3"为P3.3接收外部输入的高低电平

uint16 j=0; // 定义"j"为计数变量初始值为0

/********************************************************************************************
* 函数名称:Delay()
* 功 能:软件延时
* 入口参数:count 延时参数,值越大,延时越长
* 出口参数:无
*********************************************************************************************/
void Delay(uint16 count)
{
uint8 i;

while(--count != 0)
{
for(i = 0; i < 125; i++); // ";" 表示空语句,CPU空转。
} // i 从0加到125,在12M晶体下CPU大概耗时1毫秒
}

/********************************************************************************************
* 函数名称:INT1_Server()
* 功 能:外部中断1的中断服务程序。蜂鸣器蜂鸣两次,LED11闪烁两次。
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void INT1_Server(void) interrupt 2
{
uint8 i;

EX1=0; // 外部中断1上的中断请求被禁止

/* 蜂鸣器蜂鸣两次,LED11闪烁两次 */
for(i=0;i<2;i++)
{
LED11_ON();
BEEP_ON();
Delay(100);
LED11_OFF();
BEEP_OFF();
Delay(100);
}

while(~KEY3); // 等待KEY3被用户释放
j++;

EX1=1; // 外部中断1上的中断请求被允许
}
/********************************************************************************************
* 函数名称:main()
* 功 能:外部中断1低电平触发实验。KEY3作为外部中断1的触发输入,当KEY3按下时,产生外部中断1,
* 在外部中断1的服务程序中,使蜂鸣器蜂鸣两次,LED11闪烁两次,计数值j加1。
*********************************************************************************************/
void main (void)
{
LED11_OFF(); // LED11熄灭
BEEP_OFF(); // 蜂鸣器不蜂鸣

IT1=0; // 外部中断1的中断触发方式为电平触发(即低电平引起中断)

/* 以下两行代码可替换为"IE=0x84" */
EA=1; // 所有中断源的中断请求被开放
EX1=1; // 外部中断1上的中断请求被允许

while(1); // 死循环,等待外部中断1
}
第2个回答  2014-04-23
啥单片机啊?有电路图吗?不可能全部帮你做吧,需要你有一点基础才行的。追问

电路图先不慌,我就打算先把编程做了。然后电路最后还是要做成数字信号

追答

“电路最后还是要做成数字信号”啥意思啊?是最终用数字电路来搭建吗?
单片机编程需要根据电路来写的啊,计数有啥要求吗?

追问

计数没有啥要求,能达到计数就可以了。就是就是暗黑条纹产生的脉冲信号进行计数

追答

这个比较简单的啊,把C/T设置成计数器模式,读取数据/处理/显示就行了。如果需要双向计数,那还需要信号源能产生两路信号,电路上也需要设计一个辨向电路