历史上的今天
返回首页

历史上的今天

今天是:2025年01月17日(星期五)

正在发生

2021年01月17日 | MSP430G2553开发板万年历加温湿度

2021-01-17 来源:eefocus

材料:MSP430G2553开发板一块、DS1302时钟芯片、CR1220纽扣电池、CR1220纽扣电池、32.768Khz晶振、小纽扣按键三个、DHT11温湿度传感器、跳帽三个、LCD12864(自带电位器,3.3v供电需要调节对比度)


一、DS1302

DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时。DS1302采用三线SPI接口与单片机通讯,在进行一次读写操作时,我们要先发送控制字(要进行得操作和相应寄存器地址),然后对该寄存器写入数据或者读出数据。

DS1302读时隙:

 

控制字在串行时钟SCLK每个上升沿将一位数据读入,将一个字节(8位)控制字写入后,读出数据,读出数据在串行时钟SCLK每个下降沿读出一位数据,写入数据和读出数据得时钟沿刚好相反。无论是读出数据还是写入数据,都是从低位到高位的读(写)。

DS1302写时隙:

写时隙也是和读差不多,首先写入一个字节的控制字,也就是我们要进行的操作和相关寄存器地址,不同在于在每个串行时钟SCLK每个上升沿写入一位数据,传输8位控制字后写入数据,无论是控制字还是数据,都是从低位到高位写入(读出)。


我们一般只对DS1302时间相关的寄存及写入和读出数据,和时间相关的寄存器如下:

 

秒寄存器(0x80写,0x81读):BIT7为’1‘时,时钟停止。其他位位秒的数据位。

小时寄存器(0x82写,0x83读):BIT7为’1‘为12小时模式,为’0‘为24小时模式

                                                     在十二小时模式,BIT5表示上下午标志位,BIT5                                                               为'1'表示下午。在24小时模式,BIT5是第二个10小                                                         时位。

控制寄存器(0x8f写,0x8e读):BIT0~BIT6全为0,BIT7位’1‘为写保护,写保护状态下禁止向任何一个寄存器写入数据。

二、DHT11


 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。DHT11   DATA接口是用于与单片机通讯和同步,DHT11一次传输的数据为40位(5个字节),DHT11传输数据时是从高到低传输,这个与DS1302不同,DS1302传输数据是从低位到高位传输。数据格式:8BIT湿度整数数据+8BIT湿度小数数据 +8BIT温度整数数据+8BIT温度小数数据 +8BIT校验和。


其中,8位校验和=8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据。


单片机与DHT11通讯过程:

1.单片机发送开始信号。DHT11总线空闲时位高点平,单片机把总线电平拉低,在拉低电平总线要大于18ms。

2.DHT11收到开始信号后发送80us的低电平响应信号。单片机检测总线位低电平,说明DHT11收到开始信号,把总线拉高80us准备准备发送数据。

3.单片机接收数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1。数据为“0”:50us的低电平 + 26-28us的高电平

数据为“1”:50us的低电平 + 70us的高电平

4.数据传输完毕,单片机拉低总线50us,总线进入空闲状态。


DHT11不会主动去采集数据,只有当收到单片机发来的开始信号后DHT11开始采集数据,并发送40BIT数据。


三、原理图

 

四、PCB:


五、实物图:

 

                                 

六、代码:


#include "msp430g2553.h"

#include "in430.h"

#include "stdio.h"

#include "string.h"

#define uint unsigned int

#define uchar unsigned char

#define ulong unsigned long

//标题定义

unsigned char aa[14]={"万年历加温湿度"};

unsigned char bb[4]={"日期"};

unsigned char cc[4]={"时间"};

unsigned char flag,flag1,s1num,value;//flag不掉电用标志,flag1时钟暂停标志,s1num功能键按下去的次数,value存放数据的值

signed char year,month,date,hour,minute,second,week;//

char dis_buf[16]; //lcd上排显示缓冲区

char day[7][10]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

char ch;

char ch1;

int *R;

int s=0,g=0;

int f = 1;

char str[];

int f1 = 0;

int f2 = 0;

int lacktime = 0;

unsigned char  digit[]={"0123456789"};//定义字符数组显示数字

#define SCLK BIT0  //E

#define SID  BIT1  //R/W

#define CS   BIT2  //RS

#define LCDPORT P2OUT

#define SID_1  LCDPORT |= SID

#define SID_0  LCDPORT &= ~SID

#define SCLK_1 LCDPORT |= SCLK

#define SCLK_0 LCDPORT &= ~SCLK

#define CS_1   LCDPORT |= CS

#define CS_0   LCDPORT &= ~CS

#define CLK_1 P2OUT|=BIT5//1302芯片时钟端口

#define CLK_0 P2OUT&=~BIT5

#define CLK_OUT P2DIR|=BIT5

#define CLK_IN P2DIR&=~BIT5

#define DATA_1 P2OUT|=BIT4//1302芯片数据端口

#define DATA_0 P2OUT&=~BIT4

#define DATA_OUT P2DIR|=BIT4

#define DATA_IN  P2DIR&=~BIT4

#define DATA (P2IN&BIT4)

#define RST_1 P2OUT|=BIT3//复位端口

#define RST_0 P2OUT&=~BIT3

#define RST_OUT P2DIR|=BIT3

#define RST_IN P2DIR&=~BIT3

//宏定义DS1302数据地址

 #define write_second 0x80

 #define read_second 0x81

 #define write_minute 0x82

 #define read_minute 0x83

 #define write_hour 0x84

 #define read_hour 0x85

 #define write_date 0x86

 #define read_date 0x87

 #define write_month 0x88

 #define read_month 0x89

 #define write_year 0x8c

 #define read_year 0x8d

 #define write_day 0x8a

 #define read_day 0x8b

 #define write_protect 0x8e

 #define write_power 0x90

uint i=0;

//温湿度数据变量

uint com_data,respond,temp,untemp;

uint TH_data,TL_data,RH_data,RL_data,CK_data;

uint TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;

uchar s1num,num,shis,shig,wens,weng;

//延时程序

#define CPU_F ((double)1000000)

#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))

#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

void Uart0Sends(uchar *s);

void sendbyte(unsigned char data);

void write_cmd(uchar cmd);

void lcd_pos(uchar x,uchar y);

void Checkin();

void Init_RxTx();

void delay(unsigned int t)

{

unsigned int i,j;

for(i=0; i

for(j=0; j<3; j++);

}

void sendbyte(unsigned char data)

{

unsigned int i;

for(i=0;i<8;i++)

{

if((data<{

SID_1;

}

else

{

SID_0;

}

SCLK_0;

SCLK_1;

}

}

void write_cmd(uchar cmd)

{

CS_1;

sendbyte(0xf8);

sendbyte(cmd&0xf0);

sendbyte((cmd<<4)&0xf0);

delay(1);

}

void write_dat(uchar dat)

{

CS_1;

sendbyte(0xfa);

sendbyte(dat&0xf0);

sendbyte((dat<<4)&0xf0);

delay(1);

}

void lcd_pos(uchar x,uchar y)

{

  uchar pos;

  switch(x)

  {

    case 1:pos=0x80;break;

    case 2:pos=0x90;break;

    case 3:pos=0x88;break;

    case 4:pos=0x98;break;

    default:pos=0x80;

  }

  pos += y;

  write_cmd(pos);

}

void lcd_string(char *s)

{

unsigned char lcd_temp;

lcd_temp=*s;

while(lcd_temp!=0x00)

{

write_dat(lcd_temp);

lcd_temp=*(++s);

}

}

//LCD12864初始化

void LCD_init(void)

{

    write_cmd(0x01);//清除显示

    delay_ms(5);

    write_cmd(0x30);//功能设定

    delay_ms(5);

    write_cmd(0x02);//地址归为

    delay_ms(5);

    write_cmd(0x0C);//整体显示ON

    delay_ms(5);

    write_cmd(0x06);//指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位

    delay_ms(5);

}

//

void Write1302(unsigned char dat)

{

uchar i;

DATA_OUT;

CLK_0;

delay_us(2);

for(i=0;i<8;i++)

{

if(dat&0x01)

DATA_1;

else DATA_0;

delay_us(2);

CLK_1;

delay_us(2);

CLK_0;

dat>>=1;

}

}

void WriteSet1302(uchar Cmd,uchar dat)

{

RST_0;

CLK_0;

RST_1;

delay_us(2);

Write1302(Cmd);

Write1302(dat);

CLK_1;

RST_0;

}

uchar Read1302(void)

{

uchar i,dat;

DATA_IN;//

DATA_0;//

delay_us(2);

for(i=0;i<8;i++)

{

dat>>=1;

if(DATA!=0)

dat|=0x80;

else dat&=0x7f;

CLK_1;

delay_us(2);

CLK_0;

delay_us(2);

}

DATA_OUT;//

return dat;

}

uchar ReadSet1302(uchar Cmd)

{

uchar dat;

RST_0;

CLK_0;

RST_1;

Write1302(Cmd);

dat=Read1302();

CLK_1;

RST_0;

return dat;

 }

//初始化DS1302的程序

void ds1302_init(void)

{

flag= ReadSet1302(0x81);

if(flag&0x80) //判断时钟芯片是否关闭,即可不掉电

{

WriteSet1302(write_protect,0x00);//关闭写保护

WriteSet1302(write_second,0x45); //根据写秒寄存器命令字,写入秒的初始值

WriteSet1302(write_minute,0x24); //根据写分寄存器命令字,写入分的初始值

WriteSet1302(write_hour,0x09); //根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(write_date,0x13); //根据写日寄存器命令字,写入日的初始值

WriteSet1302(write_month,0x04); //根据写月寄存器命令字,写入月的初始值

WriteSet1302(write_year,0x16); //根据写年寄存器命令字,写入年的初始值

WriteSet1302(write_day,0x07); //周日

WriteSet1302(write_power,0xa5); //一个二极管压降,电阻4K

WriteSet1302(write_protect,0x80);//打开写保护

}

}

//DS1302数据处理函数,此函数将个位、十位分别用char表示,方便用数码管显示

void DisplaySecond(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(3,6);

//delay_ms(500);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void DisplayMinute(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(3,4);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void DisplayHour(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(3,2);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void DisplayDate(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(2,6);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void DisplayMonth(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(2,4);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void DisplayWeek(char we)

{

lcd_pos(4,3);

dis_buf[0]=day[we-1][0];

dis_buf[1]=day[we-1][1];

dis_buf[2]=day[we-1][2];

dis_buf[3]=day[we-1][3];

dis_buf[4]=day[we-1][4];

dis_buf[5]=day[we-1][5];

dis_buf[6]=day[we-1][6];

dis_buf[7]=day[we-1][7];

dis_buf[8]=day[we-1][8];

dis_buf[9]=day[we-1][9];

lcd_string(dis_buf);

}

void DisplayYear(unsigned char x)

{

unsigned char i,j;

i=x/10;//取十位

j=x;//取个位

lcd_pos(2,2);

write_dat(digit[i]);

write_dat(digit[j]);

delay_ms(50);

}

void IO_init(void)

{

 ///12864和1302端口定义///

 P2SEL&=~(BIT0 + BIT1 + BIT2);//P2.0,P2.1,P2.2 为I/O端口

 P2DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5;

 CLK_OUT;

 DATA_OUT;

 RST_OUT;

 ///按键端口定义///

 P1DIR&=~(BIT7+BIT5+BIT4+BIT3);   //输入

 P1DIR |= BIT6;

 P1OUT|=(BIT7+BIT5+BIT4);//P1输出为1

 P1OUT &=~ (BIT6+BIT3);

 P1REN|=BIT7+BIT5+BIT4;      //用于按键接地型

 P1IE|=BIT7+BIT5+BIT4+BIT3;       //允许中断

 P1IES|=BIT7+BIT5+BIT4;   //下升沿触发

 P1IFG&=~(BIT7+BIT5+BIT4+BIT3);   //消除中断标志

}

void DCO_init(void)

{

    BCSCTL1 = CALBC1_1MHZ;  //设定cpu时钟DCO频率为1MHz

    DCOCTL = CALDCO_1MHZ;

}

void display()

{

lcd_pos(1,0);//标题

for(i=0;i<14;i++)

{

 write_dat(aa[i]);

}

lcd_pos(2,0);//日期

for(i=0;i<4;i++)

{

 write_dat(bb[i]);

}

lcd_pos(3,0);//时间

for(i=0;i<4;i++)

{

 write_dat(cc[i]);

}

}

///标志位初始化///

void init_flag(void)

{

flag1=0;

}

//收发信号检测,数据读取

char receive()

{

          uint i;

          com_data=0;

          P1DIR &=~ BIT0;

          for(i=0;i<=7;i++)

         {

                    respond=2;

                    while((!(P1IN&BIT0))&&respond++);

                    delay_us(20);

                    if(P1IN&BIT0)

                    {

                              temp=1;

推荐阅读

史海拾趣

台湾富致(FUZETEC)公司的发展小趣事

为了更好地服务于中国市场,Futaba在2002年成立了双叶电子科技开发(北京)有限公司。该公司专营Futaba的全线产品,包括VFD真空荧光显示管和RC无线遥控设备等。这一举措标志着Futaba在全球化布局上迈出了重要一步,也为公司在中国市场的快速发展奠定了基础。北京分公司的成立不仅加强了Futaba与中国客户的联系,还促进了公司在技术、产品和市场等方面的全方位合作。

General Cable公司的发展小趣事
内部设计有抑制噪声的机制,确保信号传输的稳定性和可靠性。
Anvo-Systems公司的发展小趣事

Anvo-Systems深知人才是企业发展的核心动力。因此,公司一直注重与高校和研究机构的合作,共同开展电子技术的研发与创新。通过与高校合作开展科研项目、设立奖学金等方式,Anvo-Systems吸引了大批优秀的人才加入公司。同时,公司还建立了完善的培训体系,为员工的职业发展提供了有力支持。这些举措不仅提升了公司的研发实力,也为公司的未来发展储备了丰富的人才资源。

CLANDELL公司的发展小趣事

随着公司规模的扩大,CLANDELL公司开始积极履行社会责任。公司不仅关注自身的经济效益,还积极参与公益事业和环保活动。同时,公司还注重员工的福利待遇和职业发展,为员工提供良好的工作环境和培训机会。这些举措不仅提升了CLANDELL公司的社会形象,也为公司的可持续发展注入了新的动力。

这五个故事只是CLANDELL公司发展过程中的一部分,它们展示了公司在电子行业中的崛起之路,也反映了公司不断追求卓越、勇于创新的精神风貌。

Catalyst / ON Semiconductor公司的发展小趣事

随着技术的不断进步,Catalyst / ON Semiconductor公司逐渐在半导体领域取得了重要的技术突破。公司投入大量资源进行研发,成功开发出了一系列高性能、低功耗的半导体产品,这些产品在市场上受到了广泛的欢迎。这些技术突破不仅提升了公司的市场竞争力,也为整个电子行业的发展注入了新的活力。

Bellin Dynamic Systems公司的发展小趣事

Bellin Dynamic Systems在电子行业中以其创新技术而著称。某年,公司成功研发出一款高效能、低能耗的芯片,这款芯片在行业内引起了巨大反响。凭借这一技术突破,Bellin Dynamic Systems迅速获得了多家大型电子设备制造商的合作意向,市场份额迅速扩大。公司借此机会加大了研发投入,进一步巩固了其在行业内的技术领先地位。

问答坊 | AI 解惑

哪位大侠用过片内的可编程放大器及滤波器???

这是24位AD转换器的资料 我想用到片内的可编程放大器及滤波器 但不知如何用单片机对其内部寄存器编程 有人用过么…

查看全部问答>

【藏书阁】中兴通讯EDA工具手册

序  言 第一章   系统简介 1  系统组成 1.1  库 1.2  原理图输入 1.3  设计转换和修改管理 1.4  物理设计与加工数据的生成 1.5  高速 PCB 规划设计环境 ...…

查看全部问答>

这电路能跑起来吗

图中的D8实现半波整流,固体继电器还能过零检测吗?…

查看全部问答>

暂时没分了,此贴会加分,请教:怎样才能在PB里安装NETCFv35.wce.armv4.cab的内容?而不是在设备上安装

NETCFv35.wce.armv4.cab的管方做法是在设备上安装,但是对于大规模生产这个方法不可取。 我们想在PB里直接安装NETCFv35.wce.armv4.cab, 这样编译NK.BIN时,里面就包含了.net cf v3.5; 请教怎么做呢? 非常抱歉现在没分了,但是这个贴子我会加 ...…

查看全部问答>

任意分频的verilog的实现

好久没有来发自己的成果了,好不容易整理一份出来啦~希望大家给些意见~…

查看全部问答>

大家功率放大模块做得怎样啦?有不用BUF634就做出来比较好效果的么

本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 大家功率放大模块做得怎样啦?有不用BUF634就做出来比较好效果的么? 比如带宽多少?负载多少?电流多大?输入信号幅度多大? 我们用通用运放搭的,也做了扩流,可波形出来就是失真啊…… &nb ...…

查看全部问答>

求cyclone II ep2c8t144c8n的原理引脚图

急求cyclone II ep2c8t144c8n的原理引脚图…

查看全部问答>

参与Silicon Labs 2014技术创新巡回研讨会,赢新颖大礼

    由中国最大本土分销企业世强携手业界领先的高性能混合信号IC供应商Silicon Labs举办的创新技术巡回研讨会将于近期全面启动。本次研讨会主要针对在职研发工程师,Silicon Labs的资深技术专家将亲临现场,带来处于创新最前沿的设计技术 ...…

查看全部问答>

430用iar如何校准

手册上说g2553最高频率是26mhz,那怎么设置它的频率呢。 BCSCTL1 = CALBC1_16MHZ;                     DCOCTL = CALDCO_16MHZ; 我用上面的代码,为啥编译错误呢,求 ...…

查看全部问答>