蓝桥杯单片机-----第十届

目录

题目要求

考察模块

分析

代码实现

 1、主函数

 2、IIC      

                2.1、iic.c

        2.2、iic.h


题目要求

考察模块

        三件套:LED,按键,数码管

        IIC:ADC和DAC

        频率

 

分析

1、按键和数码管:老生常谈了,不多说了。

2、LED:这次题目我感觉小灯挺重点的,实现也算是个难点,我之前也讲过小灯的实现方法,不会的可以去看我之前写的第十一届第一场的博客,里面有讲方法,和这次类似,不说了不说了。

3、iic:ADC和DAC。ADC:也可以看之前的博客,说下DAC(首先驱动代码里面你需要写一个Write_DAC函数,然后在主函数里面调用这个函数去实现你将要写入DAC中的电压)。

注意:255欧姆对应5V。通过这个关系来实现电压与电阻之间的转换。

//DAC
void Write_DAC(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

4、频率:记住一个点就行了,不能使用定时器1来频率计数。因此本题我用到了两个定时器,定时器0用来作频率计数,定时器1用来定时(按键扫描,数码管刷新.......)

本题频率测过了:与理想的误差在1-2之间,还算准的。

//一定要加上TMOD |=0x04;这是表示定时器0的工作模式为计数

void Timer0Init(void)		//1毫秒@12.000MHz
{
	ET0=1;
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x04;
	TL0 = 0;		//设置定时初值
	TH0 = 0;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

//一定要加上TMOD |=0x04;这是表示定时器0的工作模式为计数

5、初始化

        初始化每次都是重点。

代码实现

        1、主函数

#include<stc15f2k60s2.h>
#include"iic.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 smg_table[]={16,16,16,16,16,16,16,16};
uchar ReadData,Trg,Cont;
bit key_flag;
bit ReadAdc_flag;  //读ADC
bit DAC_flag;		   //输出模式切换
bit LED_flag;			//led灯模式控制
bit Smg_flag;			//数码管模式控制
uchar LED;//小灯
uchar mode=0;//0为电压显示界面,1为频率显示界面
uint ADC_Value;		 //电压值
uint DAC_Value;				//Vdac
uint f=0;			//频率

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 Timer0Init(void)		//1毫秒@12.000MHz
{
	ET0=1;
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x04;
	TL0 = 0;		//设置定时初值
	TH0 = 0;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void Timer1Init(void)		//1毫秒@12.000MHz
{
	ET1=1;EA=1;
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初值
	TH1 = 0xD1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}

void Timer1() interrupt 3
{
	static uint smg_count,key_count,i,ADC_count,f_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[smg_table[i]];P2=0x00;
		i++;
		if(i>=8)i=0;
	}
	if(++key_count>=10)
	{
	  key_count=0;
	  key_flag=1;
	}
	if(++ADC_count>=100)
	{
	  ADC_count=0;
	  ReadAdc_flag=1;
	}
	if(++f_count>=1000)
	{
	   f_count=0;
	   TR0=0;
	   f=(TH0<<8|TL0);
	   TL0=0;
	   TH0=0;
	   TR0=1;
	}
}

void ReadKey()
{
   ReadData=P3^0xff;
   Trg=ReadData&(ReadData^Cont);
   Cont=ReadData;
}

void dis_key()
{
	if(key_flag)
	{
		key_flag=0;
		Set_LED();
		ReadKey();
		switch(Trg)
		{
		  case 0x08:	  //s4
			  mode++;
			  if(mode>=2) mode=0;
		  break;
		  case 0x04:	  //s5
			  DAC_flag=~DAC_flag;
		  break;		
		  case 0x02:	  //s6
			 LED_flag=~LED_flag; 
		  break;
		  case 0x01:	  //s7
			  Smg_flag=~Smg_flag;
		  break;		  		
		}
	}
}

void dis_Led3()
{
	if(ADC_Value<150)
	{
	   LED&=~4;			  //L3熄灭
	}
	else if(ADC_Value>=150&&ADC_Value<250)
	{
		LED|=4;
	}
	else if(ADC_Value>=250&&ADC_Value<350)
	{
	   LED&=~4;
	}
	else if(ADC_Value>=350)
	{
		LED|=4;//L3亮
	}
}

void dis_Led4()
{
   if(f<1000)
   {
   	  LED&=~8;			  //L4熄灭
   }
   else if(f>=1000&&f<5000)
   {
   	  LED|=8;//L4亮
   }
   else if(f>=5000&&f<10000)
   {
   	  LED&=~8;			  //L4熄灭
   }
   else if(f>=10000)
   {
   	  LED|=8;//L4亮
   }


}

void dis_DAC()
{
	if(DAC_flag==0)
	{
	  Write_DAC(102);	   //2v
	  LED&=~16;			   	//	L5灭
	}
	else {
	 DAC_Value=ADC_Value;
	 Write_DAC(DAC_Value/100*255/5.0);
	 LED|=16;			 //L5亮
	}
}
void dis_Led()
{
   if(LED_flag==0)
   {
   		dis_DAC();
		dis_Led3();
		dis_Led4();
   		if(mode==0)
		{
		  LED|=1;	   //L1亮
		  LED&=~2;		   //L2灭
		}
		else if(mode==1)
		{
		   LED|=2;	   //L2亮
		  LED&=~1;		   //L1灭
		}
   }
   else  
   {
   	 	LED=0;	  //所有灯熄灭
   }
}

int main()
{

	allinit();		   //关闭外设
	Timer0Init();	   //定时器0
	Timer1Init();
	Write_ADC(0x03);		   //rb2
	while(1)
	{
		if(ReadAdc_flag)
		{
			EA=0;
			ADC_Value=Read_ADC(0x03)*5.0/255*100;
			ReadAdc_flag=0;
			EA=1;
		}
		if(Smg_flag==0)
		{
			switch(mode)
			{
			   case 0:
					smg_table[0]=25;
					smg_table[1]=16;
					smg_table[2]=16;
					smg_table[3]=16;
					smg_table[4]=16;
					smg_table[5]=ADC_Value/100+32;
					smg_table[6]=ADC_Value/10%10;
					smg_table[7]=ADC_Value%10;
			   break;
			   case 1:
					smg_table[0]=15;
					smg_table[1]=16;
					smg_table[2]=(f/100000==0)?16:f/100000;
					smg_table[3]=(f/10000==0)?16:f/10000%10;
					smg_table[4]=(f/1000==0)?16:f/1000%10;
					smg_table[5]=(f/100==0)?16:f/100%10;
					smg_table[6]=(f/10==0)?16:f/10%10;
					smg_table[7]=f%10;
			   break;			
			}
		}
		else
		{
		 	smg_table[0]=16;	smg_table[1]=16;	smg_table[2]=16;	smg_table[3]=16;	
			smg_table[4]=16;	smg_table[5]=16;	smg_table[6]=16;	smg_table[7]=16;	
		}
		dis_Led();
		dis_key();
	}
}

        2、IIC

                2.1、iic.c

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

#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;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();

	return temp;
}

//DAC
void Write_DAC(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

               2.2、iic.h

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

//DAC
void Write_DAC(unsigned char dat);
#endif
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值