1. 程式人生 > 其它 >藍橋杯微控制器CT107D_21_底層驅動程式碼

藍橋杯微控制器CT107D_21_底層驅動程式碼

技術標籤:藍橋杯微控制器微控制器c語言

軟體環境: Keil uVision 4.10
硬體環境: CT107微控制器綜合實訓平臺 8051,12MHz

1.SPI:

//SPI.h
#ifndef __DS1302_H
#define __DS1302_H

#include<reg52.h>

sbit SCLK = P1^7; 
sbit RST = P1^3; 
sbit DSIO = P2^3; 

void DS1302_WriteByte(unsigned char addr, unsigned char dat);  //單位元組寫的時序
unsigned char DS1302_ReadByte
(unsigned char addr); //單位元組讀的時序 #endif //SPI.c #include"SPI.h" //單位元組寫的時序 void DS1302_WriteByte(unsigned char addr, unsigned char dat) { unsigned char n; RST = 0; _nop_(); SCLK = 0; _nop_(); RST = 1; _nop_(); for (n=0; n<8; n++) //傳送要寫入資料的記憶體地址 {
DSIO = addr & 0x01; addr >>= 1; SCLK = 1; _nop_(); SCLK = 0; _nop_(); } for (n=0; n<8; n++) //將指定內容寫入該地址的記憶體 { DSIO = dat & 0x01; dat >>= 1; SCLK = 1; _nop_(); SCLK = 0; _nop_(); } RST = 0; _nop_(); } //單位元組讀的時序 unsigned
char DS1302_ReadByte(unsigned char addr) { unsigned char n,dat,tmp; RST = 0; _nop_(); SCLK = 0; _nop_(); RST = 1; _nop_(); for(n=0; n<8; n++) //傳送要讀出資料的記憶體地址 { DSIO = addr & 0x01; addr >>= 1; SCLK = 1; _nop_(); SCLK = 0; _nop_(); } for(n=0; n<8; n++) //讀出該地址記憶體的資料 { tmp = DSIO; dat = (dat>>1) | (tmp<<7); SCLK = 1; _nop_(); SCLK = 0; _nop_(); } RST = 0; _nop_(); SCLK = 1; _nop_(); DSIO = 0; _nop_(); DSIO = 1; _nop_(); //dat = (((dat>>4)*10) | (dat%16)); return dat; }

2.IIC:

//IIC.h
#ifndef __IIC_H
#define __IIC_H

#include<reg52.h>

sbit SDA = P2^1;      //資料線
sbit SCL = P2^0;      //時鐘線

void Delay_IIC(unsigned char t);        //延時函式
void IIC_Start(void);                   //起始訊號
void IIC_Stop(void);                    //停止訊號
void IIC_Ack(unsigned char ackbit);     //產生應答
bit IIC_WaitAck(void);                  //等待應答
void IIC_SendByte(unsigned char byte);	//傳送資料
unsigned char IIC_RecByte(void);        //接收資料

#endif


//IIC.c
#include"IIC.h"

void Delay_IIC(unsigned char time)
{
	while(time--);
}

void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	Delay_IIC(5);
	SDA = 0;        //在SCL高電平期間,SDA由高變低
	Delay_IIC(5);
	SCL = 0;	
}

void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	Delay_IIC(5);
	SDA = 1;	//在SCL高電平期間,SDA由高變低
	Delay_IIC(5);
}

void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 	
		SDA = 0;	//產生應答訊號
	else 
		SDA = 1;	//產生非應答訊號
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	        //第9個時鐘週期
        SCL = 0;
	SDA = 1; 		//釋放SDA線
	Delay_IIC(5);
}

bit IIC_WaitAck(void)
{
	SDA = 1;
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	
 
	if(SDA)    		//在SCL高電平期間,SDA為高電平,從機非應答。
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else 			//在SCL高電平期間,SDA為低電平,從機有應答。
	{ 
		SCL = 0;
		return 1;
	}	
}

void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)		//迴圈傳送8位資料
	{   
		if(byt & 0x80) 		//資料位是高電平
		{	
			SDA = 1;
		}
		else 			//資料位是低電平
		{
			SDA = 0;
		}
 
		Delay_IIC(5);
		SCL = 1;		//SCL高電平期間,SDA的資料要保持穩定
		byt <<= 1;		//傳送的資料左移,準備傳送下一位
		Delay_IIC(5);		//等待SDA的資料被讀取
		SCL = 0;
	}
}

unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		Delay_IIC(5);		//在SCL高電平期間,讀取SDA的資料
		da <<= 1;
		if(SDA) 
			da |= 0x01;
		SCL = 0;
		Delay_IIC(5);
	}
	return da;
}

3.Onewire:

//onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include<reg52.h>

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

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

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

#endif


//onewire.c
#include"onewire.h"

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

//DS18B20晶片初始化
bit Init_DS18B20(void)
{
	bit initflag = 0;
	DQ = 0;
	Delay_OneWire(200);       //拉低匯流排480us以上
	DQ = 1;                   //然後釋放匯流排
	Delay_OneWire(20);        //等待15—60us
	initflag = DQ;            //讀取DS18B20復位應答訊號
	Delay_OneWire(100);       //等待60—240us後釋放匯流排

	return initflag;          //應答訊號為低電平,表示復位成功
}

//DS18B20寫操作
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;               //將匯流排拉低10—15us
		DQ = dat & 0x01;      //想匯流排寫資料
		Delay_OneWire(20);    //維持20—45us
		DQ = 1;               //釋放匯流排
		dat >>= 1;            //右移一位,傳送下一位資料
	}
}

//DS18B20讀時序
unsigned char Read_DS18B20(void)
{
	unsigned char i,dat;
	for(i=0;i<8;i++)
	{
		DQ = 0;               //將匯流排拉低10—15us
		dat >>= 1;            //右移
		DQ = 1;               //釋放匯流排
		if(DQ)				  //讀取總線上的電平,如果為高電平則讀1
		{
			dat |= 0x80;
		}
		Delay_OneWire(20);    //延時45us,再度下一位
	}
	return dat;
}