资讯详情

蓝桥杯模考----串口与ADC

题目要求

主函数

1、main

2、iic

总结


题目要求

大致为:独立按键s5按钮去循环切换实现显示读取rb2的值,上电显示两位小数的电压值,按下s5后显示小数电压值,然后按下s5显示相应的电阻值,然后按下回到两位小数的电压显示。当电压处于2-3v之外时小灯L1以0.1s2-3v时L1点亮,其余小灯熄灭。按键s4每次按下一次通过串口发送一次电压:格式为:"U:2.15V\r\n",波特率为9600。

初始状态:蜂鸣器继电器关闭,上电显示两位小数电压。

主函数

1、main

#include <stc15f2k60s2.h> #include <stdio.h> #include "iic.h" #include "intrins.h" #define uchar unsigned char #define uint unsigned int   sbit Buzzer = P0^6; sbit Relay = P0^4;  /*************  本地常量声明    **************/ uchar code t_display[]={                       ///标准字库 //   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F     0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71, //black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y     0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,     0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1  uchar code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码 uchar table[]={16,16,16,16,16,16,16,16}; uchar ReadData,Trg,Cont; bit key_flag; //指示灯 uchar LED; bit led_flag; //adc数字量 uchar temp; uint V_num1; uchar V_num2;//电压 //模式 uchar set_mode; //串口 bit send_flag;//发送标志 char rx='1'; bit rxc=0; float v_num;  void Delay300ms()  //@12.000MHz {  unsigned char i, j, k;   _nop_();  _nop_();  i = 14;  j = 174;  k = 224;  do  {   do   {    while (--k);   } while (--j);  } while (--i); }  //关闭外设 void allinit() {  P2=0Xa0;Buzzer=0;Relay=0;P2=0X00;  P2=0X80;P0=0XFF;P2=0X00; } void Set_LED() {  P2=0X80;  P0=~LED;  P2=0X00; } //串口 void UartInit(void)  //9600bps@12.000MHz {  SCON = 0x50;  //8位数据,可变波特率  AUXR |= 0x40;  ///定时器1时钟Fosc,即1T  AUXR &= 0xFE;  //串口1选择定时器1波特率发生器  TMOD &= 0x0F;  ///设定时间16位自动重新安装  TL1 = 0xC7;  ///设定时的初始值  TH1 = 0xFE;  ///设定时的初始值  ET1 = 0;  //禁止定时器1中断  TR1 = 1;  ///启动定时器1  ES=1;  EA=1; }  void irs_uart() interrupt 4 {  if(RI)  {   RI=0;   rx=SBUF;   ES=0;   rxc=1;  } }  void uart_sendstring(unsigned char *str) {  unsigned char *p;  p=str;  while(*p!='\0')  {   SBUF=*p;   while(TI==0);   TI=0;   p  ;  } }  //定时器0 void Timer0Init(void)  //1毫秒@12.000MHz {  EA=1;ET0=1;  AUXR |= 0x80;  //定时器时钟1T模式  TMOD &= 0xF0;  //设置定时器模式  TL0 = 0x20;  ///设定时初值  TH0 = 0xD1;  ///设定时初值  TF0 = 0;  //清除TF0标志  TR0 = 1;  ///定时器0开始计时 }  void Timer0() interrupt 1 {  static uint smg_count,key_count,i,led_count;  if(  smg_count>=2)  {   smg_count=0;   P2=0Xe0;P0=0XFF;P2=0X00;   P2=0Xc0;P0=T_COM[i];P2=0X00;   P2=0Xe0;P0=~t_display[table[i]];P2=0X00;   i  ;   if(i>=8)i=0;  }  if(  key_count>=10)  {   key_count=0;   key_flag=1;  }  if(  led_count>=100)  {   led_count=0;   led_flag=~led_flag;  } }  void ReadKey() {  ReadData=P3^0xff;  Trg=ReadData&(ReadData^Cont);  Cont=ReadData; }  void disp_key() {  if(key_flag)  {   key_flag=0;   Set_LED();   ReadKey();   switch(Trg)   {    case 0x08://s4     send_flag=1;    break;    case 0x04://s5     set_mode  ;    if(set_mode>=3)set_mode=0;    break;   }  }  } //L1指示灯 void disp_LED() {  if((temp*5.0/255)<=2||(temp*5.0/255)>=3)  {   if(led_flag)   {    LED|=1;   }else{    LED&=~1;   }     }  else if((temp*5.0/255)>2&&(temp*5.0/255)<3){   LED|=1;  } }    void main() {  unsigned char str[35];  allinit();  Timer0Init();  UartInit();  Write_ADC(0x03);//rb2  while(1)  {         //读取rb2,电阻值,以及一个小数电压值和两个小数电压值   temp=Read_ADC(0x03);   V_num1=(temp*5.0/255)*100;   V_num2=temp*50.0/255;   switch(set_mode)   {    case 0:     table[0]=25;     table[1]=16;     table[2]=16;     table[3]=16;     table[4]=16;     table[5]=V_num1/100 32;     table[6]=V_num1/10;     table[7]=V_num1;    break;    case 1:     table[0]=25;     table[1]=16;     table[2]=16;     table[3]=16;     table[4]=16;     table[5]=16;     table[6]=V_num2/10 32;     table[7]=V_num2;    break;    case 2:     table[0]=16;     table[1]=16;     table[2]=16;     table[3]=16;     table[4]=16;     table[5]=temp>100?temp/100:16;     table[6]=temp>100?temp/100:16;     table[6]=temp>100?temp/10:16;     table[]=temp%10;
			break;
		}
		if(send_flag)//串口
		{
			send_flag=0;
			sprintf(str,"U:%4.2fV\r\n",v_num);//发送格式为:U:2.15V\r\n,uv大写,包含换行和回车
			v_num=temp*5.0/255;
			uart_sendstring(str);
			Delay300ms();
			Delay300ms();
			if(rxc==1)
			{
				rxc=0;
				ES=1;
			}
		}
		disp_LED();
		disp_key();//按键
	}
}

2、iic

#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#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);
}


//等待应答
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;    
}

//ADC
void Write_ADC(unsigned char add)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char Read_ADC(unsigned char add)
{
	unsigned char temp;
	EA=0;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	EA=1;
	return temp;
}
#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
//ADC
void Write_ADC(unsigned char add);
unsigned char Read_ADC(unsigned char add);
#endif

总结

        就这四次模考来讲,考了基本的led灯,按键,数码管,时钟,eeprom,DA/AD,超声波,串口等。虽然其中超声波和串口都是国赛的考点,但是模考考了,这得重视,猜不准它不考。

        其中按键考了长按中的长按超过要求时间后抬起才起作用。还有iic得多注意!!!感觉今年必考iic。DA必考!!!不考频率!!!

标签: 36v指示灯串电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台