今天就写了两个程序,晚上准备去装一个linux以后方便学linux编程,收获呢就是对单片机的时序图模拟的顺利了点。。。
贴上代码,装机去。
#include "I2C.h"
//延迟10us
void Delay10us(void)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
void I2cStart()
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();
SDA=0;
Delay10us();
SCL=0;
Delay10us();
}
void I2cEnd()
{
SDA=0; //这里第一次写出现错误
Delay10us();
SCL=1;
Delay10us();
SDA=1;
Delay10us();
}
unsigned char I2cSendByte(unsigned char dat)
{//这里没有思路,不会写
unsigned char a=0, b=0;
for(a=0; a<8; a++)
{
SDA=dat>>7;
dat<<=1;
Delay10us();
SCL=1;
Delay10us();
SCL=0;
Delay10us();
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)
{
b++;
if(b>200)
{
SCL=0;
Delay10us();
return 0;
}
}
SCL=0;
Delay10us();
return 1;
}
unsigned char I2cReadByte()
{
unsigned char a=0, dat=0;
SDA=1;
Delay10us();
for(a=0; a<8; a++)
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
Delay10us();
SCL=0;
Delay10us();
}
return dat;
}
void At24c02Write(unsigned char addr, unsigned char dat)
{
I2cStart();
I2cSendByte(0xa0);
I2cSendByte(addr);
I2cSendByte(dat);
I2cEnd();
}
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0);
I2cSendByte(addr);
I2cStart();
I2cSendByte(0xa1);
num=I2cReadByte();
I2cEnd();
return num;
}
#ifndef _I2C_H
#define _I2C_H
#include "reg51.h"
sbit SDA=P2^0; //把这里写成P3^0口了,以为是通过串行口来模仿I2C总线时序,导致最后写完以后调试花了1个小时
sbit SCL=P2^1;
void I2cStart();
void I2cEnd();
unsigned char I2cSendByte(unsigned char);
unsigned char I2cReadByte();
void At24c02Write(unsigned char, unsigned char);
unsigned char At24c02Read(unsigned char);
#endif
#include "reg51.h"
#include "I2C.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit K1=P3^1;
sbit K2=P3^0;
sbit K3=P3^2;
sbit K4=P3^3;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char num=0;
u8 Disp[4];
void Delay(u16 i)
{
while(i--);
}
void KeyProc()
{
if(K1==0)
{
Delay(1000);
if(K1==0)
At24c02Write(1, num);
while(!K1);
}
if(K2==0)
{
Delay(1000);
if(K2==0)
num=At24c02Read(1);
while(!K2);
}
if(K3==0)
{
Delay(100);
if(K3==0)
{
num++;
if(num>255)num=0;
}
while(!K3);
}
if(K4==0)
{
Delay(1000);
if(K4==0)
num=0;
while(!K4);
}
}
void DataProc()
{
Disp[0]=smg[num/1000];
Disp[1]=smg[num%1000/100];
Disp[2]=smg[num%1000%100/10];
Disp[3]=smg[num%1000%100%10];
}
void Display()
{
u8 i;
for(i=0; i<4; i++)
{
switch(i)
{
case 0: LSA=0; LSB=0; LSC=0; break;
case 1: LSA=1; LSB=0; LSC=0; break;
case 2: LSA=0; LSB=1; LSC=0; break;
case 3: LSA=1; LSB=1; LSC=0; break;
}
P0=Disp[3-i];
Delay(100);
P0=0x00;
}
}
void main()
{
while(1)
{
KeyProc();
DataProc();
Display();
}
}
上面的程序主要是对I2C总线模拟。
下面是对18B20数据线的传输模拟
//mani.c
#include "reg51.h"
#include "temp.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char num=0;
u8 Disp[4], DisplayData[8];
void Delay(u16 i)
{
while(i--);
}
void DataProc(int temp)
{
float tp;
if(temp<0)
{
DisplayData[0]=0x40;
temp-=1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
}
else
{
DisplayData[0]=0x00;
temp=temp*0.0625*100+0.5;
}
Disp[1]=smg[temp/10000];
Disp[2]=smg[temp%10000/1000];
Disp[3]=smg[temp%10000%1000/100]|0x80;
Disp[4]=smg[temp%100/10];
Disp[5]=smg[temp%100%10];
}
void Display()
{
u8 i;
for(i=0; i<4; i++)
{
switch(i)
{
case 0: LSA=0; LSB=0; LSC=0; break;
case 1: LSA=1; LSB=0; LSC=0; break;
case 2: LSA=0; LSB=1; LSC=0; break;
case 3: LSA=1; LSB=1; LSC=0; break;
case 4: LSA=0; LSB=0; LSC=1; break;
case 5: LSA=1; LSB=0; LSC=1; break;
}
P0=Disp[5-i];
Delay(100);
P0=0x00;
}
}
void main()
{
while(1)
{
DataProc(Ds18b20ReadTemp());
Display();
}
}
//18b20.h
#ifndef _TEMP_H
#define _TEMP_H
#include <reg51.h>
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
sbit DSPORT=P3^7;
int Ds18b20ReadTemp();
#endif
//18b20.c
#include "temp.h"
void Delay1ms(uint y)
{
uint x;
for(; y>0; y--)
{
for(x=110; x>0; x--);
}
}
//1:成功; 0:失败
uchar Ds18b20Init()
{
uchar i=0;
DSPORT=0;
i=70;
while(i--);//642us
DSPORT=1;
i=0;
while(DSPORT)
{
Delay1ms(1);
i++;
if(i>5)
{
return 0;
}
}
return 1;
}
void Ds18b20WriteByte(uchar dat)
{
uchar i, j;
for(j=0; j<8; j++)
{
DSPORT=0;
i++;
DSPORT=dat&0x01;
i=6;
while(i--);//68us
DSPORT=1;
dat>>=1;
}
}
uchar Ds18b20ReadByte()
{
uint i, j;
uchar bi, byte;
for(j=8; j>0; j--)
{
DSPORT=0;
i++;
DSPORT=1;
i++;
i++;
bi=DSPORT;
byte=(byte>>1)|(bi<<7);
i=4;
while(i--);
}
return byte;
}
void Ds18b20ChangeTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0x44);
}
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0xbe);
}
int Ds18b20ReadTemp()
{
int temp=0;
uchar tmh, tml;
Ds18b20ChangeTemp();
Ds18b20ReadTempCom();
tml=Ds18b20ReadByte();
tmh=Ds18b20ReadByte();
temp=tmh;
temp<<=8;
temp|=tml;
return temp;
}
可以实现对温度的实时监控。
装机去。