藍橋杯微控制器CT107D_21_底層驅動程式碼
阿新 • • 發佈:2021-02-18
軟體環境: 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;
}