stc15f204单片机使用ds1302调试

使用stc单片机的准IO口模式,驱动能力太弱,导致操作1302不正常,逻辑分析仪看到是写给1302的地址就出错了,但正常和错误交替出现,非常奇怪,后来把IO配置为推挽输出后,可以稳定读写1302,附程序:

一部分程序操作也是在网上下载的,使用下面的程序可以正常读写ds1302.


#include "ds1302.h"


#define ds1302_sec_add 0x80 //秒数据地址
#define ds1302_min_add 0x82 //分数据地址
#define ds1302_hr_add 0x84 //时数据地址
#define ds1302_date_add 0x86 //日数据地址
#define ds1302_month_add 0x88 //月数据地址
#define ds1302_day_add 0x8a //星期数据地址
#define ds1302_year_add 0x8c //年数据地址
#define ds1302_control_add 0x8e //控制数据地址
#define ds1302_charger_add 0x90


sbit CS = P1^3;
sbit SCLK = P1^4;
sbit SDA = P1^5;


BYTE ds1302_read(BYTE cmd);
void ds1302_write(BYTE cmd,BYTE dat);
BYTE bcd_to_dec(BYTE value);
BYTE dec_to_bcd(BYTE value);


void ds1302_init(void)
{
SDA = 0;
SCLK = 0;
CS = 0;
}


BYTE get_curr_hour(void)
{
return bcd_to_dec(ds1302_read(ds1302_hr_add));
}


BYTE get_curr_minute(void)
{
return  bcd_to_dec(ds1302_read(ds1302_min_add));
}


void save_curr_hour(BYTE value)
{
value = dec_to_bcd(value);
EA = 0;
ds1302_write(ds1302_control_add, 0x00); //关闭写保护
ds1302_write(ds1302_sec_add,0x80);   //暂停
ds1302_write(ds1302_hr_add, value);
ds1302_write(ds1302_sec_add,0x00);   //开启
ds1302_write(ds1302_control_add, 0x80); //打开写保护
EA = 1;
}


void save_curr_minute(BYTE value)
{
value = dec_to_bcd(value);
ds1302_write(ds1302_control_add, 0x00); //关闭写保护
ds1302_write(ds1302_sec_add,0x80);   //暂停
ds1302_write(ds1302_min_add, value);
ds1302_write(ds1302_sec_add,0x00);   //开启
ds1302_write(ds1302_control_add, 0x80); //打开写保护
}


void ds1302_write(BYTE cmd,BYTE dat)
{
BYTE dattmp = 0;
BYTE i = 0;

P1M0 |= 0x20;  //1 << 5 //一定要配置为强上啦输出
P1M1 &= 0xdf;  // ~(1 << 5)


CS=1;// 初始CE置为1 ,传输开始
//ds1302_write_byte(cmd);//传输命令字,要写入的时间日历地址
//ds1302_write_byte(dat);// 写入要修改的时间 /日期
dattmp = cmd;
for(i = 0; i < 8; ++i)// 开始传输8个字节的数据
{
if(dattmp & 0x01){ // 取最低位,注意ds1302的数据和地址都是从最低位开始传输的
SDA = 1;
}else{
SDA = 0;
}
delay2us();
SCLK=1; //时钟线拉高,制造上升沿,SDA的数据被传输
delay2us();
SCLK=0; //时钟线拉低,为下一个上升沿做准备
dattmp >>= 1; // 数据右移一位,准备传输下一位数据
}
dattmp = dat;
for(i = 0; i < 8; ++i)// 开始传输8个字节的数据
{
if(dattmp & 0x01){ // 取最低位,注意ds1302的数据和地址都是从最低位开始传输的
SDA = 1;
}else{
SDA = 0;
}
delay2us();
SCLK=1; //时钟线拉高,制造上升沿,SDA的数据被传输
delay2us();
SCLK=0; //时钟线拉低,为下一个上升沿做准备
dattmp >>= 1; // 数据右移一位,准备传输下一位数据
}
CS=0;// 读取结束,CE置为0,结束数据的传输
//SCLK=1;// 时钟线拉高  这个线不能拉高,否则出错
SDA = 1;
P1M1 &= 0xdf;
P1M0 &= 0xdf;
}


BYTE ds1302_read(BYTE cmd)
{
BYTE dat = 0;
BYTE cmdtmp = cmd;
BYTE dattmp = 0;
BYTE i = 0;
P1M1 &= 0xdf;//要先把io配置为强上拉输出
P1M0 |= 0x20;
CS=1; // 初始CE置为1 ,传输开始
cmdtmp |= 0x01;//读命令的最低位固定为1
dattmp = cmdtmp;
for(i = 0; i < 8; ++i)// 开始传输8个字节的数据
{
if(dattmp & 0x01){ // 取最低位,注意ds1302的数据和地址都是从最低位开始传输的
SDA = 1;
}else{
SDA = 0;
}
delay2us();
SCLK=1; //时钟线拉高,制造上升沿,SDA的数据被传输
delay2us();
SCLK=0; //时钟线拉低,为下一个上升沿做准备
dattmp >>= 1; // 数据右移一位,准备传输下一位数据
}
//
P1M1 &= 0xdf; //准io口方式
P1M0 &= 0xdf;
SDA = 1;
delay2us();
for(i=0;i<8;i++)
{
dat >>= 1; // 要返回的数据右移一位
 
if(SDA == 1){ //当数据线为高时,证明该位数据为1
dat|=0x80; // 要传输数据的当前值置为1,若不是 ,则为0
}
SCLK=1; //拉高时钟线
delay2us();
SCLK=0; //制造下降沿
SDA = 1;
delay2us();
}
CS=0; // 读取结束,CE置为0,结束数据的传输
//SCLK=1; // 时钟线拉高 ,这个线不能拉高,否则出错
return dat;// 返回得到的时间/ 日期
}


BYTE bcd_to_dec(BYTE value)
{
BYTE tmp = 0;
tmp = ((value & 0xf0) >> 4) * 10 + (value & 0x0f);
return tmp;
}


BYTE dec_to_bcd(BYTE value)
{
BYTE tmp = 0;
tmp = ((value / 10) << 4) & 0xf0;
tmp |= (value % 10) & 0x0f;
return tmp;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
stc15w4k32s4是一款基于MCS-51核心的单片机,具有高性能、低功耗和易于编程的特点。而ds18b20是一款数字温度传感器,采用单总线接口进行通信,具有高精度、稳定可靠的特点。将这两款器件联合起来进行温度检测,是很多纳电子学、嵌入式系统和物联网等领域中常用的应用。 首先,需要进行硬件连接。要想实现stc15w4k32s4与ds18b20的通信,需要将它们的引脚进行连接。具体地,ds18b20的DQ引脚与stc15w4k32s4的任意I/O口连接即可(这里我们选用P3.7口)。同时,为了保证ds18b20的供电,需要将它的VDD引脚连接至正电源,而它的GND引脚则需要连接至地。 接下来,需要进行程序仿真。首先,要在程序中定义ds18b20传感器的通信命令,这些命令可以从ds18b20的数据手册中获取。然后,需要进行初始化,包括设置芯片的时钟频率、I/O口的工作模式等,以确保芯片正常工作。接着,就可以进行温度检测了。在程序中,我们读取ds18b20发送的温度数据,将其转换为实际温度值,再将温度值以数字表示的方式输出到OLED屏幕或其他外设上。 最后,我们需要进行调试和优化。在检测温度时,可能会因为传感器精度不够、通信错误等原因出现误差。因此,在实际应用中,需要不断地进行调试和优化,以提高系统的精度和稳定性。 总之,在stc15w4k32s4单片机中链接ds18b20温度检测仿真,需要进行硬件连接、程序编写及调试等一系列操作,它是一项应用十分广泛的技术。通过温度检测,我们可以实现对环境的监测和控制,为各种应用提供有力的技术支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值