LQB十二届手打代码

main.c

//生成和引用头文件
#include "stc15.h"
#include "stdio.h"//sprintf函数
#include "iic.h"//sprintf函数
#include "onewire.h"//sprintf函数

//写下程序框架,定时器1作为系统的定时时钟,1ms中断

typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;


/*************  本地常量声明    **************/
u8 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

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码


u8 LEDbuf=0x00;
u8 ULNbuf=0x00;
u8 SMGtemp[20];
u8 SMGbuf[8];

#define LED 4
#define ULN 5
#define COM 6
#define ABC 7

//函数声明
void Delay1ms();		//@12.000MHz
void delayms(u16 tms);
void se(u8 x);//选择573
void init();//关闭所有外部设备
void LEDout(); //LED输出
void LEDctrl(); //LED数据刷新,100ms刷新一次,根据不同模式等变化
void ULNout();  //ULN输出
void ULNctrl(); //ULN数据刷新,100ms刷新一次,根据不同模式等变化
void SMGconv(); //数码管转换函数,将字符串转为打印的字段
void SMGnow();  //刷新页面的内容,更新当前的页面,300ms刷新一次页面,根据模式和页面指针
void SMGdisp();//数码管扫描函数,1ms刷新一次;

void KeyRead(); //按键函数
void ReadOut();//读取温度,等控制外设,500ms一次
//添加一下外设的头文件,文件等

//其他全局变量
u8 LEDtime=0;  //LED时间0-200ms,所以u8类型合适了。
u8 ULNtime=0;    //ULNtime时间0-200ms,所以u8类型合适了。
u16 SMGtime=0;    //300ms,大于u8类型
u16 Readtime=0;

//三个页面
u8 page=0;  //0是温度显示页面,1是参数显示页面,2是DAC输出页面

//温度参数
float wendu=24.25;//实时温度参数
float wenduset=25;//温度设置参数


//dac数据
float dac=3.25;

//模式指针
u8 mode=1;//等于1,是模式1,=2是模式2

//
//测试一下数码管程序对不对能不能显示正常
//从stc-isp软件复制定时器的配置过来
//-----------------------------------------------

#define FOSC 11059200L
#define T1MS (65536-FOSC/1000)      //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式
//-----------------------------------------------

/* Timer1 interrupt routine */
void tm1_isr() interrupt 3 using 1
{
    LEDtime++;
	  ULNtime++;
	  SMGtime++;
	  Readtime++;
	
	  SMGdisp();  //1ms刷新一位数码管,一直打开
}
void main()
{
	u8 i=5;
	
	 init();//关闭所有外设
	
   read18b20();//添加头文件
   delayms(800);
		//AUXR,这个寄存器要熟悉,可能后面用到定时器0也需要配置一下
    AUXR |= 0x40;                   //定时器1为1T模式
	//TMOD,这个寄存器要熟悉,可能后面用到定时器0也需要配置一下
    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL1 = T1MS;                     //初始化计时值
    TH1 = T1MS >> 8;
    TR1 = 1;                        //定时器1开始计时
    ET1 = 1;                        //使能定时器0中断
    EA = 1;
	      read18b20();//添加头文件

	 while(1)
	 {
		  if(LEDtime>100)
			{
				LEDtime=0;
				LEDctrl();
			}

			 if(SMGtime>300)
			{
				SMGtime=0;
				SMGnow();
			}
			
			if(Readtime>500)   //DAC输出,读取温度等,都在这个时间段里面
			{
				Readtime=0;
				ReadOut();
			}
		KeyRead(); //按键函数	
			
	 }
}


void KeyRead()
{
	//题目要求,S4,S8 S9 S5
	P32=0;P33=1;
	P34=1;P35=1;P42=1;P44=1;
	if(P44==0)
	{
		delayms(10);
		if(P44==0)  //S5 切换模式
		{
			if(mode==1)mode=2;
			else if(mode==2)mode=1;
		}
		while(P44==0);//如果不放松的话,一直按着
	}
	
	else if(P42==0)
	{
		delayms(10);
		if(P42==0)  //S9
		{
			if(page==1)
				{
					wenduset=wenduset+1;
					if(wenduset>99)wenduset=99;//最大加到99
				}
		}
		while(P42==0);//如果不放松的话,一直按着
	}

//题目要求,S4
	P32=1;P33=0;
	P34=1;P35=1;P42=1;P44=1;	
	if(P44==0)
	{
		delayms(10);
		if(P44==0)  //S4 切换页面
		{
			 if(page==0)page=1;
			 else if(page==1)page=2;
			 else if(page==2)page=0;
		}
		while(P44==0);//如果不放松的话,一直按着
	}

	else if(P42==0)
	{
		delayms(10);
		if(P42==0)  //S8 参数界面下,温度减一
		{
			  if(page==1)
				{
					wenduset=wenduset-1;
					if(wenduset<10)wenduset=10;//最小减到10
				}
		}
		while(P42==0);//如果不放松的话,一直按着
	}
		
	
}
//******************************************函数定义Delay1ms()	
void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}
//******************************************函数定义delayms(u16 tms)
void delayms(u16 tms)
{
	u16 i;
	for(i=0;i<tms;i++)
	{
	   Delay1ms();
	}
	
}
void se(u8 x)
{
	switch(x)
	{
		case 0:P2=P2&0x1F;break;
		case LED:P2=P2&0x1F|0x80;break;
		case ULN:P2=P2&0x1F|0xA0;break;
		case COM:P2=P2&0x1F|0xC0;break;
		case ABC:P2=P2&0x1F|0xE0;break;	
	}
}

void init()//关闭所有外部设备
{
	//关闭LED等,等
	 se(LED);LEDbuf=0x00;P0=~LEDbuf;se(0);  //这里取反,记得,低电平点亮,这里取反等于高电平,熄灭
	 se(ULN);ULNbuf=0x00;P0=ULNbuf;se(0);//这里不取反,因为ULN本身是个反相器,原理图里面,高电平没作用
	 se(COM);P0=0xFF;se(0); //关闭数码管
	 se(ABC);P0=0x00;se(0);
}

void LEDout() //LED输出
{
	 se(LED);P0=~LEDbuf;se(0); 
}
void LEDctrl() //LED数据刷新,100ms刷新一次,根据不同模式等变化
{
   if(mode==1)
	 {
		 //L1点亮,否则熄灭 //bit0=1,
		 LEDbuf =LEDbuf |0x01;
	 }
	 else if(mode==2)
	 {
		 //L1点亮,否则熄灭 //bit0=0,
		 LEDbuf =LEDbuf &(~0x01);
	 }
	
		if(page==0)
		{
			//L1点亮,否则熄灭 //bit1=1,
		 LEDbuf =LEDbuf |0x02;  //0010
		 LEDbuf =LEDbuf &(~0x04);  //0000
		 LEDbuf =LEDbuf &(~0x08);  //0000
		}
		else 	if(page==1)
		{
			//L1点亮,否则熄灭 //bit1=1,
		 LEDbuf =LEDbuf |0x04;  //0100
		 LEDbuf =LEDbuf &(~0x02);  //0000
		 LEDbuf =LEDbuf &(~0x08);  //0000
		}
		else 	if(page==2)
		{
			//L1点亮,否则熄灭 //bit1=1,
		 LEDbuf =LEDbuf |0x08;  //0100
		 LEDbuf =LEDbuf &(~0x02);  //0000
		 LEDbuf =LEDbuf &(~0x04);  //0000
		}
	 
	   LEDout();//输出数据
}

void ReadOut()//读取温度,等控制外设,500ms一次
{
    wendu=read18b20();
	  if(mode==1)
		{
		    if(wendu<wenduset)
				{
				    dac=0;
					  writeDAC(0);
				}
				else if(wendu>=wenduset)
				{
					  dac=5;
				    writeDAC(255);
				}
		}
		else if(mode==2)
		{
		     dac=0.15*wendu-2;
			   writeDAC((int)(dac*51));
		}
}
















void ULNout()  //ULN输出
{
	 se(ULN);P0=ULNbuf;se(0);
}
void ULNctrl() //ULN数据刷新,100ms刷新一次,根据不同模式等变化
{
	
}
void SMGconv() //数码管转换函数,将字符串转为打印的字段
{
	//数码管转换函数,注意小数点
	u8 i,j,temp;
	while(SMGtemp[i]!=0) //没有转换结束的话,就一个个转换到对应段码
	{
		 switch(SMGtemp[i])
		 {
			 case '0':temp=0x3F;break;//注意,是单引号
			 case '1':temp=0x06;break;	
			 case '2':temp=t_display[2];break;//一样的作用
			 case '3':temp=t_display[3];break;//一样的作用
			 case '4':temp=t_display[4];break;//一样的作用
			 case '5':temp=t_display[5];break;//一样的作用
			 case '6':temp=t_display[6];break;//一样的作用
			 case '7':temp=t_display[7];break;//一样的作用
			 case '8':temp=t_display[8];break;//一样的作用
			 case '9':temp=t_display[9];break;//一样的作用
			 //其他字符
			 case 'C':temp=0x39;break;
			 case 'P':temp=0x73;break;
			 case 'A':temp=0x77;break;
			 //***********
			 default:temp=0x00;break;
		 }
		 //判断下一个是不是小数点
		 if(SMGtemp[i+1]=='.')
		 {
			 temp =temp|0x80;
			 i=i+2;
		 }
		 else
		 {
			i=i+1;
		 }
		 
		 SMGbuf[j]=temp;
		 j=j+1;
	}
}

//刷新页面的内容,更新当前的页面,300ms刷新一次页面
	//,根据模式和页面指针
void SMGnow() 
{
  if(page==0)
	{
		//Cxxx25.24
	   sprintf(SMGtemp,"Cxxx%5.2f",wendu);//24.25有5个字符,2个小数点
	}
	else if(page==1)
	{
	 sprintf(SMGtemp,"Pxxxxx%2d",(int)wenduset);//24.25有5个字符,2个小数点
	}
	else if(page==2)
	{
		sprintf(SMGtemp,"Axxxx%3.2f",dac);//24.25有5个字符,2个小数点
	}
	
  SMGconv();//转换段码

}
void SMGdisp()//数码管扫描函数,1ms刷新一次;
{
	static u8 i=0;
	se(COM);P0=0xFF;se(0); //关闭数码管
	se(ABC);P0=0x00;se(0);

	se(COM);P0=T_COM[i];se(0); //关闭数码管
	se(ABC);P0=~SMGbuf[i];se(0);//记得取反
	
  i=i+1;
	if(i>=8)i=0;
}


iic.c

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

#include "stc15.h"
#include "intrins.h"
#include "iic.h"

#define DELAY_TIME 60   //stc15运算速度更加快

#define SlaveAddrW 0xA0   //这个是at24C02de
#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;    
}
//输出DAC,时序,我忘记了,怎么办。参考stcISP
void writeDAC(unsigned char temp)
{
  IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(0x40);//选择输出DAC的控制数据
	IIC_WaitAck();
	  
	IIC_SendByte(temp);
	IIC_WaitAck();
	
	IIC_Stop();
}


iic.h

#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); 
void writeDAC(unsigned char temp);
#endif

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void);  //; ;
float read18b20();//添加头文件
#endif

onewire.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "stc15.h"
#include "onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=t*12; //这一行一定要添加。。
	while(t--);
}

//通过单总线向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;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		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);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

 //读取温度函数
float read18b20()
{
	 unsigned char high,low;
	unsigned int temp;
	float xx;
	
	init_ds18b20();
	Write_DS18B20(0xCC);   //跳过ROM
	Write_DS18B20(0x44);   //开始转换
	Delay_OneWire(200);
	init_ds18b20();
	Write_DS18B20(0xCC);  //跳过ROM
	Write_DS18B20(0xBE);//读取
	Delay_OneWire(200);
	
	low = Read_DS18B20();  //先低
	high =Read_DS18B20();  //后高
	
	temp= (high&0x1F) <<8 |low;
	xx=temp*0.0625;
	 return xx;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值