藍橋杯大賽——驅動程式

朽木自雕i發表於2020-12-05

首先介紹一下這個藍橋杯電子組微控制器給出的驅動程式,這個驅動程式幾乎是必考的,因為初賽的話大家也都知道,無非就是考LED、數碼管、獨立按鍵、矩陣按鍵、蜂鳴器、單匯流排DS18B20溫度感測器,時鐘晶片DS1302以及AD轉換嘛,那塊板子總共也沒幾個模組,像LED、數碼管、按鍵(不管是矩陣按鍵還是獨立按鍵)和蜂鳴器這幾個幾乎是必考,這是最最基礎的東西了,這些功能肯定會有的,所以說初賽的話主要就是考察大家對DS18B20、DS1302和AD轉換的知識,可見學習這三個驅動還是非常重要的,雖然這三個驅動大賽的時候官方會給提供,但大家在下面一定要多練習多理解,要不然到時候不會用不也白搭。下面把官方提供的驅動先分享給大家,需要的可以先收藏起來以後慢慢研究。

iic.c檔案如下:

#include "iic.h"
//匯流排啟動條件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    somenop;
    SDA = 0;
    somenop;
    SCL = 0;    
}

//匯流排停止條件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    somenop;
    SDA = 1;
}

//應答位控制
void IIC_Ack(unsigned char ackbit)
{
    if(ackbit) 
    {    
        SDA = 0;
    }
    else 
    {
        SDA = 1;
    }
    somenop;
    SCL = 1;
    somenop;
    SCL = 0;
    SDA = 1; 
    somenop;
}

//等待應答
bit IIC_WaitAck(void)
{
    SDA = 1;
    somenop;
    SCL = 1;
    somenop;
    if(SDA)    
    {   
        SCL = 0;
        IIC_Stop();
        return 0;
    }
    else  
    { 
        SCL = 0;
        return 1;
    }
}

//通過I2C匯流排傳送資料
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {   
        if(byt&0x80) 
        {    
            SDA = 1;
        }
        else 
        {
            SDA = 0;
        }
        somenop;
        SCL = 1;
        byt <<= 1;
        somenop;
        SCL = 0;
    }
}

//從I2C匯流排上接收資料
unsigned char IIC_RecByte(void)
{
    unsigned char da;
    unsigned char i;
    
    for(i=0;i<8;i++)
    {   
        SCL = 1;
        somenop;
        da <<= 1;
        if(SDA) 
        da |= 0x01;
        SCL = 0;
        somenop;
    }
    return da;
}

iic.h檔案如下:

#ifndef _IIC_H
#define _IIC_H

#include "regx52.h"
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//匯流排引腳定義
sbit SDA = P2^1;  /* 資料線 */
sbit SCL = P2^0;  /* 時鐘線 */

//函式宣告
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 

#endif

ds1302.c檔案如下:

#include "ds1302.h"
/********************************************************************/ 
/*單位元組寫入一位元組資料*/
void Write_Ds1302_Byte(unsigned char dat) 
{
	unsigned char i;
	SCK = 0;
	for (i=0;i<8;i++) 
	{ 
		if (dat & 0x01) 	// 等價於if((addr & 0x01) ==1) 
		{
			SDA_SET;		//#define SDA_SET SDA=1 /*電平置高*/
		}
		else 
		{
			SDA_CLR;		//#define SDA_CLR SDA=0 /*電平置低*/
		}		 
		SCK_SET;
		SCK_CLR;		
		dat = dat >> 1; 
	} 
}
/********************************************************************/ 
/*單位元組讀出一位元組資料*/
unsigned char Read_Ds1302_Byte(void) 
{
	unsigned char i, dat=0;	
	for (i=0;i<8;i++)
	{	
		dat = dat >> 1;
		if (SDA_R) 	  //等價於if(SDA_R==1)    #define SDA_R SDA /*電平讀取*/	
		{
			dat |= 0x80;
		}
		else 
		{
			dat &= 0x7F;
		}
		SCK_SET;
		SCK_CLR;
	}
	return dat;
}

/********************************************************************/ 
/*向DS1302 單位元組寫入一位元組資料*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{ 

	RST_CLR;			/*RST腳置低,實現DS1302的初始化*/
	SCK_CLR;			/*SCK腳置低,實現DS1302的初始化*/

	RST_SET;			/*啟動DS1302匯流排,RST=1電平置高 */
	addr = addr & 0xFE;	 
	Write_Ds1302_Byte(addr); /*寫入目標地址:addr,保證是寫操作,寫之前將最低位置零*/	
	Write_Ds1302_Byte(dat);	 /*寫入資料:dat*/
	RST_CLR;				 /*停止DS1302匯流排*/
}

/********************************************************************/ 
/*從DS1302單位元組讀出一位元組資料*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) 
{ 
	unsigned char temp;
	RST_CLR;			/*RST腳置低,實現DS1302的初始化*/
	SCK_CLR;			/*SCK腳置低,實現DS1302的初始化*/

	RST_SET;	/*啟動DS1302匯流排,RST=1電平置高 */	
	addr = addr | 0x01;	 
	Write_Ds1302_Byte(addr); /*寫入目標地址:addr,保證是讀操作,寫之前將最低位置高*/
	temp=Read_Ds1302_Byte(); /*從DS1302中讀出一個位元組的資料*/		
	RST_CLR;	/*停止DS1302匯流排*/
	return temp;
}

ds1302.h檔案如下:

#ifndef  __DS1302_H__
#define  __DS1302_H__

#include<regx52.h>
#include<intrins.h>
/********************************************************************/ 
sbit SCK=P1^7;		
sbit SD=P2^3;		
sbit RST=P1^3;
/********************************************************************/ 
/*復位腳*/
#define RST_CLR	RST=0	/*電平置低*/
#define RST_SET	RST=1	/*電平置高*/
/*雙向資料*/
#define SDA_CLR	SD=0	/*電平置低*/
#define SDA_SET	SD=1	/*電平置高*/
#define SDA_R	SD	/*電平讀取*/	
/*時鐘訊號*/
#define SCK_CLR	SCK=0	/*時鐘訊號*/
#define SCK_SET	SCK=1	/*電平置高*/
/********************************************************************/ 
#define ds1302_sec_addr			0x80		//秒資料地址
#define ds1302_min_addr			0x82		//分資料地址
#define ds1302_hr_addr			0x84		//時資料地址
#define ds1302_date_addr		0x86		//日資料地址
#define ds1302_month_addr		0x88		//月資料地址
#define ds1302_day_addr			0x8A		//星期資料地址
#define ds1302_year_addr		0x8C		//年資料地址

#define ds1302_control_addr		0x8Ee		//防寫命令字單元地址
#define ds1302_charger_addr		0x90 		//涓電流充電命令字地址			 
#define ds1302_clkburst_addr	0xBE		//日曆、時鐘突發模式命令字地址
/********************************************************************/ 

/********************************************************************/ 
/*單位元組寫入一位元組資料*/
extern void Write_Ds1302_Byte(unsigned char dat);
/********************************************************************/ 
/*單位元組讀出一位元組資料*/
extern unsigned char Read_Ds1302_Byte(void);
  
/********************************************************************/ 
/********************************************************************/ 
/*向DS1302單位元組寫入一位元組資料*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/ 
/*從DS1302單位元組讀出一位元組資料*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);

#endif	 
/********************************************************************/
//		     	END FILE
/********************************************************************/

onewire.c檔案如下:

#include "onewire.h"

//單匯流排延時函式
void Delay_OneWire(unsigned int t)
{
  while(t--);
}

//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;
}

//通過單匯流排向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;
}

onewire.h檔案如下:

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "reg52.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//IC引腳定義
sbit DQ = P1^4;

//函式宣告
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);

#endif

 

相關文章