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

📄 test.c

📁 一个51单片机温度控制器,又一个示范如何在2051这样的小内存小ROM单片机上实现实时多任务小例子.使用时间片和状态机来完成任务的调度,而不是靠任务切换机制(这样小的资源是不足以支持RTOS的)
💻 C
字号:
#include <reg51.h>

code unsigned char* ver = "00000004";

sbit CS0 = P3^0;
sbit CS1 = P1^6;
sbit CS2 = P1^5;
sbit CS3 = P3^1;
sbit CS4 = P1^3;
sbit CS5 = P3^7;

sbit WARM = P3^4;
sbit LIGHT = P3^5;

//#define DATA_PORT P1

void out_cs_mask(bit n){
	CS0 = n;
	CS1 = n;
	CS2 = n;
	CS3 = n;
	CS4 = n;
	CS5 = 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;
		case 4:			CS4 = n;			break;
		case 5:			CS5 = n;			break;
	}
}

sbit CLK = P1^7;
sbit DATA = P1^4;
void spiout(unsigned char byte){
	unsigned char i;
	CLK = 0;
	for(i=0; i<8; i++){
		if(byte & 1)
			DATA = 1;
		else
			DATA = 0;
		CLK = 1;
		CLK = 0;
		byte >>= 1;
	}
}

#define a +1
#define b +2
#define c +4
#define d +8
#define e +16
#define f +32
#define g +64
//code unsigned char font[16] = "\x6f\x41\x3b\x6b" "\x4d\x76\x77\xe4" "\xf7\xf6\x00\x00" "\x00\x00\x00\x00";
code unsigned char font[16] = {
	a b c e f g,	//0
	a g,			//1
	a b d e f,		//2
	b a d g f,		//3
	a c d g,		//4
	b c d f g,		//5
	b c d e f g,	//6
	a b g,			//7
	a b c d e f g,	//8
	a b c d f g,	//9
	a b c d e g,	//A
	c d e f g,		//B
	b c e f,		//C
	a d e f g,		//D
	b c d e f,		//E
	b c d e,		//F
};
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g

#define DISP_WIDTH 6
unsigned char disp_buff[DISP_WIDTH];

unsigned char dot_pos = DISP_WIDTH;
unsigned char disp_cs = 0;

/*key value:
1:				1<<2
2:				1<<3
3:				1<<7
4:				1<<6
5:				1<<5
6:				1<<4
*/
#define	KEY_SET		(1<<2)		//键值1 2 4 8 16...
#define	KEY_FUNC	(1<<3)
unsigned char key_reg = 0x00,tmp_key_reg = 0x00;
unsigned char key_cs = 0;
sbit KEY_LINE = P1^2;

bit disp_on = 1;
void out_disp_buff(){
	unsigned char disp_data;

	out_cs_mask(1);

	//键盘扫描
	if(key_cs == 0)
		tmp_key_reg = 0;
	disp_data = 1<<key_cs;
	spiout(disp_data);
	if(KEY_LINE)
		tmp_key_reg |= disp_data;
	else
		tmp_key_reg &= ~disp_data;
	key_cs++;
	key_cs &= 7;
	if(key_cs == 0){
		key_reg = tmp_key_reg;
		disp_buff[5] = key_reg;
	}

	if (!disp_on){
		out_cs_mask(1);
		return;
	}

	disp_data = disp_buff[disp_cs];
	if (dot_pos == disp_cs)
		disp_data |= 0x80;


	if ((disp_cs & 1) == 1){
		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;
	spiout(disp_data);//~disp_data表示共阳驱动,disp_data是共阴驱动
	out_cs(disp_cs, 0);
	disp_cs++;
	if (disp_cs == DISP_WIDTH)
		disp_cs = 0;
}

unsigned int disp_flash = 0;
bit sys_wake_up = 0;

unsigned int time;
unsigned int timer_on;
unsigned int timer_long;
unsigned int time_ms= 0;
unsigned char jiffies = 0;
bit timer_isr_stop = 0;

void timer_isr(void) interrupt 1 using 1{
	jiffies++;
	if (jiffies < 10)
		return;
	jiffies = 0;
	sys_wake_up = 1;
	if(timer_isr_stop)
		return;
	time_ms++;
	if(time_ms == 1000)//同步闪烁与字符跳变
		disp_flash = 0;
//	if (time_ms == 60000){//1000 == 1 Sec
	if (time_ms == 1000){//1000 == 1 Sec
		time_ms = 0;
		time++;
		if(time == 1440)
			time = 0;
	}
}

void timer_init(void){
	timer_on = 300;
	timer_long = 30;
	time = 0;
	TMOD=0x02;
//	TH0=TL0=0x9b;//12M
//	TH0=TL0=0x7a;//16M
//	TH0=TL0=0x75;//16.59M
//	TH0=TL0=0x72;//17M
//	TH0=TL0=0x37;//24M
	TH0=TL0=-200;//24M
	EA=1;
	ET0=1;
	TR0=1;
}

void out_time(unsigned int out_time){
	unsigned char h, m;
	m = out_time % 60;
	h = out_time / 60;
	disp_buff[0] = font[h/10];
	disp_buff[1] = font[h%10];
	disp_buff[2] = font[m/10];
	disp_buff[4] = font[m%10];
}

#define FUCTION_NORMAL 0
#define FUCTION_TIME_ADJUST 1
#define FUCTION_TIMER_ON_SET 2
#define FUCTION_TIMER_OFF_SET 3
#define FUCTION_MAX 4
unsigned char function_select = FUCTION_NORMAL;

unsigned int key_set = 0;		//各按键按下去的时间,按住该键不放时,每运行一次键扫该值加1.
bit key_func = 0;
#define PUSH_DELAY 200		//100ms
#define FIRST_PUSH_DELAY 500		//250ms

void key_scan(void){
	unsigned int diff;
	//按键为高电平触发.
	if(key_reg & KEY_SET){
		disp_flash = 0;
		if(key_set){//原来已经按下,连续增加.
			if(key_set % PUSH_DELAY == 0 && key_set > FIRST_PUSH_DELAY){
				unsigned int _key_set = key_set - FIRST_PUSH_DELAY;
				diff = _key_set / PUSH_DELAY;
			}else
				diff = 0;
		}else
			diff = 1;
		if (function_select == FUCTION_TIME_ADJUST){
			timer_isr_stop = 1;
			time += diff;
			time %= 1440;	//一天为1440分钟
		}else if (function_select == FUCTION_TIMER_ON_SET){
			timer_on += diff;
			timer_on %= 720;	//一天为1440分钟
		}else if (function_select == FUCTION_TIMER_OFF_SET){
			timer_long += diff;
			timer_long %= 121;
			if(timer_long < 10)
				timer_long += 10;
		}
		if (key_set < 65500)
			key_set++;
	}else
		key_set = 0;

	if(key_reg & KEY_FUNC){
		disp_flash = 0;
		if(!key_func){//原来未按下,改变设置模式,否则不作处理.
			function_select++;
			if (function_select == FUCTION_MAX){
				function_select = FUCTION_NORMAL;//FUCTION_NORMAL == 0
				if (timer_isr_stop){
					timer_isr_stop = 0;
					time_ms = 0;
				}
			}
			key_func = 1;
		}
	}else
		key_func = 0;
}

#define FLASH_CHECK(x) disp_flash % x < x / 2
void sys_run(){
	while(1){
		if (!sys_wake_up)
			continue;
		sys_wake_up = 0;
		key_scan();
		if(function_select == FUCTION_NORMAL){
			unsigned int diff_time;
			diff_time = time % 720;
			if (diff_time >= timer_on && diff_time < timer_on + timer_long){//timer_long 为0时,定时器不再作输出.
				//out low
				WARM = 0;
				disp_flash++;
				if(FLASH_CHECK(500))
					disp_on = 1;
				else
					disp_on = 0;
			} else {
				//out high
				WARM = 0;
				disp_on = 1;
			}
		} else {
			disp_flash++;
			if(FLASH_CHECK(1000))
				disp_on = 1;
			else
				disp_on = 0;
		}
		
		if (function_select == FUCTION_TIME_ADJUST){
			dot_pos = 0;
			out_time(time);
		}else if (function_select == FUCTION_TIMER_ON_SET){
			dot_pos = 1;
			out_time(timer_on);
		}else if (function_select == FUCTION_TIMER_OFF_SET){
			dot_pos = 2;
			out_time(timer_long);
		}else{
			dot_pos = DISP_WIDTH;
			out_time(time);
		}
		out_disp_buff();
	}
}



void main(){
#if 1
	timer_init();
	sys_run();
#else
	unsigned char i;
	unsigned int j;

	out_cs_mask(0);
	for(i=0; ;){
		if (i==16)
			i=0;
		//DATA_PORT = ~(1 << i);
//		out_cs_mask(1);
//		spiout(1 << i);
//		spiout(font[i]);
//		out_disp_buff();
//		out_cs_mask(0);
//		for(j=0; j<500; j++);
//		disp_buff[0] = font[i];
//		disp_buff[1] = font[(i+1)&0xf];
//		disp_buff[2] = font[(i+2)&0xf];
//		disp_buff[3] = font[(i+3)&0xf];
//		disp_buff[4] = font[(i+4)&0xf];
//		disp_buff[5] = font[(i+5)&0xf];
//		for(j=0; j<200; j++);
//			out_disp_buff();
#if 0
		unsigned char disp_data;
		out_cs_mask(1);
		//键盘扫描
		key_reg = 0;
		disp_data = 1<<key_cs;
		spiout(disp_data);
		if(KEY_LINE)
			key_reg |= disp_data;
		else
			key_reg &= ~disp_data;
		key_cs++;
		key_cs &= 7;
		spiout(key_reg);
		out_cs_mask(0);
		for(j=0; j<500; j++);
#endif
	}
#endif
}


⌨️ 快捷键说明

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