蓝桥杯单片机_蓝桥杯单片机资料 - CSDN
  • 这是一篇介绍蓝桥杯板子方波N555模块的博客 我自己的理解是将定时器0设置为计数模式,定时器1设置为计时模式来定1S的时间,然后定时器0记录的次数就是频率。 怎么设置呢只需要将TMOD设置为TMOD=0x04即可 寄存器...

    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;是用中断的方式计数,自己写中断函数,在中断函数里自己设置变量来计数。

    工作时需要将P34和SIGNAL用调键帽连接在一起,这样P34才会有脉冲。

    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模块跳了过去。 今天之后这个比赛就算过去了,以后不管做什么事情都要要求自己做好最充分的准备,万万不可骄傲。

     

     

    展开全文
  • 蓝桥杯单片机省赛全历年真题已解全历年国赛真题题目(史上最全) 省赛代码全为原创,持续更新中。 (其中部分代码为各处转载) 蓝桥杯单片机比赛加油!与君共勉! 码云:https://gitee.com/quanshiyicunzai/events
  • 2019年3月12日更新 在连续多次单字节读取E22PROM时,不需要延时。 搞完所有模块,开始写真题。 1、题目解读 ...看到这个题,大致要知道用到了哪些模块。...在这里我直接把所有代码给贴上来吧,程序可能写的很麻烦,...

    2019年3月12日更新

    在连续多次单字节读取E22PROM时,不需要延时。


    搞完所有模块,开始写真题。

    1、题目解读

     

    看到这个题,大致要知道用到了哪些模块。

    LED、数码管、AD、E2PROM、独立按键。

     

    2、代码

    在这里我直接把所有代码给贴上来吧,程序可能写的很麻烦,大家参考一下就行了

    也可以在这下载https://download.csdn.net/download/xiaomo_haa/10991680

    main.c

    #include <stc15.h>
    #include "sys.h"
    
    u8 time_led[] = {0x11, 0x04, 0x04, 0x04, 0x04};				//LED流转间隔 *100
    u8 Mode_led = 1;
    u8 pwm = 4;
    
    u8 Mode_Option = 0;			//设置模式位  0无/1流转方式/2流转间隔
    u8 led_lighting = 0;		//LED亮度
    bit flag_led = 0;				//LED工作标志
    bit flag_800ms = 1;
    bit display_pwm = 0;
    
    void main(void)
    {
    	u8 flag_dat = 0;
    	
    	All_init();
    	Timer0Init();
    	Timer1Init();
    	flag_dat = Read_E2PROM(0x00);			//读取E2PROM写入标志位
    	if(flag_dat == 0x11)
    	{
    		time_led[0] = flag_dat;
    		time_led[1] = Read_E2PROM(0x01);
    		time_led[2] = Read_E2PROM(0x02);
    		time_led[3] = Read_E2PROM(0x03);
    		time_led[4] = Read_E2PROM(0x04);
    	}
    	LED_work(0xff);
    	EA = 1;
    	while(1)
    	{
    		Key_press();
    	}
    }
    

    sys.c

    #include "sys.h"
    
    void All_init(void)
    {
    	P2 = (P2 & 0x1f) | 0x80;	//打开Y4C
    	P0 = 0xff;		//关闭LED
    	P2 = (P2 & 0x1f) | 0xc0;	//打开Y6C
    	P0 = 0x00;		//关闭所有数码管
    	P2 = (P2 & 0x1f) | 0xa0;	//打开Y5C
    	P0 = 0x00;		//关闭蜂鸣器和继电器
    	P2 = P2 & 0x1f;						//关闭所有573	
    }
    
    void Timer0Init(void)		//2毫秒@11.0592MHz
    {
    	AUXR |= 0x80;		//定时器时钟1T模式
    	TMOD &= 0xF0;		//设置定时器模式
    	TL0 = 0x9a;		//设置定时初值
    	TH0 = 0xa9;		//设置定时初值
    	TF0 = 0;		//清除TF0标志
    	TR0 = 1;		//定时器0开始计时
    	ET0 = 1;
    }
    
    void Timer0(void) interrupt 1
    {
    	static u16 T0count1 = 0, T0count2 = 0;
    	static u8 index = 0, e2_addr = 0x00;
    	
    	T0count2 ++;
    	
    	if(Mode_Option > 0)			//800ms数码管闪烁
    	{
    		T0count1 ++;
    		if(T0count1 >= 400)
    		{
    			T0count1 = 0;
    			flag_800ms = ~flag_800ms;
    		}
    	}
    	
    	if((T0count2 % 5 == 0) && (T0count2 < 30))	//每10ms时写一次E2PROM
    	{
    		switch(index)
    		{
    			case 0: Write_E2PROM(0x00, time_led[e2_addr]); break;
    			case 1: Write_E2PROM(0x01, time_led[e2_addr]); break;
    			case 2: Write_E2PROM(0x02, time_led[e2_addr]); break;
    			case 3: Write_E2PROM(0x03, time_led[e2_addr]); break;
    			case 4: Write_E2PROM(0x04, time_led[e2_addr]); break;
    			default : break;
    		}
    		index ++;
    		e2_addr ++;
    		
    		if(index >= 5)
    		{
    			index = 0;
    			e2_addr  = 0;
    		}
    	}
    	else if(T0count2 >= 30)		//60ms时读取一次AD值
    	{
    		T0count2 = 0;
    		pwm = Read_AIN(0x03);
    	}
    
    	Key_Scan();
    	Smg_show();
    	Smg_Scan();
    }
    
    void Timer1Init(void)		//100us@11.0592MHz
    {
    	AUXR |= 0x40;		//定时器时钟1T模式
    	TMOD &= 0x0F;		//设置定时器模式
    	TL1 = 0xAE;		//设置定时初值
    	TH1 = 0xFB;		//设置定时初值
    	TF1 = 0;		//清除TF1标志
    	TR1 = 0;		//定时器1暂停计时
    	ET1 = 1;
    }
    
    void Timer1(void) interrupt 3
    {
    	static u8 dat;
    	static u16 T1count1 = 0;
    	static u8 mode_backup = 0;
    	static u8 index = 0, T1count2 = 0;
    	static u8 mode_index = 1;
    	u16 temp = 0;
    	u8 hightime = 0;
    	
    	T1count1 ++;
    	T1count2 ++;
    	
    	T1count2 &= 0x0f;			//最大计数到15
    	
    	temp = 1000 * time_led[mode_index];		//流转时间间隔
    	hightime = pwm * pwm;								//高电平时间
    	
    	if(T1count1 >= temp)
    	{
    		T1count1 = 0;
    		
    		if(mode_index == 1)
    		{
    			if(mode_backup != mode_index)
    			{
    				dat = 0x7f;
    				mode_backup = mode_index;
    			}
    			dat = _crol_(dat, 1);			//模式1
    			if(dat == 0x7f)
    				mode_index ++;
    		}
    		
    		else if(mode_index == 2)
    		{
    			if(mode_backup != mode_index)
    			{
    				dat = 0xfe;
    				mode_backup = mode_index;
    			}
    			dat = _cror_(dat, 1);			//模式2
    			if(dat == 0xfe)
    				mode_index ++;
    		}
    		
    		else if(mode_index == 3)
    		{
    			if(mode_backup != mode_index)
    			{
    				index = 0;
    				mode_backup = mode_index;
    			}
    			switch(index)
    			{
    				case 0: dat = 0x7e; break;		//0111 1110
    				case 1: dat = 0xbd; break;		//1011 1101
    				case 2: dat = 0xdb; break;
    				case 3: dat = 0xe7; break;
    				default : break;
    			}
    			index ++;
    			index &= 0x03;
    			if(dat == 0xe7)
    				mode_index ++;
    		}
    		
    		else if(mode_index == 4)
    		{
    			if(mode_backup != mode_index)
    			{
    				index = 0;
    				mode_backup = mode_index;
    			}
    			switch(index)
    			{
    				case 0: dat = 0xe7; break;		//1110 0111
    				case 1: dat = 0xdb; break;		//1011 1101
    				case 2: dat = 0xbd; break;
    				case 3: dat = 0x7e; break;
    				default : break;
    			}
    			index ++;
    			index &= 0x03;
    			if(dat == 0x7e)
    				mode_index = 1;
    		}
    	}
    	
    	if(T1count2 < hightime)			//PWM
    		LED_work(dat);
    	else
    		LED_work(0xff);
    }
    

    sys.h

    #ifndef _SYS_H_
    #define _SYS_H_
    
    //头文件包含
    #include <stc15.h>
    #include <intrins.h>
    #include "iic.h"
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    typedef unsigned long u32;
    
    //外部变量
    extern u8 time_led[];				//LED流转间隔 *100
    extern u8 Mode_led;
    extern u8 pwm;
    extern u8 Mode_Option;			//设置模式位  0无/1流转方式/2流转间隔
    extern u8 led_lighting;			//LED亮度
    extern bit flag_led;				//LED工作标志
    extern bit flag_800ms;
    extern bit display_pwm;
    
    extern u8 KeySta[];			//键值存储区
    extern u8 Keybackup[];
    
    //管脚定义
    
    //函数声明
    void All_init(void);
    void Timer0Init(void);
    void Timer1Init(void);
    
    void Smg_Scan(void);
    void Smg_show();
    void Smg_show();
    void LED_work(u8 dat);
    
    void Key_Scan(void);
    void Key_drive(u8 key);
    void Key_press(void);
    
    #endif
    
    
    

    key.c

    #include "sys.h"
    
    u8 KeySta[] = {1, 1, 1, 1};			//键值存储区
    u8 Keybackup[] = {1, 1, 1, 1};	//键值备份区
    
    sbit S4 = P3^3;
    sbit S5 = P3^2;
    sbit S6 = P3^1;
    sbit S7 = P3^0;
    
    //按键扫描函数,在定时器中断里调用
    void Key_Scan(void)
    {
    	static u8 Keybuff[] = {0xff, 0xff, 0xff, 0xff};	//按键缓冲区
    	u8 i = 0;
    	
    	Keybuff[0] = (Keybuff[0] << 1) | S7;
    	Keybuff[1] = (Keybuff[1] << 1) | S6;
    	Keybuff[2] = (Keybuff[2] << 1) | S5;
    	Keybuff[3] = (Keybuff[3] << 1) | S4;
    	
    	for(i = 0; i < 4; i++)
    	{
    		if(Keybuff[i] == 0xff)				//按键松开
    			KeySta[i] = 1;
    		else if(Keybuff[i] == 0x00)		//按键按下
    			KeySta[i] = 0;
    		else				//键值不稳定
    		{}
    	}
    }
    
    void Key_drive(u8 key)
    {	
    	if(key == 0)
    	{
    		if(TR1 == 0)
    			TR1 = 1;
    		else
    			TR1 = 0;
    	}
    	
    	else if(key == 1)
    	{
    		Mode_Option ++;
    		if(Mode_Option >= 3)
    			Mode_Option = 0;
    	}
    	
    	else if(key == 2)
    	{
    		if(Mode_Option == 1)
    		{
    			Mode_led ++;
    			if(Mode_led >= 4)				//模式最大4
    				Mode_led = 4;
    		}
    		else if(Mode_Option == 2)
    		{
    			time_led[Mode_led] ++;
    			if(time_led[Mode_led] >= 12)		//最大1200ms
    				time_led[Mode_led] = 12;
    		}
    	}
    	
    	else if(key == 3)
    	{
    		if(Mode_Option == 1)
    		{
    			Mode_led --;
    			if(Mode_led <= 1)				//模式最小1
    				Mode_led = 1;
    		}
    		
    		else if(Mode_Option == 2)
    		{
    			time_led[Mode_led] --;
    			if(time_led[Mode_led] <= 4)		//最小400ms
    				time_led[Mode_led] = 4;
    		}
    	}
    }
    
    //检测按键是否按下,在main函数调用
    void Key_press(void)
    {
    	u8 i;
    	
    	for(i = 0; i < 4; i ++)
    	{
    		if(KeySta[i] != Keybackup[i])
    		{
    			if(Keybackup[i] != 0)		//按键松开时操作
    				Key_drive(i);
    			Keybackup[i] = KeySta[i];
    		}
    	}
    	
    	if(Mode_Option == 0)
    	{
    		if(KeySta[3] == 0)
    			display_pwm = 1;
    		else
    			display_pwm = 0;
    	}
    }
    
    
    

    display.c

    #include "sys.h"
    
    u8 code Nixie[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
    										0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
    										0xff, 0xbf};		//16 17
    u8 Nixiebuff[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    u8 smg1, smg2, smg3, smg4, smg5, smg6, smg7, smg8;
    
    //数码管扫描
    void Smg_Scan(void)
    {
    	static u8 index = 0;
    	
    	P2 = (P2 & 0x1f) | 0xc0;	//打开Y6C
    	P0 = 0x01 << index;
    	
    	P2 = (P2 & 0x1f) | 0xe0;	//打开Y7C
    	P0 = 0xff;
    	P0 = Nixiebuff[index];
    	
    	index ++;
    	index &= 0x07;
    }
    
    //更新数码管值
    void Smg_show()
    {
    	if(Mode_Option == 0)		//不是设置模式不显示
    	{
    		if(display_pwm == 0)
    			smg1 = smg2 = smg3 = smg4 = smg5 = smg6 = smg7 = smg8 = 16;
    		else
    		{
    			smg1 = smg2 = smg3 = smg4 = smg5 = smg6 = 16;
    			smg7 = 17;
    			smg8 = pwm % 10;
    		}
    	}
    	else if(Mode_Option == 1)
    	{
    		if(flag_800ms == 1)		//显示
    		{
    			smg1 = 17;
    			smg2 = Mode_led % 10;
    			smg3 = 17;
    			smg4 = 16;
    			smg5 = time_led[Mode_led] / 10;
    			smg6 = time_led[Mode_led] % 10;
    			smg7 = 0;
    			smg8 = 0;
    		}
    		else				//不显示,实现闪烁
    		{
    			smg1 = 16;
    			smg2 = 16;
    			smg3 = 16;
    			smg4 = 16;
    			smg5 = time_led[Mode_led] / 10;
    			smg6 = time_led[Mode_led] % 10;
    			smg7 = 0;
    			smg8 = 0;
    		}
    	}
    	else if(Mode_Option == 2)
    	{
    		if(flag_800ms == 1)		//显示
    		{
    			smg1 = 17;
    			smg2 = Mode_led % 10;
    			smg3 = 17;
    			smg4 = 16;
    			smg5 = time_led[Mode_led] / 10;
    			smg6 = time_led[Mode_led] % 10;
    			smg7 = 0;
    			smg8 = 0;
    		}
    		else				//不显示,实现闪烁
    		{
    			smg1 = 17;
    			smg2 = Mode_led % 10;
    			smg3 = 17;
    			smg4 = 16;
    			smg5 = 16;
    			smg6 = 16;
    			smg7 = 16;
    			smg8 = 16;
    		}
    	}
    
    	Nixiebuff[0] = Nixie[smg1];
    	Nixiebuff[1] = Nixie[smg2];
    	Nixiebuff[2] = Nixie[smg3];
    	Nixiebuff[3] = Nixie[smg4];
    	Nixiebuff[4] = Nixie[smg5];
    	Nixiebuff[5] = Nixie[smg6];
    	Nixiebuff[6] = Nixie[smg7];
    	Nixiebuff[7] = Nixie[smg8];
    }
    
    
    //LED显示
    void LED_work(u8 dat)
    {
    	P2 = (P2 & 0x1f) | 0x80;
    	P0 = dat;
    	P2 = P2 & 0x1f;
    }
    
    
    

    iic.c

    #include "sys.h"
    
    #define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}    
    
    
    #define SlaveAddrW 0xA0
    #define SlaveAddrR 0xA1
    
    //总线引脚定义
    sbit SDA = P2^1;  /* 数据线 */
    sbit SCL = P2^0;  /* 时钟线 */
    
    
    //总线启动条件
    void IIC_Start(void)
    {
    	SDA = 1;
    	SCL = 1;
    	somenop;
    	SDA = 0;
    	somenop;
    	SCL = 0;	
    }
    
    //总线停止条件
    void IIC_Stop(void)
    {
    	SDA = 0;
    	SCL = 1;
    	somenop;
    	SDA = 1;
    }
    
    //应答位控制
    void IIC_Ack(bit ackbit)
    {
    	if(ackbit) 
    	{	
    		SDA = 0;
    	}
    	else 
    	{
    		SDA = 1;
    	}
    	somenop;
    	SCL = 1;
    	somenop;
    	SCL = 0;
    	SDA = 1; 
    	somenop;
    }
    
    //等待应答
    bit IIC_WaitAck(void)
    {
    	SDA = 1;
    	somenop;
    	SCL = 1;
    	somenop;
    	if(SDA)    
    	{   
    		SCL = 0;
    		IIC_Stop();
    		return 0;
    	}
    	else  
    	{ 
    		SCL = 0;
    		return 1;
    	}
    }
    
    //通过I2C总线发送数据
    void IIC_SendByte(unsigned char byt)
    {
    	unsigned char i;
    	for(i=0;i<8;i++)
    	{   
    		if(byt&0x80) 
    		{	
    			SDA = 1;
    		}
    		else 
    		{
    			SDA = 0;
    		}
    		somenop;
    		SCL = 1;
    		byt <<= 1;
    		somenop;
    		SCL = 0;
    	}
    }
    
    //从I2C总线上接收数据
    unsigned char IIC_RecByte(void)
    {
    	unsigned char da;
    	unsigned char i;
    	
    	for(i=0;i<8;i++)
    	{   
    		SCL = 1;
    		somenop;
    		da <<= 1;
    		if(SDA) 
    		da |= 0x01;
    		SCL = 0;
    		somenop;
    	}
    	return da;
    }
    
    /*******************************************************************************
    * 函数名	:Read_AIN
    * 输入值	:unsigned char chn
    * 返回值	:unsigend char dat
    * 作者		:小默haa
    * 时间		:2019年2月25日
    * 功能描述:读取PCF8591AIN采集数据
    * 备注		:chn为PCF8591的通道
    *******************************************************************************/
    unsigned char Read_AIN(unsigned char chn)
    {
    	unsigned char dat, val, ad_pwm;
    	EA = 0;
    	IIC_Start();						//IIC总线起始信号							
    	IIC_SendByte(0x90);			//PCF8591的写设备地址		
    	IIC_WaitAck();  		    //等待从机应答		
    	IIC_SendByte(chn); 			//写入PCF8591的控制字节		
    	IIC_WaitAck();  				//等待从机应答						
    	IIC_Stop(); 						//IIC总线停止信号					
    	
    	IIC_Start();						//IIC总线起始信号									
    	IIC_SendByte(0x91); 	  //PCF8591的读设备地址		
    	IIC_WaitAck(); 			    //等待从机应答		
    	dat = IIC_RecByte();	  //读取PCF8591通道3的数据 			
    	IIC_Ack(0); 						//产生非应答信号				
    	IIC_Stop(); 						//IIC总线停止信号		
    	val = (dat * 50) / 255;
    	
    	if((val >= 38) && (val <= 50))
    		ad_pwm = 4;
    	else if((val >= 26) && (val < 38))
    		ad_pwm = 3;
    	else if((val >= 14) && (val < 26))
    		ad_pwm = 2;
    	else if((val >= 0) && (val < 14))
    		ad_pwm = 1;
    	
    	EA = 1;
    	
    	return ad_pwm;	
    }
    
    
    void Write_E2PROM(unsigned char add, unsigned char dat)
    {
    	EA = 0;
      IIC_Start();
      IIC_SendByte(0xa0);	//发送器件地址
      IIC_WaitAck();
      IIC_SendByte(add);	//发送操作地址
      IIC_WaitAck();
      IIC_SendByte(dat);	//写一字节
      IIC_WaitAck();
      IIC_Stop();
      somenop;
    	EA = 1;
    }
    
    unsigned char Read_E2PROM(unsigned char add)
    {
      unsigned char d;
    	
    	IIC_Start();
    	IIC_SendByte(0xa0); 	//发送器件地址
    	IIC_WaitAck();
    	IIC_SendByte(add);		//发送要操作的地址
    	IIC_WaitAck();
    	IIC_Stop();
    	
    	IIC_Start();
    	IIC_SendByte(0xa1);		//发送读操作
    	IIC_WaitAck();
    	d = IIC_RecByte();	//读一字节
    	IIC_Ack(0);
    	IIC_Stop();
    	return d;
    }
    

    iic.h

    #ifndef _IIC_H
    #define _IIC_H
    
    //函数声明
    void IIC_Start(void); 
    void IIC_Stop(void);  
    void IIC_Ack(bit ackbit); 
    void IIC_SendByte(unsigned char byt); 
    bit IIC_WaitAck(void);  
    unsigned char IIC_RecByte(void); 
    unsigned char Read_AIN(unsigned char chn);
    void Write_E2PROM(unsigned char add, unsigned char dat);
    unsigned char Read_E2PROM(unsigned char add);
    
    #endif

     

     

     

     

     

     

    展开全文
  • 翻了下以前做过的一些项目和比赛,发现了之前准备比赛的一些注意事项和心得,分享给大家希望大家能够避免错误拿高分。 适当的延时很重要,可以解决一些不正常现象 ds1302读取的时间是BCD码,操作时间时换成10进制...

    翻了下以前做过的一些项目和比赛,发现了之前准备比赛的一些注意事项和心得,分享给大家希望大家能够避免错误拿高分。

                    适当的延时很重要,可以解决一些不正常现象
            ds1302读取的时间是BCD码,操作时间时换成10进制操作例:(shi / 16) * 10 + shi % 16
    **********************************使用串口时*********************
                每次只接受和发送一个字符,字符用单引号 ‘’ 字符串用双引号“”
                if(SBUF == ‘a’)而不是if(SBUF == "a")

    **1.总中断EA定时器中断ET0和串行通信中断ES记得开

    **2.52单片机程序不可以直接使用P32的写法,15单片机可以,52使用前需要先进行定义P32=P3^2

    *3.main函数下面不能忘记写while(1){}

    4.简单初始化函数必须写在while1(){}上面,不能写在里面

    5.DS18B20当需要执行温度测量和ad转换的时候,总线控制器必须发出[44h]命令

    6.写iic的读字节函数不用这行程序:temp=0.39*temp;
       iicwrite()函数里面写(要存的地址,要存的值)或者直接把add换成地址

    7.pwm的精度不同表现在占空比上,比如8位pwm占空比最小只能是1:256,尔10位pwm占空比可以使1:1024.

    8.定时器溢出时间=周期/占空比

    9.定时器不好用的时候可以用ds1302代替

    10.ds1302和ds18b20部分子程序名相同,注意!!

    11.串口通信发送或接受一个字节就进入中断,TI或RI = 1;使用串口助手时一定要选对波特率和文本模式或HEX模式

    ***12.修改时钟时,将BCD转换成10进制在进行加减,时到24变成0,分和秒到60变成0,修改时分秒显示时 /10  不是/16

    13.超声波用的TR1,TF1,TH1,TL1.用的是定时器1,串口通信的波特率在模式1下与定时器1的溢出率有关

    14.写数据到EEPROM时,地址最好0x00到0x56,最好间隔一个地址存多个数据,存入的数据最大为255,超过可把数据分开存储

    15.读取时钟时先关中断在读,写EEPROM和读iic和温度时,加延时,注意++i和i++的区别使用

    16.iic返回数都是unsigned char,adc_val / 255.0f * 5.ds18b20返回数是float,先读low,再读high函数里temp定义为int,temp*0.0625。读函数都要初始化两次,超声波distance = t * 0.017

    17.读时间和adc时关总中断再读取

    18.当矩阵键盘和串口同时使用时,串口不要用串口1;P30端口会相互影响;

    19.定义数组时预设内存比实际使用大一点
    速查表:

    char -128 ~ +127 (1 Byte)
    short -32767 ~ + 32768 (2 Bytes)
    unsigned short 0 ~ 65536 (2 Bytes)
    int -2147483648 ~ +2147483647 (4 Bytes)
    unsigned int 0 ~ 4294967295 (4 Bytes)
    long == int
    long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes)
    double 1.7 * 10^308 (8 Bytes)

    unsigned int 0~4294967295 
    long long的最大值:9223372036854775807
    long long的最小值:-9223372036854775808
    unsigned long long的最大值:1844674407370955161

    __int64的最大值:9223372036854775807
    __int64的最小值:-9223372036854775808
    unsigned __int64的最大值:18446744073709551615

    展开全文
  • 我刚开始学完 51单片机的时候,听师兄们说有蓝桥杯这个比赛,所以在寒假开始准备,刚开始很懵逼,拿到板子后都不知道怎么用,怎么入手,当时我也是走了波坑才懂的 所以这里我的建议是上blibli学习小蜜蜂的入门编程...

    相信有很多小伙伴,在没打蓝桥杯的时候会担心说自己不能拿到蓝桥杯的省赛一等奖,而且会疑惑说蓝桥杯省赛准备多久可以拿到省赛一等奖。所以在这里我做以下分析,和攻略,希望大家可以用到。

    我刚开始学完 51单片机的时候,听师兄们说有蓝桥杯这个比赛,所以在寒假开始准备,刚开始很懵逼,拿到板子后都不知道怎么用,怎么入手,当时我也是走了波坑才懂的 所以这里我的建议是上blibli学习小蜜蜂的入门编程(关键词搜索蓝桥杯就可以),

    在这里的个人建议是基础不好的人仔细看完小蜜蜂上的代码(基础好的或者说学过单片机的可以快速掠过看视频这个环节。),然后完成完视频上的题目,看完之后,把板子上的 超声波,ds1302,温度模块等,单独打一遍后再去做往届省赛题目,做完省赛题目还有空余时间的可以去刷一下数电模电单片机等要选择题的大纲。

    1.模电主要会考 运放 , 信号 , 以及一些二极管的一些基本特性。
    2.数电主要会考 运算逻辑式等等
    3.单片机考的知识会比较多,这里就不一一列举了。

    然后告诉大家一定的是客观题真的很重要,因为第十届的时候,我一个朋友程序题没怎么做好,反而客观题全对,最后也拿到了去北京的通行证省一,所以大家请不要小看客观题。

    然后涮程序题的时候 有几个坑提前跟小伙伴们说一下,就是 比赛方给的驱动是按照51单片机来写的 而蓝桥杯那块板子的速度是51单片机的8-12倍,所以iic驱动里面的

    1.NOP() 要加到32个到40个 。
    2.,ds18b20的延时时间要乘12 。
    3.ds1302的时钟模块读完 要加 SCL = 1 ;SD = 1 ; SD = 0;才可以,要不然会乱码的。

    然后在此先祝贺大家能旗开得胜,拿到去北京比赛的门票。
    如果还有什么疑问的话,可以加我qq 1213936954 帮你们解答问题,或者提供往届题目以及代码,不免费的哦,看你的问题收钱。

    展开全文
  • 2017年蓝桥杯单片机比赛经验分享 我的蓝桥杯单片机获得江苏省二等奖,大约是江苏省130名(江苏省一等奖103个)。比赛失利的主要原因还是当时比较的单纯,只知道一味的死练。 这也是我感觉死的最莫名其妙的比赛,抱...
  • 这是蓝桥杯官方在单片机比赛时提供的官方资料包,里面包含比赛会用到的相关底层驱动代码,单片机开发板的驱动程序,以及一些辅助开发软件和技术文档,建议有需要的伙伴在比赛前先下载该资料包,提前熟悉官方提供的...
  • 往届蓝桥杯省赛题目答案, 第三届:温度监控器。 第四届:自动售水机。 第五届:模拟智能灌溉系统。 第六届:简易温度采集与控制装置。 第七届:模拟风扇控制系统。 第八届:基于单片机的电子钟。
  • 通过单片机控制8个LED指示灯按照特定的顺序(工作模式)亮灭;指示灯的流转间隔可通过按键调整,亮度可由电位器RB2进行控制;各工作模式的流转间隔时间需在E2PROM中保存,并可在硬件重新上电后,自动载入。 2-设计...
  • 3.蓝桥杯单片机设计与开发历年真题3.蓝桥杯单片机设计与开发历年真题3.蓝桥杯单片机设计与开发历年真题
  • 这是蓝桥杯单片机设计与开发组历届真题和具体代码,有自动售水机、温度监控器、温度采集与控制、模拟智能灌溉等等,全部代码依据蓝桥杯板子写的,下载进去就能用,对于要参加蓝桥杯单片机设计与开发的同学复习非常...
  • 蓝桥杯 单片机设计 历年决赛真题及答案 在学习蓝桥杯编程时很好的参考,要沉下心分析很精华!
  • 数码管显示几乎是每次蓝桥杯单片机设计与开发组竞赛的必考部分,相对于使用LCD1602作为显示设备,使用数码管来显示能够更好的考察参赛选手的单片机基本功,因为CT107D开发平台的设计使得数码管的显示不仅牵扯到...
  • 为推动软件开发技术的发展,促进软件专业技术人才培养,向软件行业输送具有创新能力和实践能力的高端人才,提升高校毕业生的就业竞争力,全面推动行业发展及人才...本程序是第七届蓝桥杯单片机设计与开发省赛一等奖程序
  • 蓝桥杯单片机设计与开发模拟试题客观题,包括数字电子技术、模拟电子技术、单片机开发与设计等相关基础知识
  • 蓝桥杯单片机第三届至第八届的代码和题目,这都是我当初练习时写的,有需要的朋友可以下载来看看,不过最好是自己写完或者遇到实在解决不了的问题时才打开来看。
  • 搜集了近几年比较有练习价值的蓝桥杯单片机设计与开发类的省赛和国赛试题,和蓝桥杯所用芯片的技术文档,大四老学长,快毕业了,分享给想要参加蓝桥杯的兄弟们,
  • 第十届蓝桥杯 单片机设计与开发项目省赛-程序设计试题
  • 蓝桥杯单片机proteus仿真,模块基本集全,包含独立按键和矩阵按键,LED,数码管,继电器和蜂鸣器,与实际电路完全相符,本仿真适用于入门学习,打开需要软件版本大于Proteus 8
  • 最近开始准备九月份的蓝桥杯单片机比赛, 买了一块开发板开始进行学习。以前有学过51单片机,相比于CT107D单片机竞赛板V20,51单片机的操作的确要简单许多,但原理都一样,没什么变化,以前学51的时候没怎么做笔记,...
1 2 3 4 5 ... 20
收藏数 1,516
精华内容 606
关键字:

蓝桥杯单片机