第十届蓝桥杯单片机省赛 自撸程序

重要的地方DAC输出部分 

主程序 

#include <STC15F2K60S2.H>
#include <IIC.H>

#define uchar unsigned char
#define uint unsigned int
uchar code Nodat[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code Isdat[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uint SMG_hz;
uint SMG_vlot;
uint cont_f;
uint cont_t;
uchar F_SMG=1;

uchar S5_flag=1;
uchar S6_flag=1;
uchar S7_flag=1;
float adc_vlot;

sbit S4=P3^3;
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;

sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit L4=P0^3;
sbit L5=P0^4;
void SelectHC573(uchar n)
{
	switch(n)
	{
		case 0 : P2=(P2 &0x1f)|0x00; break;
		case 4 : P2=(P2 &0x1f)|0x80; break;
		case 5 : P2=(P2 &0x1f)|0xa0; break;
		case 6 : P2=(P2 &0x1f)|0xc0; break;
		case 7 : P2=(P2 &0x1f)|0xe0; break;
	}
}
void Output_P0(uchar channel,uchar val)
{
	 SelectHC573(channel);
	 P0=val;
	 SelectHC573(0);
}
void Delay2ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 24;
	j = 85;
	do
	{
		while (--j);
	} while (--i);
}
void SMGbit(uchar pos,uchar val)
{
	Output_P0(6,0x01<<pos);
	Output_P0(7,val);
    Delay2ms();	
	Output_P0(6,0x01<<pos);
    Output_P0(7,0xff);
}
void DispalySMG()
{
	if(S7_flag)
{ switch(F_SMG)
	{
		case 0:
		TR0=TR1=1;
	    SMGbit(0,0x8e);
	    SMGbit(1,0xff);
		if(SMG_hz>99999)
		SMGbit(2,Nodat[SMG_hz/100000]);
		if(SMG_hz>9999)
		SMGbit(3,Nodat[SMG_hz/10000%10]);
		if(SMG_hz>999)
		SMGbit(4,Nodat[SMG_hz/1000%10]);
		if(SMG_hz>99)
		SMGbit(5,Nodat[SMG_hz/100%10]);
		if(SMG_hz>9)
		SMGbit(6,Nodat[SMG_hz/10%10]);
		SMGbit(7,Nodat[SMG_hz%10]);
		break;
	
		case 1:
		TR0=TR1=0;
	    SMGbit(0,0xc1);
	    SMGbit(1,0xff);
		SMGbit(2,0xff);
		SMGbit(3,0xff);
		
		SMGbit(4,0xff);
		SMGbit(5,Isdat[SMG_vlot/100]);
		SMGbit(6,Nodat[(SMG_vlot/10)%10]);
		SMGbit(7,Nodat[SMG_vlot%10]);
		break;
	}
}
}
void Timer1Init()		//定时50ms
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xB0;		//设置定时初值
	TH1 = 0x3C;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;ET1=1;
}
void Timer0Init()	//计数
{
	TMOD=0x06;
	TH0=0xff;
	TL0=0xff;
	EA=1;TR0=1;ET0=1;
}
void Timer0Service() interrupt 1
{
	cont_f++;
}
void Timer1Service() interrupt 3
{
	cont_t++;
	if(cont_t==20)
	{
		cont_t=0;
		SMG_hz=cont_f;
		cont_f=0;		
	}
}
uchar Read_cf8951()
{
	uchar medium;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_Stop();
	 
  DispalySMG();

	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	medium = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return medium;
}
void Set_PCF8591_DAC(uchar digtal) //DAC输出 float 102.4 可能更准确
{
	IIC_Start();					
	IIC_SendByte(0x90);		//PCF8591的写设备地址 
	IIC_WaitAck();	
	IIC_SendByte(0x43); 	//输出DAC,转换AIN3	
	IIC_WaitAck(); 								
	IIC_SendByte(digtal); 		//设置DAC电压输出参数
	IIC_WaitAck(); 			//产生非应答信号 								
	IIC_Stop();	
	
}
void Date_mange()
{
	 if(S5_flag)
	 {
		 Set_PCF8591_DAC(102);
		 SMG_vlot=200;
	 }
	 else
	 {
		adc_vlot=Read_cf8951()*(5.0/255);
	    SMG_vlot= adc_vlot*100;
	 }	
}
void Scankey()
{
if(S4==0)
	{  DispalySMG();
	if(S4==0)
	{
	 F_SMG=!F_SMG;	
	}
	while(S4==0)
	  DispalySMG();	
  }
if(S5==0)
	{  DispalySMG();
	if(S5==0)
	{ 
	 S5_flag=!S5_flag;
	
	}
	while(S5==0)
	  DispalySMG();	
	}
if(S6==0)
	{  DispalySMG();
	if(S6==0)
	{ 
   S6_flag=!S6_flag;
	}
	while(S6==0)
	  DispalySMG();	
	}
if(S7==0)
	{  DispalySMG();
	if(S7==0)
	{ 
   S7_flag=!S7_flag;
	}
	while(S7==0)
	  DispalySMG();	
	}	
}	
void LED()
{
if(S6_flag)
	{
	if(F_SMG)
	{
		SelectHC573(4);
		L1=0;  L2=1;
		SelectHC573(0);
	}
	else
	{
		SelectHC573(4);
		L1=1;  L2=0;
		SelectHC573(0);
	}
if(S5_flag==0)
{
	    SelectHC573(4);
	    L5=0;
		SelectHC573(0);
if(adc_vlot<1.5)
  {
	    SelectHC573(4);
	    L3=1;
		SelectHC573(0);
	}	
  	if(adc_vlot>=1.5 && adc_vlot<2.5)
  {
        SelectHC573(4);
	    L3=0;
		SelectHC573(0);
	}
		if(adc_vlot>=2.5 && adc_vlot<3.5)
   {
        SelectHC573(4);
	    L3=1;
		SelectHC573(0);
	}
else if(adc_vlot>=3.5)
	{
        SelectHC573(4);
	    L3=0;
		SelectHC573(0);
	 }
 }
else
	 {
		SelectHC573(4);
	    L5=1;
		SelectHC573(0);
	 }
if(SMG_hz<1000)
  {
	    SelectHC573(4);
	    L4=1;
		SelectHC573(0);
	}	
  	if(SMG_hz>=1000 && SMG_hz<5000)
  {
        SelectHC573(4);
	    L4=0;
		SelectHC573(0);
	}
		if(SMG_hz>=5000 && SMG_hz<10000)
  {
        SelectHC573(4);
	    L4=1;
		SelectHC573(0);
	}
	else if(SMG_hz>=10000)
	{
        SelectHC573(4);
	    L4=0;
		SelectHC573(0);
	 }
 }
  else 
  Output_P0(4,0xff);
}

void SystemInit()
{
    P2=(P2 &0x1f)|0xa0;
	P0=0x00;
	P2=(P2 &0x1f)|0x80;
	P0=0xff;
	P2 &=0xff;
}
void main()
{
	 Timer0Init();
	 Timer1Init();
	 SystemInit();
while(1)
	{
		LED();
		Scankey();
		Date_mange();
		DispalySMG();
	}
}

驱动代码

/*
  程序说明: 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);
}

//发送应答
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;    
}

还有一个喔

#ifndef _IIC_H_
#define _IIC_H_

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

#endif

不会吧不会吧...你没有原题

 告诉你怎么知道输出的电压是正确的呢??

万用表测试下面指向的引脚。A/D和GND

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值