嵌入式 - 基础

嵌入式 - 基础

  • 存储器
    • RAM(随机存储器)
    • ROM(只读存储器)
  • IO口/寄存器/CPU
  • 定时器
    • 例子 - 定时器控制流水灯
    • 定时器与中断
    • 定时器与计数器
    • 定时器系统时钟
  • 中断
    • 工作流程
    • 中断源
    • 定时器与中断
  • 外设例子
    • LED控制
    • 数码管显示
    • 按键
  • 延时
    • 代码
  • 定时器 - 补充代码
    • 代码1 配置定时器0和定时器1
    • 代码2 使用定时器的方法 查询按键是否被按下

存储器

RAM(随机存储器)

易失性存储器:掉电丢失数据
存取速度快

  • SRAM(静态RAM):电路存储数据;速度最快,容量小
  • DRAM(动态RAM):电容(充放电)存储数据;容易漏电,需要扫描电路,成本低,容量大

ROM(只读存储器)

非易失性存储器:掉电不丢失数据
存取速度慢

  • Mask ROM(掩膜ROM):早起ROM,用电路存储数据 (芯片做好就是这个电路,读出来的就是这个数据)
  • PROM(可编程ROM):生产出来之后,只能写入一次,不能再次更改
  • EPROM(可擦除可编程ROM):可以擦除(但是需要紫外线照射擦除)
  • E2PROM(电可擦除可编程ROM):直接控制程序可以擦除,
  • Flash(闪存):现代ROM
  • 硬盘、软盘、光盘

嵌入式 - 基础_第1张图片

IO口/寄存器/CPU

IO口电平和寄存器之间的交互可以通过以下步骤进行:

输出数据到IO口:当CPU需要向外部设备输出数据时,它会将数据写入指定的寄存器。这个寄存器通常称为输出寄存器或数据寄存器。CPU将要输出的数据写入到该寄存器中。

控制IO口电平:一旦数据被写入输出寄存器,CPU需要通过控制信号来改变IO口的电平状态。通常,CPU会通过控制寄存器或控制线信号来发出特定的命令,以控制IO口电平的变化。

IO口电平的改变:根据CPU发出的控制信号,IO口的电平会相应地改变。例如,如果CPU要将IO口设置为高电平,相关的控制信号会使外部设备电平变为高电平。反之,如果CPU要将IO口设置为低电平,控制信号会使外部设备电平变为低电平。

输入数据到寄存器:当外部设备的电平状态发生变化时(例如,另一个设备向CPU发送数据),IO口的电平变化会被检测到,并通过相应的电路传输到输入寄存器或数据寄存器。CPU可以通过读取该寄存器来获取输入的数据。

总结起来,CPU通过写入输出寄存器来设置数据的传输值,通过控制信号来控制IO口电平的改变,外部设备根据电平状态的变化将数据输入到输入寄存器或数据寄存器,CPU再通过读取该寄存器来获取输入的数据。这样实现了IO口电平和寄存器之间的交互。

定时器

https://www.bilibili.com/video/BV1k84y1v7q9/?spm_id_from=333.788&vd_source=7155082256127a432d5ed516a6423e20

51原理图
嵌入式 - 基础_第2张图片
在这里插入图片描述

定时器/计数
嵌入式 - 基础_第3张图片

编程实现
嵌入式 - 基础_第4张图片

例子 - 定时器控制流水灯

#include 

void main()
{
	/* NOTE: variable must declare in block front*/
	unsigned char k,n,i;
	unsigned short timer_ms;
	unsigned short initValue;
	n=0x01;
	k=0;
	
	/* setp1: config Timer register work mode */ 
  /* 0000 0001 -> T1(0000); T0(0001):: 
	 * GATE: 0 startup only with software
	 * C/T:  0 use to on timer 
	 * M1,M0: 0,1 : use TH0 and TL0
	 */
	TMOD=0x01;
	
	/* step2: set init value*/
	timer_ms=50; // 50ms
	initValue=65536-timer_ms*1000;
	TH0=(unsigned char)((initValue>>8) & 0xFF);
	TL0=(unsigned char)(initValue & 0xFF); 
	
	/* step3: start timer, if this timer is time out,the bit TF0 is 1*/
	TR0=1; // 0 is stop ; 1 is start
	
	while (1)
	{
		// left bit trans
		n=0x01;
		
		for (i=0;i<8;i++) // set 8 led 
		{
			P2=~n; // set led light
		
			while (k<10) // 50ms *10 = 500ms is 0.5s
			{
				/* setp4: wait timer time out*/	
				while (TF0==0); // 
				
				/* setp5: reset init value */
				TH0=(unsigned char)((initValue>>8) & 0xFF);
				TL0=(unsigned char)(initValue & 0xFF); 
				TF0=0;
				k++;
			}
			
			// the next led
			k=0;
			n=n<<1;
		}	
		
	}
}

定时器与中断

嵌入式 - 基础_第5张图片

定时器与计数器

时钟系统由外部引脚提供的时候,就是计数器

定时器系统时钟

系统时钟就是晶振周期,不等于机器周期
对于分频的系统时钟,12T表示12分频,对于晶振周期是12MHZ的时钟系统,12分频后就是1MHZ,一个机器周期就是1us(1微秒)

中断

嵌入式 - 基础_第6张图片

工作流程

其中一步:程序记录在ROM中, 记录断点就是记录程序语句被打断的存放的寄存器的地址(将要执行的中断语句地址,压入堆栈,中断程序返回后,再弹出堆栈)

在这里插入图片描述

中断源

引起CPU中断的根源:中断源
用于中断(打断)程序

中断优先:
分时操作:CPU分时执行I/O操作
实时响应:立即执行中断响应
可靠性

51单片机

一共有五个中断源

嵌入式 - 基础_第7张图片
嵌入式 - 基础_第8张图片

优先级

当多个中断源对CPU执行中断请求的时候,CPU根据中断源的优先级执行对应的中断请求
单片机内有默认的优先级别,也可以修改对应寄存器的值来修改优先级

嵌套

永远执行优先级高的中断 (例:在执行中断优先级低的中断程序B中,发生了一个更高优先级的中断请求C,那么则中断B,执行C,执行完成C后,在返回执行B)

定时器与中断

嵌入式 - 基础_第9张图片

时钟系统,来一个脉冲,计数系统就+1

** 例子 !!!**

#include 

unsigned char k;
unsigned short initValue;

/* how to skip interrupt code */
/*
 * 1 is interrput number
 * cpu use interrupt number to find interrupt code(interrupt server code)
 * no need to manual check TF0==1(while(TF0==0)), i.e. timer count number overflow!!!
 */
void timer0() interrupt 1
{
	/* setp5: reset init value */
	TH0=(unsigned char)((initValue>>8) & 0xFF);
	TL0=(unsigned char)(initValue & 0xFF); 
	TF0=0;
	k++;
}

void main()
{
	/* NOTE: variable must declare in block front*/
	unsigned char n,i;
	unsigned short timer_ms;
	n=0x01;
	k=0;
	
	/* !!! use interrupt method and config interrupt !!! */
	EA=1; // interrupt enable register,main flag
	ET0=1; // T0 timer interrupy enable flag
	
	/* setp1: config Timer register work mode */ 
  /* 0000 0001 -> T1(0000); T0(0001):: 
	 * GATE: 0 startup only with software
	 * C/T:  0 use to on timer 
	 * M1,M0: 0,1 : use TH0 and TL0
	 */
	TMOD=0x01;
	
	/* step2: set init value*/
	timer_ms=50; // 50ms
	initValue=65536-timer_ms*1000;
	TH0=(unsigned char)((initValue>>8) & 0xFF);
	TL0=(unsigned char)(initValue & 0xFF); 
	
	/* step3: start timer, if this timer is time out,the bit TF0 is 1*/
	TR0=1; // 0 is stop ; 1 is start (timer.start)
	
	while (1)
	{
		// left bit trans
		n=0x01;
		
		for (i=0;i<8;i++) // set 8 led 
		{
			P2=~n; // set led light
		
			/* !!! use variable k to connect timer0 function and contiol next code exec!!! */ 
			/* if timer time out k++, untill k=10 quit while code block */ 
			while (k<10) // 50ms *10 = 500ms is 0.5s
			{
//				/* setp4: wait timer time out*/	
//				while (TF0==0); // 
//				
//				/* setp5: reset init value */
//				TH0=(unsigned char)((initValue>>8) & 0xFF);
//				TL0=(unsigned char)(initValue & 0xFF); 
//				TF0=0;
//				k++;
			}
			
			// the next led
			k=0;
			n=n<<1;
		}	
		
	}
}

例子2

#include 

unsigned short initValue=65535-1000; // 1ms; unsigned short initValue=65535-1000+1; // 1ms is +1 is best, counter!!!
unsigned int timer_xms=1000; // timer out control led switch

void initTimer0()
{
	/* timer contorl register */ 
	TMOD=0x01;
	
	/* interrupt overflow flag */ 
	TF0=0;

	/* timer0 start*/ 
	TR0=1;
	
	/* set timer count init value */
	TH0=((unsigned char)(initValue>>8))&0xFF; // 1000us=1ms 
	TL0=(unsigned char)(initValue&0xFF);
	
	/* set interrupt enable flag*/
	EA=1;
	ET0=1;
	PT0=0;
}

/* interrupt sub code */
void doTimer0() interrupt 1 // timer0 interrupt's number is 1
{
	static unsigned int timer_xms_count=0;
	timer_xms_count++;
	if (timer_xms_count==timer_xms)
	{
		P2_0=~P2_0;
		timer_xms_count=0;
	}
	
	/* set timer count init value */
	TH0=((unsigned char)(initValue>>8))&0xFF; // 1000us=1ms 
	TL0=(unsigned char)(initValue&0xFF);
}

void main()
{
	// init timer0
	initTimer0();
	
	// main code block
	while (1)
	{
		
	}
}

代码优化
TMOD=TMOD&0xF0; TMOD=TMOD|0x01; 代替 TMOD=0x01; 防止高四位被修改

外设例子

LED控制

#include 
#include 

//void Delay500ms()		//@12.000MHz
//{
//	unsigned char data i, j, k;

//	_nop_();
//	i = 4;
//	j = 205; 	// 205
//	k = 187;	// 187
//	do
//	{
//		do
//		{
//			while (--k);
//		} while (--j);
//	} while (--i);
//}

void DelayXms(unsigned int xms)		//@12.000MHz
{
	unsigned char data i, j;
	
	unsigned int xms_num=0;
	while (xms_num++<xms)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}


void main()
{
	unsigned char ledNum=0;
	while (1)
	{
		/* === exp1: led waterfall light === */
//		P2=0xFE;
//		DelayXms(100);
//		P2=0xFD;
//		DelayXms(200);
//		P2=0xFB;
//		DelayXms(300);
//		P2=0xF7;
//		DelayXms(500);
//		P2=0xEF;
//		DelayXms(500);
//		P2=0xDF;
//		DelayXms(600);
//		P2=0xBF;
//		DelayXms(700);
//		P2=0x7F;
//		DelayXms(800);
		
		/*******************************************************/
		/* === if key is down, the elec level is low level === */
		/*******************************************************/

		/* === exp2: key control led switch === */
		// down turn on, up turn off
//		if (P3_1==0) 	// read register
//		{
//			P2_0=0; 		// write register
//		}
//		else if (P3_1==1)
//		{
//			P2_0=1;			
//		}
		
		/* === exp3: key control led switch === */
		// key push once led switch once
//		if (P3_1==0)
//		{
//			DelayXms(20); 		// delay 20ms to filter 
//			while (P3_1==0);	// key up is turn off
//			DelayXms(20);			// delay 20ms to filter
//			P2_0=~P2_0;				// switch led
//		}
		
		/* === exp4: key control led switch === */
//		if (P3_1==0)
//		{
//			DelayXms(20); 		// delay 20ms to filter 
//			while (P3_1==0);	// key up is turn off
//			DelayXms(20);			// delay 20ms to filter
//			
//			ledNum++;
//			P2=~ledNum;
//		}

		/* === exp5: key control led switch === */
		if (P3_1==0)
		{
			DelayXms(20); 		// delay 20ms to filter 
			while (P3_1==0);	// key up is turn off
			DelayXms(20);			// delay 20ms to filter
			
			ledNum++;
			if (ledNum>=8)
			{
				ledNum=0;
			}
			P2=~(0x01<
		}
		
		/* === exp6: two key control led switch === */
		if (P3_1==0)
		{
			DelayXms(20); 		// delay 20ms to filter 
			while (P3_1==0);	// key up is turn off
			DelayXms(20);			// delay 20ms to filter
			
			ledNum++;
			if (ledNum>=8)
			{
				ledNum=0;
			}
			P2=~(0x01<<ledNum);
		}
		else if (P3_0==0)
		{
			DelayXms(20); 		// delay 20ms to filter 
			while (P3_0==0);	// key up is turn off
			DelayXms(20);			// delay 20ms to filter
			
			if (ledNum==0)
			{
				ledNum=7;
			}
			else
			{
				ledNum--;
			}
 
			P2=~(0x01<<ledNum);
		}
	}
}

数码管显示

// main.c
#include 
#include "delay.h"
#include "ledControl.h"

//#define LED0 		0x3F 		// 0x3F 0B00111111
//#define LED1 		0x06		// 0x06 0B00000110
//#define LED2 		0x5B		// 0x5B 0B01011011
//#define LED3 		0x4F		// 0x4F 0B01001111
//#define LED4 		0x66		// 0x66	0B01100110
//#define LED5 		0x6D		// 0x6D 0B01101101
//#define LED6 		0x7D		// 0x7D 0B01111101
//#define LED7 		0x07		// 0x07 0B00000111
//#define LED8 		0x7F		// 0x7F 0B01111111
//#define LED9 		0x6F		// 0x6F 0B01101111
//#define LEDDOT 	0x80		// 0x67 0B10000000

//void DelayXms(unsigned int xms)		//@12.000MHz
//{
//	unsigned char data i, j;
//	
//	unsigned int xms_num=0;
//	while (xms_num++
//	{
//		i = 12;
//		j = 169;
//		do
//		{
//			while (--j);
//		} while (--i);
//	}
//}


//void ledDriverShowSwitch(bool isTurnOnAll)
//{
//	if (isTurnOnAll)
//	{
//		for (int i=0;i<8;i++)
//		{
//			
//		}
//	}
//}

//void ledDriverShow(unsigned char pos,unsigned char num)
//{
//	if (pos<0 || pos>7 )
//	{
//		return;
//	}
//	
//	if (num<0 || num >10)
//	{
//		return;
//	}
//	
//	// position
//	// pos use littleEnd
//	pos=7-pos;
//	P2_2=(pos) & 0x01;
//	P2_3=(pos>>1) & 0x01;	
//	P2_4=(pos>>2) & 0x01;
//	
//	// number
//	switch(num)
//	{
//		case 0:
//			P0=LED0;
//			break;
//		case 1:
//			P0=LED1;
//			break;
//		case 2:
//			P0=LED2;
//			break;
//		case 3:
//			P0=LED3;
//			break;
//		case 4:
//			P0=LED4;
//			break;
//		case 5:
//			P0=LED5;
//			break;		
//		case 6:
//			P0=LED6;
//			break;
//		case 7:
//			P0=LED7;
//			break;
//		case 8:
//			P0=LED8;
//			break;
//		case 9:
//			P0=LED9;
//			break;
//		default:
//			P0=LEDDOT;
//			break;
//	}
//	
//	// Prevent data misalignment
	DelayXms(1);
//	P0=0x00; // set zero to clear
//}

void main()
{
	/********************************************/
	/*** scan mode to update digit tube data ****/
	/********************************************/	
	
	/* === exp1: set digit led ,pos 3,num 6 === */
	//74HC138 decoder 
	// 0000 0101=5 set Y4(led6) on
//	P2_4=1;
//	P2_3=0;
//	P2_2=1;
//	
//	P0=0x7D; // set led digit tube: digit 6 
//	while(1)
//	{
//		
//	}
	
	/* === exp2: use function set digit led ,pos x,num y === */
	while (1)
	{
		int i=0;
		for (;i<8;i++)
		{
			ledDriverShow(i,i);
//			DelayXms(50);
		}
	}
}
// ledControl.h
#ifndef __LEDCONTROL_H__
#define __LEDCONTROL_H__

#include 

#define LED0 		0x3F 		// 0x3F 0B00111111
#define LED1 		0x06		// 0x06 0B00000110
#define LED2 		0x5B		// 0x5B 0B01011011
#define LED3 		0x4F		// 0x4F 0B01001111
#define LED4 		0x66		// 0x66	0B01100110
#define LED5 		0x6D		// 0x6D 0B01101101
#define LED6 		0x7D		// 0x7D 0B01111101
#define LED7 		0x07		// 0x07 0B00000111
#define LED8 		0x7F		// 0x7F 0B01111111
#define LED9 		0x6F		// 0x6F 0B01101111
#define LEDDOT 	0x80		// 0x67 0B10000000

void ledDriverShow(unsigned char pos,unsigned char num);

#endif


// ledControl.c
#include "ledControl.h"

void ledDriverShow(unsigned char pos,unsigned char num)
{
	if (pos<0 || pos>7 )
	{
		return;
	}
	
	if (num<0 || num >10)
	{
		return;
	}
	
	// position
	// pos use littleEnd
	pos=7-pos;
	P2_2=(pos) & 0x01;
	P2_3=(pos>>1) & 0x01;	
	P2_4=(pos>>2) & 0x01;
	
	// number
	switch(num)
	{
		case 0:
			P0=LED0;
			break;
		case 1:
			P0=LED1;
			break;
		case 2:
			P0=LED2;
			break;
		case 3:
			P0=LED3;
			break;
		case 4:
			P0=LED4;
			break;
		case 5:
			P0=LED5;
			break;		
		case 6:
			P0=LED6;
			break;
		case 7:
			P0=LED7;
			break;
		case 8:
			P0=LED8;
			break;
		case 9:
			P0=LED9;
			break;
		default:
			P0=LEDDOT;
			break;
	}
	
	// Prevent data misalignment
	DelayXms(1);
	P0=0x00; // set zero to clear
}

按键

#ifndef __KEY_H__
#define __KEY_H__

#include 
#include "delay.h"

unsigned char getKeyNumber();

#endif
// key.cpp
#include "key.h"

unsigned char getKeyNumber()
{
	unsigned char keyNumber=0;
	
	if (P3_1==0){DelayXms(20);while (P3_1==0);DelayXms(20);keyNumber=1;}
	if (P3_0==0){DelayXms(20);while (P3_0==0);DelayXms(20);keyNumber=2;}
	if (P3_2==0){DelayXms(20);while (P3_2==0);DelayXms(20);keyNumber=3;}
	if (P3_3==0){DelayXms(20);while (P3_3==0);DelayXms(20);keyNumber=4;}
	
	return keyNumber;
}

延时

代码

// delay.h
#ifndef __DELAY_H__
#define __DELAY_H__

void DelayXms(unsigned int xms);		//@12.000MHz

#endif
// delay.c
#include "delay.h"

void DelayXms(unsigned int xms)		//@12.000MHz
{
	unsigned char data i, j;
	
	unsigned int xms_num=0;
	while (xms_num++<xms)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}

定时器 - 补充代码

代码1 配置定时器0和定时器1

#ifndef __MYTIMER_H__
#define __MYTIMER_H__

#include 

void initTimer(unsigned char number,unsigned char mode,unsigned short initValue);
void setTimerInitValue(unsigned char number,unsigned short initValue);

#endif
// myTimer.c
#include "myTimer.h"

void initTimer(unsigned char number,unsigned char mode,unsigned short initValue)
{
	if (number==0) // timer 0
	{
		/* timer work mode register TMOD */
		TMOD=TMOD&0xF0;
		switch (mode)
		{
			case 1:
				TMOD=TMOD|0x01;	// 0000 0001
				break;
			case 2:
				TMOD=TMOD|0x02; // 0000 0010
				break;
			default:
				TMOD=TMOD|0x00;
				break;
		}
		
		/* timer control register TCON */
		/* interrupt overflow flag */ 
		TF0=0;
		
		setTimerInitValue(number,initValue);
		
		/* interrupt enable register IE*/
		/* set interrupt enable flag*/
		EA=1;
		ET0=1;
		PT0=0;
		
		/* timer0 start*/  // TCON
		TR0=1;
		

	}
	else if (number==1) // timer 1
	{
		/* timer work mode register TMOD */
		TMOD=TMOD&0xF0;
		switch (mode)
    {
    	case 1:
				TMOD=TMOD|0x10;	// 0001 0000
    		break;
    	case 2:
				TMOD=TMOD|0x20;	// 0010 0000
    		break;
    	default:
				TMOD=TMOD|0x00;
    		break;
    }
		
		/* timer control register TCON */
		/* interrupt overflow flag */ 
		TF1=0;
		
		setTimerInitValue(number,initValue);
		
		/* interrupt enable register IE*/
		/* set interrupt enable flag*/
		EA=1;
		ET1=1;
		PT0=0;
		
		/* timer0 start*/ 
		TR1=1;
	}
	
}

void setTimerInitValue(unsigned char number,unsigned short initValue)
{
	if (number==0)
	{
		/* set timer count init value */
		TH0=((unsigned char)(initValue>>8))&0xFF; // 1000us=1ms 
		TL0=(unsigned char)(initValue&0xFF);
	}
	else if (number==1)
	{
		/* set timer count init value */
		TH1=((unsigned char)(initValue>>8))&0xFF; // 1000us=1ms 
		TL1=(unsigned char)(initValue&0xFF);
	}
}

代码2 使用定时器的方法 查询按键是否被按下

ledControl.h 数码管

#ifndef __LEDCONTROL_H__
#define __LEDCONTROL_H__

#include 

#define LED0 		0x3F 		// 0x3F 0B00111111
#define LED1 		0x06		// 0x06 0B00000110
#define LED2 		0x5B		// 0x5B 0B01011011
#define LED3 		0x4F		// 0x4F 0B01001111
#define LED4 		0x66		// 0x66	0B01100110
#define LED5 		0x6D		// 0x6D 0B01101101
#define LED6 		0x7D		// 0x7D 0B01111101
#define LED7 		0x07		// 0x07 0B00000111
#define LED8 		0x7F		// 0x7F 0B01111111
#define LED9 		0x6F		// 0x6F 0B01101111
#define LEDDOT 	0x80		// 0x67 0B10000000

void ledDriverShow(unsigned char pos,unsigned char num);

#endif

ledControl.c 数码管

#include "ledControl.h"
#include "delay.h"

void ledDriverShow(unsigned char pos,unsigned char num)
{
	if (pos<0 || pos>7 )
	{
		return;
	}
	
	if (num<0 || num >10)
	{
		return;
	}
	
	// position
	// pos use littleEnd
	pos=7-pos;
	P2_2=(pos) & 0x01;
	P2_3=(pos>>1) & 0x01;	
	P2_4=(pos>>2) & 0x01;
	
	// number
	switch(num)
	{
		case 0:
			P0=LED0;
			break;
		case 1:
			P0=LED1;
			break;
		case 2:
			P0=LED2;
			break;
		case 3:
			P0=LED3;
			break;
		case 4:
			P0=LED4;
			break;
		case 5:
			P0=LED5;
			break;		
		case 6:
			P0=LED6;
			break;
		case 7:
			P0=LED7;
			break;
		case 8:
			P0=LED8;
			break;
		case 9:
			P0=LED9;
			break;
		default:
			P0=LEDDOT;
			break;
	}
	
	// Prevent data misalignment
	DelayXms(1);
	P0=0x00; // set zero to clear
}

key.h

#ifndef __KEY_H__
#define __KEY_H__

#include 
#include "delay.h"

unsigned char getKeyNumber();
unsigned char getKeyState();
void keyInterruptLoop();
unsigned char getFinalKeyNumber();

#endif

key.c

#include "key.h"

static unsigned char keyNumber_finalget=0;

unsigned char getKeyNumber()
{
	unsigned char keyNumber=0;
	
	if (P3_1==0){DelayXms(20);while (P3_1==0);DelayXms(20);keyNumber=1;}
	if (P3_0==0){DelayXms(20);while (P3_0==0);DelayXms(20);keyNumber=2;}
	if (P3_2==0){DelayXms(20);while (P3_2==0);DelayXms(20);keyNumber=3;}
	if (P3_3==0){DelayXms(20);while (P3_3==0);DelayXms(20);keyNumber=4;}
	
	return keyNumber;
}

unsigned char getKeyState()
{
	unsigned char keyNumber=0;
	
	if (P3_1==0){keyNumber=1;}
	if (P3_0==0){keyNumber=2;}
	if (P3_2==0){keyNumber=3;}
	if (P3_3==0){keyNumber=4;}
	
	return keyNumber;
}

void keyInterruptLoop()
{

	static unsigned char prekeyState=0;
	static unsigned char currkeyState=0;
	
	prekeyState=currkeyState;
	currkeyState=getKeyState();
	
	// think more
	// noly check release or not, i.e. from press to release
	if (prekeyState==1 && currkeyState==0)
	{
		keyNumber_finalget=1;
	}
	else	if (prekeyState==2 && currkeyState==0)
	{
		keyNumber_finalget=2;
	}
	else	if (prekeyState==3 && currkeyState==0)
	{
		keyNumber_finalget=3;
	}
	else	if (prekeyState==4 && currkeyState==0)
	{
		keyNumber_finalget=4;
	}
}

unsigned char getFinalKeyNumber()
{
	unsigned char keyNumber_temp=0;
	keyNumber_temp=keyNumber_finalget;
	keyNumber_finalget=0; // clear; keep keyNumber_finalget is 0;
	return keyNumber_temp;
}

main.c

#include 
#include "delay.h"
#include "key.h"
#include "AT24C02.h"
#include "myTimer.h"
#include "ledControl.h" // 数码管

unsigned short initValue=65536-1000; // 1000us=1ms
unsigned int timer_xms=1000; // 1000*1ms=1s
unsigned int key_timer_xms=20; // 20*1ms=20ms

unsigned char keyNumber=0;
unsigned char keyNumberToShow=0;

void timer0_interrupt() interrupt 1
{
	static unsigned int timer_xms_count=0;
	timer_xms_count++;
	
	if (timer_xms_count==key_timer_xms)
	{
		timer_xms_count=0;
		keyInterruptLoop();
	}
	
	setTimerInitValue(0,initValue);
}

void main()
{
	initTimer(0,initValue);
	while (1)
	{
		keyNumber=getFinalKeyNumber();
		if (keyNumber)
		{
			keyNumberToShow=keyNumber;
		}
		ledDriverShow(0,keyNumberToShow);
	}
}

你可能感兴趣的:(嵌入式,嵌入式)