蓝桥杯单片机组第十届省赛心得(很干)

题目涉及考点总结

一,按键

采用状态扫描来编写,由于J5配置为BTN独立按键模式,所以代码有所更改,变得简单。
以前:

//-----------------------------------------------//状态扫描矩阵按键
#define key_state_0  0  
#define key_state_1  1
#define key_state_2  2 
   
unsigned char read_KBD(void) 
{ 
 static char key_state = 0; 
 unsigned char key_return=0, key_press;
 unsigned char key1,key2;
	P44=1;P42=1;P35=1;P34=1;P33=0;P32=0;P31=0;P30=0;
	if(P44==0)  key1=0x70;
	else if(P42==0)  key1=0xb0;
	else if(P35==0)  key1=0xd0;
	else if(P34==0)  key1=0xe0;
	else key1=0xf0;
	P44=0;P42=0;P35=0;P34=0;P33=1;P32=1;P31=1;P30=1;
	if(P33==0)  key2=0x07;
	else if(P32==0)  key2=0x0b;
	else if(P31==0)  key2=0x0d;
	else if(P30==0)  key2=0x0e;
	else key2=0x0f;
	key_press =key1|key2;

 switch (key_state) 
{ 	
   case key_state_0:    
   if (key_press!=0xff) key_state = key_state_1; 
   break; 
	 
   case key_state_1:     
   if (key_press !=0xff) 
   { 
		  if(key_press==0x77) key_return = 4;   
		  if(key_press==0x7b) key_return = 5;
		  if(key_press==0x7d) key_return = 6;
		  if(key_press==0x7e) key_return = 7;
		 
		  if(key_press==0xb7) key_return = 8;
		 	if(key_press==0xbb) key_return = 9;
		 	if(key_press==0xbd) key_return = 10;
		 	if(key_press==0xbe) key_return = 11;
		 
		 	if(key_press==0xd7) key_return = 12;
		 	if(key_press==0xdb) key_return = 13;
		 	if(key_press==0xdd) key_return = 14;
		 	if(key_press==0xde) key_return = 15;
		 
		 	if(key_press==0xe7) key_return = 16;
		 	if(key_press==0xeb) key_return = 17;
		 	if(key_press==0xed) key_return = 18;
		 	if(key_press==0xee) key_return = 19;
			key_state = key_state_2;  
   } 
   else 
			key_state = key_state_0;  
   break;  
   case key_state_2: 
   if (key_press==0xff) key_state = key_state_0; 
   break; 
} 
return key_return; 
}      

现在:

//-----------------------------------------------//状态扫描矩阵按键
#define key_state_0  0  
#define key_state_1  1 
#define key_state_2  2 
   
unsigned char read_KBD(void) 
{ 
 static char key_state = 0; 
 unsigned char key_return=0, key_press;
	P33=1;P32=1;P31=1;P30=1;
	if(P33==0)  key_press=0x07;
	else if(P32==0)  key_press=0x0b;
	else if(P31==0)  key_press=0x0d;
	else if(P30==0)  key_press=0x0e;
	else key_press=0x0f;

 switch (key_state) 
{ 	
   case key_state_0:    
   if (key_press!=0x0f) key_state = key_state_1; 
   break; 
	 
   case key_state_1:     
   if (key_press !=0x0f) 
   { 
		  if(key_press==0x07) key_return = 4;   
		  if(key_press==0x0b) key_return = 5;
		  if(key_press==0x0d) key_return = 6;
		  if(key_press==0x0e) key_return = 7;
			key_state = key_state_2;  
   } 
   else 
			key_state = key_state_0;  
   break;  
   case key_state_2: 
   if (key_press==0x0f) key_state = key_state_0; 
   break; 
} 
return key_return; 
}    

二,NE555脉冲输入

1)通过调节滑动变阻器Rb3改变脉冲输出频率。
2)其信号输出接到P34引脚,并将定时器0设置成计数模式,对来自P34的外部脉冲进行计数。

三,PCF8591 ADC与DAC

我写的关于PCF8591的ADC和DAC

四,定时器初始化

定时器0用来计数,定时器1用来定时。

void TimerInit(void)		//1ms 晶振频率12Mhz
{
  AUXR |= 0x40;		//定时器1时钟1T模式  不分频
	TMOD =0x04;		//设置定时器模式    定时器0计数,定时器1定时   都是16位自动重装 
	TL1 = 0x20;		//设置定时初值      计数值达到65536时,自动重装载TH0,TL0的值
	TH1 = 0xD1;		//设置定时初值
	TL0=0X00;//计数器清零
	TH0=0X00;
	TF1 = 0;		//清除TF1溢出标志
	TR1 = 1;		//定时器1开始计时
	TF0 = 0;		//清除TF0溢出标志
	TR0 = 1;		//启动计数器0
	ET0=1;//溢出中断允许位
  ET1=1;//溢出中断允许位
  EA=1;	//总开关
}

五,中断服务函数

void tm1_isr() interrupt 3     //中断号3的中断服务函数  中断号1:定时器0中断   中断号3:定时器1中断

1)每500ms统计一次定时器(计数器)0的计数值,因为是16位自动重装载,足够大,不会出现溢出重装。

if (count_t == 500)    
{
	count_t=0;
	TR0=0;   // 关闭定时器0,关闭了才能同时修改当前状态TH0,TL0和重装载TH0,TL0
	DATA_f=(TH0*256+TL0)*2;// 脉冲频率=1s的脉冲次数  所以结果 *2
	TH0=0;TL0=0;  //重置TH0,TL0
	TR0=1;  //打开定时器0
}		

2)每200ms进行一次模拟电压转换

if(count_ad==200)
{
	count_ad=0;
	ad_flag=1;
}
if(ad_flag==1)      //200MS  放在main.c里面
{
	ad_flag=0;
	EA=0;
	ad_data=read_pcf8591();
	voltage=(u16)(ad_data*5/255.0f*100+0.5);//放大100倍的voltage
	EA=1;
}

六,LED

因为涉及到不同的led的亮灭,所以我定义了一个变量来操作。

u8 led=0xff;

比如:

 P0=0XFF;P2=0X80;P0=led;P2=0X00;  //  开启573锁存器之前把P0置为0xff   当不使用的led会隐隐亮,建议加上第一个代码
 led&=0xfe;led|=0x02;  //我们操作led即可  
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shine锐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值