单片机比赛准备04-蓝桥杯-eeprom、时钟芯片、AD芯片的使用
·


ds1302.h
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302_Byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
#endif
ds1302.c
/*
程序说明: DS1302驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include <stc15f2k60s2.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302( unsigned char address,unsigned char dat )
{
unsigned char num;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
num=((dat/10)<<4)|(dat%10);
Write_Ds1302_Byte(num);
RST=0;
}
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0;
_nop_();
RST=0;
SCK=0;
_nop_();
SCK=1;
_nop_();
SDA=0;
_nop_();
SDA=1;
_nop_();
SDA=0;
return (temp);
}
main.c
#include <stc15f2k60s2.h>
#include <intrins.h>
#include <ds1302.h>
#define uchar unsigned char
#define uint unsigned int
uchar ds[]={55,59,23,10,10,1,16};
uchar shijian[7];
uchar seg[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,
0xff
};
uchar yi=16, er=16,san=16,si=16,wu=16,liu=16,qi=16,ba=16;
void allinit();
void dsinit();
void readtime();
void display(uchar yi,er,san,si,wu,liu,qi,ba);
void Delay1ms();
void Delayms(uint ms);
void main()
{
allinit();
dsinit();
while(1)
{
readtime();
yi=shijian[2]/16;er=shijian[2]%16;san=16;
si=shijian[1]/16;wu=shijian[1]%16;liu=16;
qi=shijian[0]/16;ba=shijian[0]%16;
display(yi,er,san,si,wu,liu,qi,ba);
}
}
void allinit()
{
P2=0xa0;P0=0x00;
P2=0x80;P0=0xff;
P2=0xe0;P0=0xff;
P2=0xc0;P0=0xff;
}
void display(uchar yi,er,san,si,wu,liu,qi,ba)
{
P2=0xe0;//段选
P0=seg[yi];
P2=0xc0;//位选
P0=0x01;
Delay1ms();
Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[er];
P2=0xc0;//位选
P0=0x02;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[san];
P2=0xc0;//位选
P0=0x04;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[si];
P2=0xc0;//位选
P0=0x08;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[wu];
P2=0xc0;//位选
P0=0x10;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[liu];
P2=0xc0;//位选
P0=0x20;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[qi];
P2=0xc0;//位选
P0=0x40;
Delay1ms();Delay1ms();Delay1ms();
P2=0xe0;//段选
P0=seg[ba];
P2=0xc0;//位选
P0=0x80;
Delay1ms();Delay1ms();Delay1ms();
}
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void Delayms(uint ms) //@11.0592MHz
{
unsigned char i, j,k;
for(k=ms;k>0;k--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void dsinit()
{
uchar i;
uchar add=0x80;
Write_Ds1302(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302(add,ds[i]);
add=add+2;
}
Write_Ds1302(0x8e,0x80);
}
void readtime()
{
uchar i;
uchar add=0x81;
Write_Ds1302(0x8e,0x00);
for(i=0;i<7;i++)
{
shijian[i]=Read_Ds1302(add);
add=add+2;
}
Write_Ds1302(0x8e,0x80);
}
上述代码:数码管实现时钟显示
然后使用eeprom和ad的iic文件,这里功能就不做过多演示了,会结合后面的初赛题进行练习使用


iic.h:
#ifndef _IIC_H
#define _IIC_H
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
//总线引脚定义
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);
//======================AD转换
unsigned char AD_read(unsigned char add);
//====================E2PROM
//unsigned EEPROM_read(unsigned char add);
void EEPROM_write(unsigned char add,unsigned char dat);
#endif
iic.c:
#include "STC15F2K60S2.h"
#include "intrins.h"
#include "iic.h"
typedef unsigned int uint;
typedef unsigned char uchar;
void IIC_Start()//开始
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
void IIC_Stop(void)//开始
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
void IIC_Ack(uchar 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;
}
}
void IIC_SenByte(uchar byt)//发送数据
{
uchar i;
for(i = 0;i < 8;i++)
{
if (byt & 0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
uchar IIC_RecByte(void)//接收数据
{
uchar da;
uchar i;
for(i = 0;i < 8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if (SDA)
{
da |= 0x01;
}
SCL = 0;
somenop;
}
return da;
}
//======================以下程序都要自己写
uchar AD_read(uchar add)//写进数据,然后读取AD值
{
float temp;
//写地址器件操作
IIC_Start();
IIC_SenByte(0x90);//发送寻址
IIC_WaitAck();
IIC_SenByte(add);//发送0x03,器件地址
IIC_WaitAck();
IIC_Stop();
//读取操作
IIC_Start();
IIC_SenByte(0x91);//发送寻址
IIC_WaitAck();
IIC_SenByte(add);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
uchar EEPROM_read(uchar add)//写进地址
{
uint temp;
IIC_Start();
IIC_SenByte(0xa0);
IIC_WaitAck();
IIC_SenByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SenByte(0xa1);//IIC的读命令操作
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
void EEPROM_write(uchar add, uchar dat)//写进EEPROM需要分别写进地址和数据
{
IIC_Start();
IIC_SenByte(0xa0);//IIC的写命令操作
IIC_WaitAck();
IIC_SenByte(add);
IIC_WaitAck();
IIC_SenByte(dat);
IIC_WaitAck();
IIC_Stop();
}
更多推荐
所有评论(0)