历史上的今天
今天是: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;
史海拾趣
|
序 言 第一章 系统简介 1 系统组成 1.1 库 1.2 原理图输入 1.3 设计转换和修改管理 1.4 物理设计与加工数据的生成 1.5 高速 PCB 规划设计环境 ...… 查看全部问答> |
|
暂时没分了,此贴会加分,请教:怎样才能在PB里安装NETCFv35.wce.armv4.cab的内容?而不是在设备上安装 NETCFv35.wce.armv4.cab的管方做法是在设备上安装,但是对于大规模生产这个方法不可取。 我们想在PB里直接安装NETCFv35.wce.armv4.cab, 这样编译NK.BIN时,里面就包含了.net cf v3.5; 请教怎么做呢? 非常抱歉现在没分了,但是这个贴子我会加 ...… 查看全部问答> |
|
大家功率放大模块做得怎样啦?有不用BUF634就做出来比较好效果的么 本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 大家功率放大模块做得怎样啦?有不用BUF634就做出来比较好效果的么? 比如带宽多少?负载多少?电流多大?输入信号幅度多大? 我们用通用运放搭的,也做了扩流,可波形出来就是失真啊…… &nb ...… 查看全部问答> |
|
参与Silicon Labs 2014技术创新巡回研讨会,赢新颖大礼 由中国最大本土分销企业世强携手业界领先的高性能混合信号IC供应商Silicon Labs举办的创新技术巡回研讨会将于近期全面启动。本次研讨会主要针对在职研发工程师,Silicon Labs的资深技术专家将亲临现场,带来处于创新最前沿的设计技术 ...… 查看全部问答> |
|
手册上说g2553最高频率是26mhz,那怎么设置它的频率呢。 BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; 我用上面的代码,为啥编译错误呢,求 ...… 查看全部问答> |




