⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 用51单片机做的简单频率计,KEIL C环境,带工程文件,可直接编译运行.主要演示如何在内存很少,无法启用RTOS的单片机(例如2051)中使用状态机和时间片来完成实时多任务并行处理.例子中对键盘,信
💻 C
字号:
#include <reg51.h>

unsigned char* ver = "00000000";

sbit CS0 = P3^7;
sbit CS1 = P3^1;
sbit CS2 = P3^0;
sbit CS3 = P3^3;

sbit KEY_SET	= P3^5;
sbit KEY_FUNC	= P3^4;
sbit IN_PIN		= P3^2;

#define DATA_PORT P1

void out_cs_mask(bit n){
	CS0 = n;
	CS1 = n;
	CS2 = n;
	CS3 = n;
}

void out_cs(unsigned char cs, bit n){
	switch (cs){
		case 0:			CS0 = n;			break;
		case 1:			CS1 = n;			break;
		case 2:			CS2 = n;			break;
		case 3:			CS3 = n;			break;
	}
}

unsigned char font[16] = "\xe7\x84\xd3\xd6" "\xb4\x76\x77\xe4" "\xf7\xf6\x00\x00" "\x00\x00\x00\x00";

#define DISP_WIDTH 4
unsigned char disp_buff[DISP_WIDTH];

unsigned char dot_pos = DISP_WIDTH;
unsigned char disp_cs = 0;
void out_disp_buff(){
	unsigned char disp_data;
	out_cs_mask(0);

	disp_data = disp_buff[disp_cs];//~表示共阳驱动,不加该运算则是共阴驱动
	if (dot_pos == disp_cs)
		disp_data |= 0x08;

	if ((disp_cs & 1) == 0){
		unsigned char d;
		d = (disp_data & 0x80) >> 3;
		d |= (disp_data & 0x40) >> 1;
		d |= (disp_data & 0x20) << 1;
		d |= (disp_data & 0x10) << 3;
		d |= (disp_data & 0x8) >> 3;
		d |= (disp_data & 0x4) >> 1;
		d |= (disp_data & 0x2) << 1;
		d |= (disp_data & 0x1) << 3;
		disp_data = d;
	}

	DATA_PORT = ~disp_data;
	out_cs(disp_cs, 1);
	disp_cs++;
	if (disp_cs == DISP_WIDTH)
		disp_cs = 0;
}

bit sys_wake_up = 0;
bit gate_start = 0;

unsigned char jiffies = 0;
unsigned int gate = 0;
void timer_isr(void) interrupt 1 using 1{
	jiffies++;
	if(IN_PIN){
		if(gate_start){
			gate_start = 0;
			sys_wake_up = 1;
		}
	}else{
		if(!gate_start){
			gate_start = 1;
			gate = 0;
		}else
			gate++;
	}

	if (jiffies % 10 == 0)
		sys_wake_up = 1;
}

void timer_init(void){
	TMOD=0x02;
	TH0=TL0=-100;//12M
//	TH0=TL0=-200;//24M
	EA=1;
	ET0=1;
	TR0=1;
}

#define CALC_DEC(x) ((n / x) % 10)
void out_dec(unsigned int n, unsigned char dot_poss){
	unsigned char i;
	disp_buff[0] = font[CALC_DEC(1000)];
	disp_buff[1] = font[CALC_DEC(100)];
	disp_buff[2] = font[CALC_DEC(10)];
	disp_buff[3] = font[CALC_DEC(1)];
	disp_buff[dot_poss] |= 0x08;
	for(i=0; i<DISP_WIDTH; i++){
		if (disp_buff[i] != font[0])
			break;
		disp_buff[i] = 0x00;
	}
}

#define FUCTION_FREQENCY 0
#define FUCTION_PULSE 1
#define FUCTION_MAX 2
unsigned char function_select = FUCTION_FREQENCY;

bit key_func = 0;

void key_scan(void){
	//按键为低电平触发,如要改为高电平触发,将"!KEY_FUNC"中的"!"去掉.
	if(!KEY_FUNC){
		if(!key_func){//原来未按下,改变设置模式,否则不作处理.
			function_select++;
			if (function_select == FUCTION_MAX)
				function_select = FUCTION_FREQENCY;//FUCTION_FREQENCY == 0
			key_func = 1;
		}
	}else
		key_func = 0;
}

#define FLASH_CHECK(x) disp_flash % x < x / 2
void sys_run(){
	out_dec(0, DISP_WIDTH - 1);
	while(1){
		if (!sys_wake_up)
			continue;
		sys_wake_up = 0;

		key_scan();

		if(function_select == FUCTION_FREQENCY){
			unsigned int value = 8888;
			unsigned char dot_poss = DISP_WIDTH - 1;
			if(gate < 10){
				value = 10000 / gate;
				dot_poss = DISP_WIDTH - 2;
			}else if(gate < 100){
				value = 100000 / gate;
				dot_poss = DISP_WIDTH - 3;
			}else if(gate < 1000){
				value = 1000000 / gate;
				dot_poss = DISP_WIDTH - 4;
			}else if(gate < 10000){
				value = 10000000 / gate;
				dot_poss = DISP_WIDTH - 4;
			}

			out_dec(value, dot_poss);
		}else{
			if(gate < 9999)
				out_dec(gate, DISP_WIDTH - 1);
			else
				out_dec(gate / 10, DISP_WIDTH - 2);
		}

		out_disp_buff();
	}
}

void main(){
	timer_init();
	sys_run();
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -