
#include<reg52.h>
#include<intrins.h>
#define U8 unsigned char
#define U16 unsigned int
#define BOOL bit
U8 secondh,secondl,minuteh,minutel,hourh,hourl,second,minute,hour
U8 monthl,monthh,month,day,datel,dateh,date,year,yearl,yearh
/***********定义LCD功能管脚**************************************/
sbit LCDRS = P2^6 //控制LCD数据或命令的读写
sbit LCDRW = P2^5//控制LCD读写信号
sbit LCDEN = P2^7 //使能LCD
/***************************************************************/
/***********定义DS1302功能管脚*********************************/
sbit DSRST = P3^5 //DS1302复位管脚
sbit DSIO = P3^4 //控制DS1302数据传输
sbit DSCLK = P3^6//DS1302时钟
/***************************************************************/
/*******************延时函数***********************************/
void delay(U16 time)
{
U16 time1,time2
for(time1=timetime1>0time1--)
for(time2=110time2>0time2--)
}
/**************************************************************/
/***********检测LCD忙碌状态***********************************/
BOOL judge_lcd()
{
BOOL flag
LCDEN = 0
LCDRS = 0
LCDRW = 1
LCDEN = 1
delay(1)
flag=(BOOL)(P0&0x80) //状态位第7位为1时禁止读写,为0时可读写
LCDEN = 0
return flag
}
/**************************************************************/
/***********实现LCD写指令**************************************/
void write_lcd_command(U16 command)
{
while(judge_lcd()) //检测LCD是否为忙碌状态
P0 = command
LCDRS = 0
LCDRW = 0
LCDEN = 1
delay(1)
LCDEN = 0
}
/***************************************************************/
/***********实现LCD写数据**************************************/
void write_lcd_date(U16 date)
{
while(judge_lcd()) //检测LCD是否为忙碌状态
P0 = date
LCDRS = 1
LCDRW = 0
LCDEN = 1
delay(1)
LCDEN = 0
}
/***************************************************************/
/***********实现LCD写指令及数据********************************/
void write_lcd_com_date(U16 addr,U16 date)
{
write_lcd_command(addr)
delay(1)
write_lcd_date(date)
}
/**************************************************************/
/******************初始化LCD***********************************/
void init_lcd()
{
write_lcd_command(0x38) //设置16x2显示,5x7点阵,8位数据口
delay(1)
write_lcd_command(0x0c) //开显示,不显示光标,光标不闪烁
delay(1)
write_lcd_command(0x06)//读写一个字符后,地址自动加1,不移动屏幕
delay(1)
write_lcd_command(0x01) //清屏
delay(1)
}
/**************************************************************/
/**********************读DS1302********************************/
U8 read_ds1302(U8 addr)
{
U8 i,temp=0x00
DSRST=0
DSIO=1
DSCLK=0
DSRST=1
for (i=0i<8i++) //循环8次 写入地址数据
{
DSCLK=0
DSIO=addr&0x01 //每次传输低字节
addr>>=1 //右移一位
DSCLK=1
}
delay(1)
if(DSIO)
temp|=0x80 //每次传输低字节
DSCLK=0
temp>>=1
for (i=0i<7i++) //循环8次 读取数据
{
DSCLK=0
if(DSIO)
temp|=0x80 //每次传输低字节
DSCLK=1
temp>>=1 //右移一位
}
DSCLK=1
DSRST=0
DSIO=0
return temp //返回
}
/************************************************************/
/******************写DS1302**********************************/
void write_ds1302(U8 addr, U8 date)
{
U8 i
DSRST=0
DSCLK=0
DSRST=1
for (i=0i<8i++) //循环8次 写入地址数据
{
DSCLK=0
_nop_()
DSIO=addr&0x01 //每次传输低字节
addr>>=1 //右移一位
DSCLK=1
_nop_()
}
for (i=0i<8i++) //循环8次 写入数据
{
DSCLK=0
_nop_()
DSIO=date&0x01 //每次传输低字节
date>>=1 //右移一位 DSCLK=1
DSCLK=1
_nop_()
}
DSRST=0
delay(1)
}
/**************************************************************/
/*****************初始化DS1302********************************/
void init_ds1302()
{
//读秒
if((((second=read_ds1302(0x81))>>7)&&0x01)==1)
{
write_ds1302(0x8e,0x00) //关闭写保护
write_ds1302(0x80,0x00) //00秒
write_ds1302(0x82,0x54) //54分
write_ds1302(0x84,0x17) //17点
write_ds1302(0x86,0x14) //14日
write_ds1302(0x88,0x10) //10月
write_ds1302(0x8a,0x05) //星期五
write_ds1302(0x8c,0x11) //2011年
write_ds1302(0x8e,0x80) //允许写保护
}
}
/********************************************************/
/*********************主函数****************************/
void main()
{
init_lcd()
delay(2)
write_lcd_com_date(0x81,'2')
write_lcd_com_date(0x82,'0')
delay(1)
init_ds1302()
delay(1)
while(1)
{
second=read_ds1302(0x81)
secondl=second&0x0f
secondh=second>>4
minute=read_ds1302(0x83)
minutel=minute&0x0f
minuteh=minute>>4
hour=read_ds1302(0x85)
hourl=hour&0x0f
hourh=hour>>4
month=read_ds1302(0x89)
monthl=month&0x0f
monthh=month>>4
year=read_ds1302(0x8d)
yearl=year&0x0f
yearh=year>>4
date=read_ds1302(0x87)
datel=date&0x0f
dateh=date>>4
day=read_ds1302(0x8b)
day=day&0x0f
delay(15)
write_lcd_com_date(0xca,0x30+secondl)
write_lcd_com_date(0xc9,0x30+secondh)
write_lcd_com_date(0xc8,':')
write_lcd_com_date(0xc7,0x30+minutel)
write_lcd_com_date(0xc6,0x30+minuteh)
write_lcd_com_date(0xc5,':')
write_lcd_com_date(0xc4,0x30+hourl)
write_lcd_com_date(0xc3,0x30+hourh)
write_lcd_com_date(0x84,0x30+yearl)
write_lcd_com_date(0x83,0x30+yearh)
write_lcd_com_date(0x85,'-')
write_lcd_com_date(0x87,0x30+monthl)
write_lcd_com_date(0x86,0x30+monthh)
write_lcd_com_date(0x88,'-')
write_lcd_com_date(0x8a,0x30+datel)
write_lcd_com_date(0x89,0x30+dateh)
write_lcd_com_date(0x8c,0x30+day)
}
}
STM32的RTC晶振经常出现不起振的问题,这已经是“业界共识”了。很多人在各种电子论坛上求助类似于“求高手指点!RTC晶振不起振怎么办”的问题,而其答案基本可以概括为“这次高手帮不了你了”更有阴谋论者提出让人啼笑皆非的解释——STM32的RTC晶振不起振是ST与晶振厂商串通后故意搞出来的,目的是提高某晶振厂商高端晶振的销量。
最近做的几块板子也用到了STM32的RTC,前后两版一共做了大概6片,幸运的是并未遇到晶振不起振的现象。而我采用的是3毛钱一个的普通晶振,并未选用传说中低负载高精度晶振。后来在另外一片实验性质的板子上首次遇到了晶振不起振的问题,而且做了2片都不起振,这才让我意识到这个问题的严重性。
从上述现象来看,我认为对RTC晶振起振影响最大的因素应该是PCB的布线。但是遇到问题时通常是PCB已做好,甚至已经做了几百块,没有回头路了。于是大家更关注的问题似乎就是“如何补救”了。在网上搜索一下,你就会发现世界是如此美好!每个人的经验和建议都不一样,甚至是完全相反的!这种现象告诉我们,除了PCB布线,对晶振起振影响最大的似乎不是电气参数,而是另外一种不可忽略的因素——人品!
各种相互矛盾的经验也告诉我们,导致晶振不起振的原因是多种多样的,也是因“人”而异的。也许,我们无法找到一个绝对有效的经验一举解决STM32的RTC晶振这个让人头疼的问题,但我们可以从各种经验中找到一些线索,为最终摸索到适合自己这块板子的解决方案提供一些帮助和提示。
如果晶振不起振,尤其是你已经使用了传说中的爱普生6pF晶振后还是不行,也许你应该尝试对以下几个方面排列组合,找到适合你这块板子的,更容易起振的方式。
下面就罗列一下可能影响RTC晶振起振的因素
1. 晶振的品牌和负载电容
大家貌似都知道要用6pF的晶振,但我发现其实12.5pF的也可以用。大家都说KDS日本原装的好,我那个3毛钱的国产晶振貌似也没啥大问题。。。
2. 晶振外接的匹配电容
有人说6pF的晶振要配6pF的电容。但有经验公式指出这个电容的值应该是晶振本身负载电容的两倍,6pF的晶振应该配10pF的匹配电容,当然12.5pF的就应该配20pF或者22pF的电容了~电容值不匹配可能造成晶振不起振。更神奇的是,有人指出去掉外接的匹配电容会使晶振起振!这似乎没啥道理,但在我的板子上,有且仅有这个方案是可行的!!!
3. 晶振并联的反馈电阻
晶振可以并联一个高阻值的电阻,据说这样更容易起振。。。这个电阻的阻值有人说是1MΩ,有人说是5MΩ,也有人说是10MΩ,,,当然也有人说不能并联这个电阻,并联了反而不起振
4. XTALout到晶振间串联电阻
这种做法是官方的应用笔记指出的,而且给出了这个电阻的计算公式。对这个电阻的的必要性也是众说纷纭,同样存在两种矛盾的说法,即必须要有这电阻,否则不起振。还有一说不能有这个电阻,否则不起振。。。从官方的应用笔记来看,这个电阻的主要作用是保护晶振,以防晶振发热。由此看来这个这个电阻似乎并非影响晶振起振的主要因素,甚至可能让晶振更难起振。
5. 晶振的外壳是否接地
这个就不用说了吧。晶振的外壳是金属的,做封装时可以把那个焊盘做成机械焊盘而悬空,也可以做成电气焊盘,然后连接到GND。对这个说法同样存在争议,有人说外壳必须接地,也有人说接地后反而不起振。
6. 提高Vbat引脚的电源质量
这种说法是有一定道理的,因为RTC部分是由Vbat的来供电的。有人说Vbat引脚对电源质量要求比较高,如果纹波较大可能会影响晶振的起振。网上还有其他人验证过,直接上图(原贴链接:http://www.openedv.com/posts/list/6612.htm )
更有人说反而需要一些噪声,激励晶振产生正反馈从而顺利起振(本人对此表示呵呵)。但不管怎样,提高电源质量对大家都是好事。
7. 晶振周围的环境
有人指出应该仔细清洗RTC晶振周围的电路,甚至是使用环氧树脂胶将晶振密封起来。这种说法得到了一些人的支持,看来也是有相当多的事实依据。
8. 减少晶振焊接时加热的时间
有人认为长时间加热晶振进行焊接会对晶振本身带来影响,却不是彻底损坏晶振,从而使得晶振不容易起振。这种说法我没验证过,个人表示怀疑。。。
9. 焊接的焊锡量
这个种说法感觉就更不靠谱了,但真的有人在晶振引脚上多加了点焊锡晶振就能起振了。从原理上说,多加点焊锡确实会改变晶振和PCB间的寄生参数,但我感觉影响微乎其微。。。可能晶振已经徘徊在临界值的边缘了,这种做法才会起到一点作用。
10. 使用有源晶振
个人认为这是一劳永逸解决晶振不起振问题的不二法门!有人对STM32的RTC晶振不易起振的原因做了一个解释,即出于低功耗的考虑,STM32对晶振的驱动功率比较低,所谓“好鼓不用重锤”,一些差的晶振就需要更高的驱动功率,所以不易起振。我认为这种解释是有道理的。使用有源晶振则不存在驱动功率的问题,如果问题确实是因为驱动功率造成的,那使用有源晶振毫无疑问可以彻底解决问题。而且目前网上还没看到说有源晶振不起振的求助帖。但是有源晶振通常比较昂贵,甚至要比一颗外置的RTC芯片还要贵。至于这个问题的取舍,就要看各位看官自己的想法了。
转载:http://www.wtoutiao.com/p/iaa4LC.html
参考:http://www.openedv.com/posts/list/6612.htm
STM32的RTC晶振不起振的原因及解决方法的更多相关文章
宏晶STC单片机使用STC-ISP串口烧录失败的原因与解决方法汇总
官方网址: http://www.stcisp.com/q_and_a_stcisp.html 个人小结 芯片:STC12C5A60S2 封装:LQFP-48 晶振大小:SD22.1184M 最小系统 ...
单片机stm32F103单片机晶振不起振的原因分析
这是我在做单片机最小系统板时候碰到的问题,之前虽然也做过相似的板子,可是未曾出现过无源晶振不起振的问题.下面是我在遇到问题后的一些检查,排除问题的过程.本人小菜鸟一个,文章中如有错误和不足,还望各位大 ...
STM32的RTC中断标志只能手动清除
背景: 最近在做一个stm32的项目,其中用到RTC的实时时钟功能.时钟源采用外部32.768K晶振,时钟预分频设置为32767,目的是为了产生1秒的中断,然后在中断处理函数中更新实时年月日时分秒. ...
龙邱STM32单片机用J-LINK下载无法被识别的解决方法
问题如下: 按照正常步骤使用keil5给龙邱的stm32下载程序,SWD下载方式提示no cortex-m sw device found,JTAG方式提示no cortex-m device fou ...
STM32库函数void USART_SendData的缺陷和解决方法
void USART_SendData()函数在快速发送时存在问题 有丢数据的可能 转自https://blog.csdn.net/qq_27114397/article/details/506015 ...
STM32的Keil找不到想要flash的解决方法
STM32的Keil找不到想要flash的解决方法:https://blog.csdn.net/qq_38376586/article/details/79582020
stm32 晶振不起振
1. STM32f103有内部晶振.刚刚上电时,所有Clock都是源于内部晶振,所以当片内没有程序或内部程序没有使能外部晶振时,外部晶振是不会起振的.2. STM32f103有内部复位电路,只有当检测 ...
(七)STM32的RTC简单 *** 作
简单说明: /********************************************************************************************* ...
STM32之RTC配置与初始化-rtc.h rtc.c
<rtc.h>#include "stm32f10x.h" #ifndef _RTC_H #define _RTC_H typedef struct { vu8 ho ...
随机推荐
【错误收集】SVN冲突解决 标签: 错误收集 2016-03-13 08:44 624人阅读 评论(24) 收藏
最近在倒代码,这真的是一件挺低效率的事情的,但是为了之后工作的进行,必须把这些已经做好的界面,做好的功能搬到新的框架上来,所以安排了10来个同学一起倒代码,因为大家共用一个解决方案,所以使用svn来进 ...
LeetCode115 Distinct Subsequences
Given a string S and a string T, count the number of distinct subsequences of T in S. (Hard) A subse ...
WPF Binding ElementName方式无效的解决方法--x:Reference绑定
原文:WPF Binding ElementName方式无效的解决方法--x:Reference绑定 需求: 背景:Grid的有一个TextBlock name:T1和一个ListBox,ListBo ...
直击 KubeCon 现场 | 阿里云 Hands-on Workshop 亮点回顾
相关文章链接[合集]规模化落地云原生,阿里云亮相 KubeCon China沉淀九年,一文看清阿里云原生大事件 2019 年 6 月 24 日至 26 日,KubeCon + CloudNativeC ...
Linux 用户he用户组管理
8)系统中有一类用户称为伪用户(psuedo users). 这些用户在/etc/passwd 文件中也占有一条记录,但是不能登陆,因为他们的登陆shell 为空,他们的存在主要是方便系统管理,满足 ...
Round #590 (Div. 3)
拿DIV找快乐... 当场过了A-B1-B2-C 写D差5分钟写的是正解...留坑补FG A. Equalize Prices Again 直接判断sum%n==0?sum/n:sum/n+1 B1, ...
oracle函数 SYS_CONTEXT(c1,c2)
[功能]返回系统c1对应的c2的值.可以使用在SQL/PLSQL中,但不可以用在并行查询或者RAC环境中 [参数] c1,'USERENV' c2,参数表,详见示例 [返回]字符串 [示例] sele ...
@hdu - 6428@ Problem C. Calculate
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 A, B, C,求: \[\sum_{i=1}^{A}\s ...
pytorch更新
Pytorch如何更新版本与卸载,使用pip,conda更新卸载Pytorch 2018年05月22日 07:33:52 醉雨轩Y 阅读数 19047 今天我们主要汇总如何使用使用ubuntu,C ...
H3C V.24接口线缆
如果您将RTC和串口屏连接到设备主板上,但是串口屏无法读取RTC的时间信息,可能有以下几个原因:1. 连接问题:请确保RTC和串口屏的连接正确,例如连接线是否插好、是否松动等。
2. 电源问题:请确保RTC和串口屏都有足够的电源供应,例如电池或者外部电源。
3. 代码问题:请检查您的代码是否正确,例如是否正确设置了串口屏的波特率、数据位、停止位等参数,是否正确读取RTC的时间信息。
4. 软件问题:请检查您使用的串口屏驱动程序或者库文件是否正确,是否支持您使用的设备主板和RTC模块。
如果以上方法都无法解决问题,建议您联系设备主板和串口屏的生产厂家或者技术支持人员,寻求更专业的帮助。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)