|

楼主 |
发表于 2009-5-17 17:27:14
|
显示全部楼层
续(源程序部分)
//
// 100MHz / 2.4GHz Universal Counter
// 100MHz/2.4GHz 通用计数器
// SAMPLE Electronics co. 25. Nov. 2003
// 韩国Sample电子公司 二○○三年十一月二十五日
// Crossware Embedded Development Studio V 3.3.1.2
// 克洛斯威尔 嵌入开发工作站 版本:3.3.1.2
//
//
// 74F161的4比特,74HC393的8比特及8051的16比特内部计数器,共同构成28比特计数器。
// 脉冲计数时间为1秒,8位数字显示100兆赫计数器。
// 采用64分频的预分频器时,脉冲计数时间为0.64秒。
//
//
// 8051初始源程序
//
#include <sfr.h>
#include <os.h>
#include <stdlib.h>
#include <stdio.h>
_sfrbit P36_o_74f161_clr_n = _p3^6; //外部计数器F161复位
_sfrbit P35_o_74f161_enp = _p3^5; //外部计数器F161有效(Enable)
_sfrbit P30_io_74hc393_clr_hold = _p3^0; //外部计数器HC393复位/HOLD输入
_sfrbit P37_i_prescaler = _p3^7; // 64分频的预分频器
//
//七段LED字形数据
// hgfedcba
#define DIG0 0xC0 // 11000000b ; 0 P2.0
#define DIG1 0xF9 // 11111001b ; 1 +-----a-----+
#define DIG2 0xA4 // 10100100b ; 2 | |
#define DIG3 0xB0 // 10110000b ; 3 P2.5 f b P2.1
#define DIG4 0x99 // 10011001b ; 4 | |
#define DIG5 0x92 // 10010010b ; 5 | P2.6 |
#define DIG6 0x82 // 10000010b ; 6 +-----g-----+
#define DIG7 0xD8 // 11011000b ; 7 | |
#define DIG8 0x80 // 10000000b ; 8 P2.4 e c P2.2
#define DIG9 0x98 // 10011000b ; 9 | |
// ; | P2.3 |
#define DIGM 0xBF // 10111111b ; - +-----d-----+ * h P2.7
#define DIGP 0x7F // 01111111b ; .
#define DIGB 0xFF // 11111111b ; "Blank"(“空白”)
//
const char segment_pattern[] = { DIG0, DIG1, DIG2,\
DIG3, DIG4, DIG5, DIG6, DIG7, DIG8, DIG9 };
//
const char segment_select[] = { 0xFE, 0xFD, 0xFB, \
0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
//
unsigned long trailer;
unsigned long task;
unsigned int trimer;
unsigned char fnd[8];
unsigned char mfnd[8];
unsigned int int_state;
unsigned char fnd_state;
unsigned char boat;
bit hold;
//
//
void _interrupt IVN_TIMER1 time_base() {
//////////////////////////////////////////////
_tl1 = 0x60; _th1 = 0xF0; // 4000 2 M Sec 500 Times
//////////////////////////////////////////////
_p0 = 0xff;
_p2 = segment_select[fnd_state];
_p0 = fnd[fnd_state++];
fnd_state &= 0x07;
//////////////////////////////////////////////
if(int_state == 0) { //
P35_o_74f161_enp = 0; //外部计数器F161计数禁止
P30_io_74hc393_clr_hold = 1; //外部计数器HC393复位
P36_o_74f161_clr_n = 0; //外部计数器F161复位
_tl0 = 0x00; _th0 = 0x00; //内部计数器复位
hold = P30_io_74hc393_clr_hold; // HOLD(保持)键状态输入
P36_o_74f161_clr_n = 1; // 外部计数器F161有效(Enable)
P30_io_74hc393_clr_hold = 0; // 外部计数器HC393有效(Enable)
P35_o_74f161_enp = 1; // 外部计数器F161进行计数
}
//////////////////////////////////////////////
if(int_state == 316) { // 10GHz状态(64分频的预分频器)
if (!P37_i_prescaler) { // 门控时间为0.64秒
for (trimer = 0; trimer<202; trimer++) ; // 15个机器周期单位
// 测试信号24MHz输入
boat++; // 15360000 用于显示,需调整
boat++; // 延迟1个机器周期(12个时钟周期)
boat++; // 15359988
boat++; // 15360000
// boat++; // 15360012
P35_o_74f161_enp = 0; // 外部计数器停止
trailer = _th0;
trailer = (trailer << 20) & 0x0ff00000;
task = _tl0;
task = (task << 12) & 0x000ff000;
trailer |= task;
task = _p3;
task = (task << 7) & 0x00000f00;
trailer |= task;
task = _p1 & 0x000000ff;
trailer |= task;
P35_o_74f161_enp = 1; // 소비 전류가 일정하게 하기위하여
// 电流消耗,
// 外部计数器将重新开始。
}
}
//////////////////////////////////////////////
if(int_state == 494) { // 100 MHz Mode 1 Sec Gate Time
if (P37_i_prescaler) { // 1 Sec Gate Time
for (trimer = 0; trimer<248; trimer++) ; // 15个机器周期单位
// 测试24MHz信号源输入
boat++; // 24000000 用于显示,需调整
boat++; //
boat++; //
boat++; //
boat++; // 延迟1个机器周期(12个时钟周期)
boat++; // 23999988
boat++; // 24000000
// boat++; // 24000012
P35_o_74f161_enp = 0; // 外部计数器停止
trailer = _th0;
trailer = (trailer << 20) & 0x0ff00000;
task = _tl0;
task = (task << 12) & 0x000ff000;
trailer |= task;
task = _p3;
task = (task << 7) & 0x00000f00;
trailer |= task;
task = _p1 & 0x000000ff;
trailer |= task;
P35_o_74f161_enp = 1; // 소비 전류가 일정하게 하기위하여
// 电流消耗,以时间表
// 外部计数器重新开始。
}
}
//////////////////////////////////////////////
if(int_state == 506) { // 1Hz数字显示
boat = trailer % 10;
mfnd[7] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 507) {
boat = trailer % 10;
mfnd[6] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 508) {
boat = trailer % 10;
mfnd[5] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 509) {
boat = trailer % 10;
mfnd[4] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 510) {
boat = trailer % 10;
mfnd[3] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 511) {
boat = trailer % 10;
mfnd[2] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 512) {
boat = trailer % 10;
mfnd[1] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 513) {
boat = trailer % 10;
mfnd[0] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
int_state++;
//////////////////////////////////////////////
if(int_state >= 514) {
int_state = 0;
if (hold) {
fnd[0] = mfnd[0];
fnd[1] = mfnd[1];
fnd[2] = mfnd[2];
fnd[3] = mfnd[3];
fnd[4] = mfnd[4];
fnd[5] = mfnd[5];
fnd[6] = mfnd[6];
fnd[7] = mfnd[7];
if (P37_i_prescaler) {
fnd[1] &= 0x7F; // MHz点
} else {
fnd[0] &= 0x7F; // GHz点
}
}
}
//////////////////////////////////////////////
}
main()
{
_tmod = 0x15; // 0b00010101 Timer0 = Mode1, Counter, use TR0
// Timer1 = Mode1, Timer, use TR1
_tl0 = 0X0; _th0 = 0X0;
_tl1 = 0X0; _th1 = 0X0;
_tr0 = 1; // Timer 0 计数开始
_tr1 = 1; // Timer 1 计数开始
_et1 = 1; // 设置定时器1中断状态
_ea = 1; // 设置全局中断状态
while(1) ;
}
源程序可到http://www.sample.co.kr/sefcntr/sefcntr.zip网页下载。
(1) Crossware.公司8051 编译器(演示版)的安装
创建一个c:\estudio_demo\Projects\fcntr4文件夹,将文件解压到这个文件夹内。
(2) 在Crossware的File(文件)菜单上,单击Project Open(打开项目),选择C:\estudio_demo\Projects\fcntr4\fcntr4.xmk。
(3) 在Crossware的Build(建立)菜单中,选择Rebuild All开始汇编的源程序并创建fcntr4.hex文件。
(5) 可以采用Sample电子公司编辑的AT89C51的SE-516SP文本(http://www.sample.co.kr/se516/index.htm) fcntr4,在8051编程器上进行编程。
Crossware公司的 8051 C 编译器(演示版)可以下载。能以“.HEX”文件的格式输出从起始部位(0000H)开始的4K十六进制代码( http://www.sample.co.kr/sefcntr/fnctr4.hex )。
AT89C51,AT89S51及AT89C1051/2051/4051均带有4k闪存。
Crossware 8051 C 编译器( http://www.crossware.co.kr/setup-demo.exe ),已被选定为韩国产业工人协会( http://www.hrdkorea.or.kr/ )进行工程师及技术工人考试的指定编译器。
Crossware 8051 C 编译器手册(韩文)( http://www.crossware.co.kr/crossb.pdf ) |
|