“精彩呈现:第一场客观题代码竞赛!13届蓝桥杯单片机省赛”

客观题

第十三届省赛客观题

讲解

  1. 通过查找芯片手册得知IAP15F2K61S2单片机的外设中能够作为UART1的波特率发生器的有定时器1、定时器2。

  1. 压电效应就是指:某些电介质在沿一定方向上受到外力的作用而变形时,其内部会产生极化现象,同时在它的两个相对表面上出现正负相反的电荷。当外力去掉后,它又会恢复到不带电的状态,这种现象称为正压电效应。

光电效应是物理学中一个重要而神奇的现象,在光的照射下,某些物质内部的电子会被光子激发出来而 形成电流,即光生电。

热电效应是当受热物体中的电子(空穴),因随着温度梯度由高温区往低温区移动时,所产生电流或电荷堆积的一种现象。

霍尔效应: 当电流垂直于外磁场通过半导体时,载流子发生偏转,垂直于电流和磁场的方向会产生一附加电场,从而在半导体的两端产生电势差,这一现象就是霍尔效应。

  1.   三态门:是指逻辑门的输出除有高、低电平两种状态外,还有第三种状态——高阻状态的门电路,高阻态相当于隔断状态。三态门都有一个EN控制使能端,来控制门电路的通断。

  1. 从电流的流向来看,很显然A、B、C点的电流都是流向Y。因此,我们就能够推出Y=A+B+C。

  1. A选项是常用的状态翻转的方法。B选项,我们是不是可以看成P42==0呢?C选项可以转换为P4 = P4^0x100;在异或运算中同1或者同0则是0,否则就是1;因此,C选项就是正确的。D选项可以转换为P4=P4&0x100,一个数与上1结果就是它本身。

  1. 差分传输是一种信号传输的技术,区别于传统的一根信号线一根地线的做法,差分传输在这两根线上都传输信号,这两个信号的振幅相同,相位相反。在这两根线上的传输的信号就是差分信号。信号接收端比较这两个电压的差值来判断发送端发送的逻辑状态。在电路板上,差分走线必须是等长、等宽、紧密靠近、且在同一层面的两根线。RS232的传输方式是异步传输;而单总线协议1-wrie,只使用一根数据线,很显然不是正确答案。

  1. data:访问可直接寻址的片内存储器,即内部RAM,即我们常说的DATA区或数据段,在整个RAM块中只占前128字节(Ox00~Ox7f),因为它采用直接寻址方式,对变量访问最快,通常我们把使用比较频繁的变量或局部变量存储在DATA段中,但是它的空间有限(128)。

idata:使用寄存器作为指针来进行间接寻址,一般常用来存放比较频繁的变量。

xdata:访问外部数据存储器,即外部RAM,大小64K(Ox0000~Oxiff),16位地址寻址,称作外部数据区简称XDATA 区,访问XDATA须采用间接寻址。

pdata:访问当前页面内的外部RAM中的XDATA,按页访问,每一页256字节。PDATA段只有256个字节,对PDATA和XDATA的操作是相似的,但是对PDATA段寻址比对XDATA段寻址要快,因为对PDATA段寻址只需要装入8位地址,而对XDATA段寻址需装入16位地址,所以尽量把外部数据存储在PDATA段中。

  1. 掌握好虚短与续断就能够很好的解除该题的答案了。虚短:理解成短路,运放处于线性状态时,把两输入端视为等电位,即运放正输入端和负输入端的电压相等;虚断:理解成断路,运放处于线性状态时,把两输入端视为开路,即流入正负输入端的电流为零;总结一句话:虚短用来得到电压相等;虚断用来得到电流为0。

  1.    全双工通信又称为双向同时通信,即通信的双方可以同时发送和接收信息的信息交互方式。它要求发射设备与接收设备有独立的接收与发射的能力即可。

maim函数

#include <STC15F2K60S2.H>
#include <intrins.h>

#include "ds1302.h"
#include "onewire.h"

#define uc unsigned char
#define ui unsigned int

sbit H1=P3^0;
sbit H2=P3^1;
sbit H3=P3^2;
sbit H4=P3^3;
sbit L1=P3^4;
sbit L2=P3^5;
sbit L3=P4^2;
sbit L4=P4^4;

uc tac[7]={0x50,0x59,0x23,0x16,0x03,0x04,0x23};//秒 分 时 日 月 星期 年 

#define COM(X)  {P0 = X; P2 = (P2 & 0x1F | 0xC0);  P2 &= 0x1F;}
#define SEG(X)  {P0 = X; P2 = (P2 & 0x1F | 0xE0);  P2 &= 0x1F;}
#define BUZ(X)  {P0 = X; P2 = (P2 & 0x1F | 0xA0);  P2 &= 0x1F;}
#define LED(X)  {P0 = X; P2 = (P2 & 0x1F | 0x80);  P2 &= 0x1F;}

uc code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc6,0x8e,0x8C,0xC1,0x86,0xbf,0x88};//0-9,C,F,P,U,E,-
//10-C
//11-F
//12-P
//13-U
//14-E
//15--

 uc jm=0;
xdata ui temp;
xdata ui count;
 uc m=1; 
 uc wd_kz=26;
 uc zt;
//函数的申明
void jm_xs();
uc GetButtonValue_1(void);
/****************led,继电器,蜂鸣器的共用体*************************/
typedef union{
  uc led_data;
  struct{
       uc led1:1;
       uc led2:1;
       uc led3:1;
       uc led4:1;
       uc led5:1;
       uc led6:1;
       uc led7:1;
       uc led8:1;
        }led_one;
}led_tow;
static xdata led_tow s_led;
typedef union{
  uc other_data;
  struct{
       
       uc other1:4;
       uc other_jdq:1;
       uc other2:1;
       uc other_fmq:1;
        }other_one;
}other_tow;
static xdata other_tow s_other;
/****************led灯独立控制**************/
void led_dlkz(uc led_x,uc no_of)
{
  switch(led_x)
  {
  case 1:s_led.led_one.led1=(no_of==1)?1:0;break;
  case 2:s_led.led_one.led2=(no_of==1)?1:0;break;
  case 3:s_led.led_one.led3=(no_of==1)?1:0;break;
  case 4:s_led.led_one.led4=(no_of==1)?1:0;break;
  case 5:s_led.led_one.led5=(no_of==1)?1:0;break;
  case 6:s_led.led_one.led6=(no_of==1)?1:0;break;
  case 7:s_led.led_one.led7=(no_of==1)?1:0;break;
  case 8:s_led.led_one.led8=(no_of==1)?1:0;break;
  }
  LED(s_led.led_data);
}
/***************继电器开关控制**********************/
void jdq(uc no_of)
{
 s_other.other_one.other_jdq=(no_of==1)?1:0;
   BUZ(s_other.other_data);
}
/*****************蜂鸣器开关控制*****************/
void fmq(uc no_of)
{
 s_other.other_one.other_fmq=(no_of==1)?1:0;
 BUZ(s_other.other_data);
}
/******************************LED灯闪烁函数******************************/
void Timer0Init(void)        //500微秒@12.000MHz
{
    AUXR |= 0x80;        //定时器时钟1T模式
    TMOD &= 0xF0;        //设置定时器模式
    TL0 = 0x90;        //设置定时初值
    TH0 = 0xE8;        //设置定时初值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    EA  = 1;
    ET0 = 1;
}
void tim0()interrupt 1
{
   count++;
 if(count==100)
 {m++;
 if(m>2)
 { m=1; }
 count=0;
 }
}
void LED_SS()
{
 switch(m)
 {
  case 1:led_dlkz(3,0);break;
  case 2:led_dlkz(3,1);break;
 }
}
/*************************工作指示灯函数***********************************/
void LED_ZS()
{
   if(zt==0)
   {led_dlkz(2,0);}
   else
   {led_dlkz(2,1);}
}
/***************延时函数区*************/
void Delay100us()        //用于数码管显示
{
    unsigned char i, j;

    i = 2;
    j = 39;
    do
    {
        while (--j);
    } while (--i);
}
void Delay750ms()        //用于消除开机85C
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 35;
    j = 51;
    k = 182;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}
void Delay1ms()        //用于按键消抖
{
    unsigned char i, j;

    i = 12;
    j = 169;
    do
    {
        while (--j);
    } while (--i);
}
/***************数码管显示函数******************/
void OutputSMG(uc gqb,uc yxl)
{
 uc i;
 for(i=0;i<8;i++)
 {
 SEG(0xff);
 COM(0x01<<gqb);
 SEG(yxl);
 Delay100us();
 }
 COM(0x00);
 SEG(0x00);
}
/*********************************时钟显示分秒函数************************/
void smg_FM()
{
  uc F,M;
  readtime(tac);
  F=(tac[1]>>4)*10+(tac[1]&0X0F);
  M=(tac[0]>>4)*10+(tac[0]&0X0F);
  OutputSMG(0,tab[13]);
  OutputSMG(1,tab[2]);
  OutputSMG(3,tab[F/10]);
  OutputSMG(4,tab[F%10]);
  OutputSMG(5,tab[15]);//-
  OutputSMG(6,tab[M/10]);
  OutputSMG(7,tab[M%10]);
  if(F==0&&zt==1&&M==0)
    {jdq(1);led_dlkz(1,0); }
  if(F==0&&zt==1&&M==5)    
    {jdq(0);led_dlkz(1,1);}
  if(F==0&&zt==1&&0<=M<5)
    {TR0=1;LED_SS();}
  if(F==0&&zt==1&&M>=5)
    {TR0=0;led_dlkz(3,1);}
}
/*********************************时钟显示时分函数************************/
void smg_SF()
{
  uc S,F,M;
  readtime(tac);
  M=(tac[0]>>4)*10+(tac[0]&0X0F);
  S=(tac[2]>>4)*10+(tac[2]&0X0F);
  F=(tac[1]>>4)*10+(tac[1]&0X0F);
  OutputSMG(0,tab[13]);
  OutputSMG(1,tab[2]);
  OutputSMG(3,tab[S/10]);
  OutputSMG(4,tab[S%10]);
  OutputSMG(5,tab[15]);//-
  OutputSMG(6,tab[F/10]);
  OutputSMG(7,tab[F%10]);
  if(F==0&&zt==1&&M==0)
    {jdq(1);led_dlkz(1,0); }
  if(F==0&&zt==1&&M==5)    
    {jdq(0);led_dlkz(1,1);}
  if(F==0&&zt==1&&0<=M<5)
    {TR0=1;LED_SS();}
  if(F==0&&zt==1&&M>=5)
    {TR0=0;led_dlkz(3,1);}
}
/*********************************时钟功能选择函数************************/
void sz_xz()
{
 uc t;
 t=GetButtonValue_1();
 switch(t)
 {
   case 1:smg_SF();break;
   case 2:smg_FM();break;
 }
}
/******************************温度参数数码管显示函数******************************/
void smg_wd1()
{
  OutputSMG(0,tab[13]);
  OutputSMG(1,tab[3]);
  OutputSMG(6,(tab[wd_kz/10]));
  OutputSMG(7,tab[wd_kz%10]);   
}
/******************************温度数码管显示函数******************************/
void smg_wd()
{
  ui temp;
  temp=rd_temperature(); 
  temp=temp*0.625;
  OutputSMG(0,tab[13]);
  OutputSMG(1,tab[1]);
  OutputSMG(5,tab[temp/100]);
  OutputSMG(6,(tab[temp/10%10]&0x7f));
  OutputSMG(7,tab[temp%10]);
     if(temp>(wd_kz*10)&&zt==0)
    {TR0=1;jdq(1);LED_SS();}
    else
    {TR0=0;jdq(0);led_dlkz(3,1);}
}
/**********************按键函数****************/
uc GetButtonValue_1(void)
{
H3=0;
H2=H1=H4=1;
L1=L2=L3=L4=1;
if(L1==0&&zt==1)
{Delay1ms();return 1;while(L1==0);}//s17 切换时秒显示
 return 2;
}
void keycan()
{
 H3=0;
 H2=H1=H4=1;
 L1=L2=L3=L4=1;
 if(L1==0&&zt==0)
 {Delay1ms();wd_kz--;while(L1==0){jm_xs();} }//s17    温度参数减
 H4=0;
 H1=H3=H2=1;
 L1=L2=L3=L4=1;
 if(L2==0)
 {Delay1ms();jm++;if(jm>2){jm=0;}while(L2==0);}//s12   界面切换
 H3=0;
 H1=H2=H4=1;
 L1=L2=L3=L4=1;
 if(L2==0)
 {Delay1ms();zt++;if(zt>1){zt=0;}while(L2==0){jm_xs();}}//s13    温度/时钟控制
 H4=0;
 H2=H1=H3=1;
 L1=L2=L3=L4=1;
 if(L1==0&&zt==0)
 {Delay1ms(); wd_kz++;while(L1==0){jm_xs();}}//s16        温度参数加
}
/*********开机消除85显示**********/
void ds18b20_xxx()
{
   rd_temperature();
   Delay750ms(); 
}
/********界面切换函数*************/
void jm_xs()
{
   switch(jm)
   {
    case 0:smg_wd(); break;
    case 1:sz_xz();  break;
    case 2:smg_wd1();break;
   }
}
/****************初始化函数**********/
void csh_system()
  {
       LED(0xff);//LED灯全关闭
       fmq(0);//关闭蜂鸣器
       jdq(0);//关闭继电器
  }

void main()
{
 ds18b20_xxx();
 savetime(tac);    //时钟初始化
 Timer0Init();
 csh_system();
  while(1)
  {
  GetButtonValue_1();
  keycan();
  LED_ZS();
  jm_xs();
  }
}

ds18B20.c

#include "STC15F2K60S2.H"
#include "onewire.h"

sbit DQ = P1^4;

单总线延时函数
void Delay_OneWire(unsigned int t)  
{
    unsigned char i;
    while(t--){
        for(i=0;i<12;i++);
    }
}

void Delay_us(void)
{
    unsigned char i;

    i = 30;
    while (--i);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        DQ = dat&0x01;
        Delay_OneWire(5);
        DQ = 1;
        dat >>= 1;
    }
    Delay_OneWire(5);

}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
    unsigned char i;
    unsigned char dat;
//    unsigned char index = 0;
             
    for(i=0;i<8;i++)
    {
        DQ = 0;
        dat >>= 1;
        DQ = 1; 
           Delay_us();

        if(DQ)  
        {
            dat |= 0x80;
        }        
        Delay_OneWire(5);
    }
    return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
      bit initflag = 0;
      
      DQ = 1;
      Delay_OneWire(12);
      DQ = 0;

      Delay_OneWire(80); // 延时大于480us
      DQ = 1;
      Delay_OneWire(10);  // 14
      initflag = DQ;     // initflag等于1初始化失败
      Delay_OneWire(5);
  
      return initflag;
}

//缺失自己写
//DS18B20温度采集程序:整数
unsigned int rd_temperature()
{
//   unsigned int temp;
   unsigned char L,H;
   init_ds18b20();
   Write_DS18B20(0xcc);//跳过ROM指令
   Write_DS18B20(0x44);//转换温度指令
   Delay_OneWire(80); // 延时大于480us
   init_ds18b20();
   Write_DS18B20(0xcc);//跳过ROM指令
   Write_DS18B20(0xbe);//读温度指令

   L = Read_DS18B20();
   H = Read_DS18B20();
//   temp = H<<4;
//   temp|=(L>>4);

   return (H<<8)+L;
}

ds18b20.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H


//函数声明 全部声明
void Delay_OneWire();
void Delay_us();
void Write_DS18B20();
unsigned char Read_DS18B20();
bit init_ds18b20();
unsigned int rd_temperature();
 
#endif

ds1302.c

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

#include <STC15F2K60S2.H>
#include <intrins.h>

sbit SCK=P1^7;        
sbit SDA=P2^3;        
sbit RST = P1^3;   // DS1302复位                                                

void Write_Ds1302(unsigned  char temp) 
{
    unsigned char i;
    for (i=0;i<8;i++)         
    { 
        SCK=0;
        SDA=temp&0x01;
        temp>>=1; 
        SCK=1;
    }
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;     _nop_();  
     Write_Ds1302(address);    
     Write_Ds1302(dat);        
     RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
     unsigned char i,temp=0x00;
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;    _nop_();
     Write_Ds1302(address);
     for (i=0;i<8;i++)     
     {        
        SCK=0;
        temp>>=1;    
         if(SDA)
         temp|=0x80;    
         SCK=1;
    } 
     RST=0;    _nop_();
     SCK=0;    _nop_();
    SCK=1;    _nop_();
    SDA=0;    _nop_();
    SDA=1;    _nop_();
    return (temp);            
}

void readtime(unsigned char *time)
{
    unsigned char i=0;
    unsigned char dat=0x81;
    for (i=0;i<7;i++) 
    {
       *(time+i)=Read_Ds1302_Byte (dat); //i对应的是偏移量
       dat=dat+2;
    }
}
void savetime(unsigned char *Time)
{
     unsigned char i=0;
    unsigned char dat=0x80;
    Write_Ds1302_Byte(0x8e,0x00);//禁止写保护  
    for (i=0;i<7;i++) 
    {
       Write_Ds1302_Byte( dat, *(Time+i) );   
       dat=dat+2;
    }
       Write_Ds1302_Byte(0x8e,0x80);//启用写保护  
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void readtime(unsigned char *time);
void savetime(unsigned char *Time);

#endif

代码效果

二维码形式

物联沃分享整理
物联沃-IOTWORD物联网 » “精彩呈现:第一场客观题代码竞赛!13届蓝桥杯单片机省赛”

发表评论