蓝桥杯第十届单片机总结

https://blog.csdn.net/qq_37429313/article/details/86929724

这是一篇介绍蓝桥杯板子方波N555模块的博客

我自己的理解是将定时器0设置为计数模式,定时器1设置为计时模式来定1S的时间,然后定时器0记录的次数就是频率。

怎么设置呢只需要将TMOD设置为TMOD=0x04即可

寄存器TMOD高四位是设置定时器1工作方式,低四位是设置定时器0工作方式

C/T位是设置C/T==0是计时模式,C/T==1是计数模式,所以TMOD=0x04;

之后是设置TH0和TL0位,此时可以设置为 TH0=TL0=0X00;也可以设置为 TH0=TL0=0XFF;

设置为TH0=TL0=0x00;就是用这两个记录次数。最后计算 num=(TH0<<8)+TL0;num就是1S内的次数

设置为TH0=TL0=0XFF;是用中断的方式计数,自己写中断函数,在中断函数里自己设置变量来计数。

TH0=TL0=0x00;主要代码如下:

  1. void Timer0Init(void)       
  2. {
  3.     AUXR |= 0x80;       
  4.     TMOD = 0x04;    //方式1 16位模式; 
  5.     TL0 = 0x00;        //设置定时初值
  6.     TH0 = 0x00;        //设置定时初值
  7.     TF0 = 0;        //清除TF0标志 
  8.     TR0 = 1;        //定时器0开始计时  
  9. }
  10. void Timer1Init(void)        //5毫秒@11.0592MHz
  11. {
  12.     AUXR |= 0x40;        //定时器时钟1T模式
  13.     TMOD &= 0x0F;        //设置定时器模式
  14.     TL1 = 0x00;        //设置定时初值
  15.     TH1 = 0x28;        //设置定时初值
  16.     TF1 = 0;        //清除TF1标志
  17.     TR1 = 1;        //定时器1开始计时
  18.     EA=1;
  19.     ET1=1;
  20. }
  21. void main()
  22. {
  23.      while(1)
  24.      {
  25.        if(T_flag)    //频率采集
  26.      { 
  27.           T_flag=0;
  28.           num=(TH0<<8)+TL0;
  29.           TL0=0x00;
  30.           TH0=0x00;
  31.           TF0=0;
  32.           TR0=1;
  33.        }
  34.     } 
  35. }
  36. void  time1() interrupt 3
  37. {
  38.     static  uint T_cont=0;
  39.     T_cont++;
  40.     if(T_cont==200)
  41.     {     T_cont=0;
  42.          TF0 = 0;        
  43.          TR0 = 0;
  44.          T_flag=1;
  45.     }
  46. }

 TH0=TL0=0xff;主要代码如下:

  1. void Timer0() interrupt 1
  2. {
  3.     sqre_count++;  //计数
  4. }
  5. while(1)
  6.     {
  7.         if(count_flag)
  8.         {
  9.             count_flag = 0;
  10.             sqre = sqre_count;   //sqre就是频率
  11.             sqre_count = 0;
  12.             TR0 = 1;
  13.             TR1 = 1;
  14.         }
  15. }

 上面那么多介绍的都N555下面介绍第十届的编程试题这里只放了框图,试题的话大家都能找到;

我感觉这一届的试题比第九届的简单多了,按键部分也都是简单的逻辑但是因为没看方波所以直接就丢掉了一半的分数。具体实现的思路每个人都不一样,我就直接贴代码了;

主函数

#include<stc15F2K60S2.h>
#include<intrins.h>
#include<iic.h>
#define uchar unsigned char
#define uint  unsigned int
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc1,0x8e};
uchar yi,er,san,si,wu,liu,qi,ba;
bit T_flag,set_flag,a_flag,L_flag,M_flag;
//T_flag 1S时间的标记 set_flag 电压和频率
//a_flag 电压固定 L_flag灯开关,M_flag数码管开关
uchar AD(uchar add);
void display31(uchar dat1,uchar dat2);
void keyscan();
void allinit();
void keyscan();
void delayms(uint ms);
void display1(uchar dat1,uchar dat2);
void display2(uchar dat1,uchar dat2);
void display3(uchar dat1,uchar dat2);
void display4(uchar dat1,uchar dat2);

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD = 0x05;		
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x00;		//设置定时初值
	TF0 = 0;		//清除TF0标志 
	TR0 = 1;		//定时器0开始计时  
}
void Timer1Init(void)		//5毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x00;		//设置定时初值
	TH1 = 0x28;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;
	ET1=1;
}

void main()
{ 
  uint num,ad;
  allinit();
  Timer0Init();
  Timer1Init();
  while(1)
  {  
	 ad=AD(0x03)*1.961; //ad采集 255扩大到500
   keyscan();    //按键扫描
	 if(T_flag)    //频率采集
	 { 
	   T_flag=0;
	   num=(TH0<<8)+TL0;
	   TL0=0x00;
	   TH0=0x00;
	   TF0=0;
	   TR0=1;
	 }
	 /*****电压*******************/
	 if(set_flag==0)
	 {
		  yi=12;er=11;san=11;si=11;wu=11;
	    liu=ad/100;qi=ad/10%10;ba=ad%10;
		  if(a_flag==0)  //DAC固定2V
			{
			  yi=12;er=11;san=11;si=11;wu=11;
	      liu=2;qi=0;ba=0;
			}
			if(L_flag==0)  //灯亮
			{
			  if((ad<150) || (ad>=250 && ad<350)) 
				{ 
					if(a_flag==0)//固定
					{
					  P2=0x80;P0=0xfe;
					}
					else if(a_flag==1)
					{
					  P2=0x80;P0=0xee;
					}
				}
				else 
				{ 
					if(a_flag==0)//固定
				  {
						P2=0x80;P0=0xfe;
				  }
					else
					{
					 P2=0x80;P0=0xea;
					}
				}
			}
			else
	    {
				  P2=0x80;P0=0xff;
			}
	 }
	 /*******频率**********************/
	 else 
	 {
	    yi=13;er=11;san=11;si=num/10000;wu=num/1000%10;
		  liu=num/100%10;qi=num/10%10;ba=num%10;
			if(si==0) 
			{
			  si=11;
				if(wu==0)
				{
					wu=11;
				  if(liu==0)  //数码管
					{
					  liu=11;
					}
				}
			}
		  if(L_flag==0)  
			{
			  if((num<1000)||(num>=5000&&num<10000))
				{
				  P2=0x80;P0=0xfd;
				}
				else
				{
				  P2=0x80;P0=0xf5;
				}
			} 
      else
			{
			    P2=0x80;P0=0xff;
			}				
	 }
	 if(M_flag)//关闭所有数码管
	 {
	    yi=11;er=11;san=11;si=11;wu=11;
		  liu=11;qi=11;ba=11;
	 }
	 display1(yi,er);
	 display2(san,si);
	 if(set_flag==0&& M_flag==0) 
		 display3(wu,liu);  //带小数点的
	 else if(set_flag==1)
		 display31(wu,liu); //不带小数点的
	 display4(qi,ba);
	
  }
}
/****按键****************/
void keyscan()
{
  if(P33==0)
  {
    delayms(10);
	  if(P33==0)
	  {
	    set_flag = ~set_flag;
	  }
	  while(!P33);
  }
	if(P32==0)
  {
    delayms(10);
	  if(P32==0)
	  {
	    a_flag = ~a_flag;
	  }
	  while(!P32);
  }
	if(P31==0)
  {
    delayms(10);
	  if(P31==0)
	  {
	    L_flag = ~L_flag;
	  }
	  while(!P31);
  }
	if(P30==0)
  {
    delayms(10);
	  if(P30==0)
	  {
	    M_flag = ~M_flag;
	  }
	  while(!P30);
  }
}
//计时
void  time1() interrupt 3
{
    static  uint T_cont=0;
	T_cont++;
	if(T_cont==200)
	{	 T_cont=0;
		 TF0 = 0;		
		 TR0 = 0;
		 T_flag=1;
	}
}
/***********AD***************/
uchar AD(uchar add)
{
   uchar temp;
   IIC_Start();
   IIC_SendByte(0x90);
   IIC_WaitAck();
   IIC_SendByte(add);
   IIC_WaitAck();
   IIC_Stop();
   
   IIC_Start();
   IIC_SendByte(0x91);
   IIC_WaitAck();
   temp=IIC_RecByte();
   IIC_Stop();
   return temp;
}
/******初始化*********************/
void allinit()
{
  P2=0xa0;P0=0x00;
  P2=0x80;P0=0xff;
  P2=0xc0;P0=0xff;
  P2=0xff;P0=0xff;
}

void display1(uchar dat1,uchar dat2)
{
  P2=0xc0;P0=0x01;
  P2=0xff;P0=tab[dat1];
  delayms(1);
  P2=0xc0;P0=0x02;
  P2=0xff;P0=tab[dat2];
  delayms(1);
}
void display2(uchar dat1,uchar dat2)
{
  P2=0xc0;P0=0x04;
  P2=0xff;P0=tab[dat1];
  delayms(1);
  P2=0xc0;P0=0x08;
  P2=0xff;P0=tab[dat2];
  delayms(1);
}
void display3(uchar dat1,uchar dat2)
{
  P2=0xc0;P0=0x10;
  P2=0xff;P0=tab[dat1];
  delayms(1);
  P2=0xc0;P0=0x20;
  P2=0xff;P0=tab[dat2]&0x7f;
  delayms(1);
}
void display31(uchar dat1,uchar dat2)
{
  P2=0xc0;P0=0x10;
  P2=0xff;P0=tab[dat1];
  delayms(1);
  P2=0xc0;P0=0x20;
  P2=0xff;P0=tab[dat2];
  delayms(1);
}
void display4(uchar dat1,uchar dat2)
{
  P2=0xc0;P0=0x40;
  P2=0xff;P0=tab[dat1];
  delayms(1);
  P2=0xc0;P0=0x80;
  P2=0xff;P0=tab[dat2];
  delayms(1);
  P2=0xc0;P0=0xff;
  P2=0xff;P0=0xff;
}
void delayms(uint ms)
{
   uint i,j;
   for(i=0;i<ms;i++)
	for(j=0;j<855;j++);
}

IIC 驱动:

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include<stc15F2K60S2.h>
#include "intrins.h"

#define DELAY_TIME 20

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
//void IIC_SendAck(bit ackbit)
//{
//    SCL = 0;
//    SDA = ackbit;  					// 0:应答,1:非应答
//    IIC_Delay(DELAY_TIME);
//    SCL = 1;
//    IIC_Delay(DELAY_TIME);
//    SCL = 0; 
//    SDA = 1;
//    IIC_Delay(DELAY_TIME);
//}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

自己给自己的话,这次比赛虽然不是什么大比赛,但也学会了很多,从过完年回来开始准备,2个星期把之前的省赛题做完,后边感觉自己会的挺多的了,后边就没看省赛之前没出过的模块,当时还做了官网模拟题就是把N555模块跳了过去。 今天之后这个比赛就算过去了,以后不管做什么事情都要要求自己做好最充分的准备,万万不可骄傲。

猜你喜欢

转载自blog.csdn.net/TANG3223/article/details/88809392