#include "msp430x26x.h"
#define uchar unsigned char
#define uint unsigned int
#define iDat 1 //数据标志
#define iCmd 0 //指令标志
#define LCDb_RS 0x20 //定义四个控制引脚
#define LCDb_RW 0x40
#define LCDb_E 0x80
#define LCDb_RST 0x04
#define LCDb_L1 0x80 //第一行的地址
#define LCDb_L2 0x90 //第二行的地址
#define LCDb_L3 0x88 //第三行的地址
#define LCDb_L4 0x98 //第四行的地址
#define LCDb_SET_RS P1OUT|=LCDb_RS //四个控制管脚的控制 *** 作
#define LCDb_SET_RW P1OUT|=LCDb_RW
#define LCDb_SET_E P1OUT|=LCDb_E
#define LCDb_SET_RST P8OUT|=LCDb_RST
#define LCDb_CLR_RS P1OUT&=~LCDb_RS
#define LCDb_CLR_RW P1OUT&=~LCDb_RW
#define LCDb_CLR_E P1OUT&=~LCDb_E
#define LCDb_CLR_RST P8OUT&=~LCDb_RST
#define LCDb_DO P4OUT //输出数据总线端口定义
#define LCDb_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符
#define LCDb_BASCMD 0x30 // 基本指令集
#define LCDb_CLS 0x01 // 清屏
#define LCDb_HOME 0x02 // 地址返回原点,不改变DDRAM内容
#define LCDb_ENTRY 0x06 // 设数春定输入模式,光标加,屏幕不移动
#define LCDb_C2L 0x10 // 光标左移
#define LCDb_C2R 0x14 // 光标右移
#define LCDb_D2L 0x18 // 屏幕左移
#define LCDb_D2R 0x1C // 屏幕又移
#define LCDb_ON 0x0C // 打开显示
#define LCDb_OFF 0x08 //告野 关闭显示
unsigned char RXData
unsigned char Seg_Data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} //数码管袜毕喊编码
unsigned char Result[5] //整数转化成字符串,给LCD显示
void Delayms(uint MS)
{
uint i,j
for( i=0i<MSi++)
for(j=0j<1141j++)
}
void Delayus(uint US)
{
uint i
US=US*5/4
for( i=0i<USi++)
}
void LCD12864_portini()
{
P1DIR=0xFF
P4DIR=0xFF
P5DIR=0xFF
P8DIR=0xFF
P8OUT |=LCDb_RST
//P1OUT=0xFF
}
/*函数名称: LCD12864_sendbyte
功能: 向12864液晶写入一个字节数据或者指令
*/
void LCD12864_sendbyte(uchar DatCmd, uchar dByte)
{
if (DatCmd == iCmd) //指令 *** 作
LCDb_CLR_RS
else
LCDb_SET_RS
LCDb_CLR_RW //写 *** 作
LCDb_SET_E
LCDb_DO = dByte //写入数据
//Delayus(500)
Delayms(1)
LCDb_CLR_E
}
/*函数名称: LCD12864_sendstr
功能: 向12864液晶写入一个字符串
参数: ptString--字符串指针
返回值 : 无
*/
void LCD12864_sendstr(uchar *ptString)
{
while((*ptString)!='\0') //字符串未结束一直写
{
LCD12864_sendbyte(iDat, *ptString++)
}
}
/*函数名称: LCD12864_clear
功能: 12864液晶清屏
参数: 无
返回值 : 无
*/
void LCD12864_clear(void)
{
LCD12864_sendbyte(iCmd,LCDb_CLS)
Delayms(2)// 清屏指令写入后,2ms 的延时是很必要的!!!
}
/*
函数名称: LCD12864_gotoXY
功能: 移动到指定位置
参数: Row--指定的行
Col--指定的列
返回值 : 无
*/
void LCD12864_gotoXY(uchar Row, uchar Col)
{
switch (Row) //选择行
{
case 2:
LCD12864_sendbyte(iCmd, LCDb_L2 + Col)break //写入第2行的指定列
case 3:
LCD12864_sendbyte(iCmd, LCDb_L3 + Col)break //写入第3行的指定列
case 4:
LCD12864_sendbyte(iCmd, LCDb_L4 + Col)break //写入第4行的指定列
default:
LCD12864_sendbyte(iCmd, LCDb_L1 + Col)break //写入第1行的指定列
}
}
/*
函数名称: LCD12864_initial
功能: 12864液晶初始化
*/
void LCD12864_initial(void)
{
Delayms(100) // 等待内部复位
LCD12864_portini() //端口初始化
LCD12864_sendbyte(iCmd, LCDb_FUNCTION) //功能、模式设定
LCD12864_sendbyte(iCmd, LCDb_ON) //打开显示
LCD12864_clear() //清屏
LCD12864_sendbyte(iCmd, LCDb_ENTRY) // 输入模式设定
}
void Int_char(int data)
{
if(data/1000)
{
Result[0]=data/1000+'0'
Result[1]=data/100%10+'0'
Result[2]=data/10%10+'0'
Result[3]=data%10+'0'
Result[4]=0
}
else if(data/100)
{
Result[0]=data/100+'0'
Result[1]=data/10%10+'0'
Result[2]=data%10+'0'
Result[3]=0
}
else if(data/10)
{
Result[0]=data/10%10+'0'
Result[1]=data%10+'0'
Result[2]=0
}
else
{
Result[0]=data%10+'0'
Result[1]=0
}
}
unsigned char Key_Press(void)
{
P7OUT=0xF0
if((P7IN&0x10)&&(P7IN&0x20)&&(P7IN&0x40)&&(P7IN&0x80)) return 0x00
else return 0xFF
}
unsigned char Get_Keycode(void)
{
while(1)
{
P7OUT=0xFE //扫描第一列
if((P7IN&0x10)==0) return 0
else if((P7IN&0x20)==0) return 4
else if((P7IN&0x40)==0) return 8
else if((P7IN&0x80)==0) return 12
P7OUT=0xFD //扫描第二列
if((P7IN&0x10)==0) return 1
else if((P7IN&0x20)==0) return 5
else if((P7IN&0x40)==0) return 9
else if((P7IN&0x80)==0) return 13
P7OUT=0xFB //扫描第三列
if((P7IN&0x10)==0) return 2
else if((P7IN&0x20)==0) return 6
else if((P7IN&0x40)==0) return 10
else if((P7IN&0x80)==0) return 14
P7OUT=0xF7 //扫描第四列
if((P7IN&0x10)==0) return 3
else if((P7IN&0x20)==0) return 7
else if((P7IN&0x40)==0) return 11
else if((P7IN&0x80)==0) return 15
}
}
void Init_compa()
{
CACTL1 = CAON+CAREF_2+CARSEL// Enable Comp, ref = 0.5*Vcc = Vin-
CACTL2 = P2CA0 // Pin to CA0
P1DIR |= 0x01 // P1.0 = o/p direction(CAOUT - LED)
P1SEL |= 0x01 // P1.0 - CAOUT, option select
}
/*
** 函数名称:初始化函数
*/
void Init_IIC(void)
{
P3SEL |= 0x06 // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC// I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST // Use SMCLK, keep SW reset
UCB0BR0 = 12// fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0
UCB0I2CSA = 0x50 // Slave Address is 048h
UCB0CTL1 &= ~UCSWRST// Clear SW reset, resume operation
IE2 |= UCB0RXIE // Enable RX interrupt
_BIS_SR(GIE)
// RXCompare = 0x0 // Used to check incoming data
}
/** 函数名称:字节写函数
*/
void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word)
{
while (UCB0CTL1 &UCTXSTP) // 确定总线空闲
UCB0CTL1 |= UCTXSTT + UCTR // 发送起始位,确定为发送模式
UCB0TXBUF = high_Address// 发送高位地址
while((IFG2 &UCB0TXIFG)==0) // 判断是否发送完毕
UCB0TXBUF = low_Address // 发送低位地址
while((IFG2 &UCB0TXIFG)==0) // 判断是否发送完毕
UCB0TXBUF = Word// 发送数据
while((IFG2 &UCB0TXIFG)==0) // 判断是否发送完毕
UCB0CTL1 |= UCTXSTP // 发送停止位
while((UCB0CTL1 &UCTXSTP)==1) // 判断停止位是否发送完毕
}
/**
** 函数名称:字节读函数
*/
void EEPROM_readmore()
{
UCB0CTL1 &= ~UCTR // 确定为读
while (UCB0CTL1 &UCTXSTP) // 总线是否空闲
UCB0CTL1 |= UCTXSTT// 发送开始位
}
/*
** 函数名称:字节写函数
**/
void EEPROM_read(unsigned char high_Address,unsigned char low_Address)
{
while (UCB0CTL1 &UCTXSTP) // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT + UCTR // 发送起始位,确定为写
UCB0TXBUF = high_Address// 发送地址位高位
while((IFG2 &UCB0TXIFG)==0) // 判断是否发送完毕
UCB0TXBUF = low_Address // 发送地址位低位
while((IFG2 &UCB0TXIFG)==0) // 判断是否发送完毕
UCB0CTL1 &= ~UCTR // 确定为接收
while (UCB0CTL1 &UCTXSTP) //
UCB0CTL1 |=UCTXSTT
while((UCB0CTL1 &UCTXSTT)==1)
for(unsigned char i=0x0i<0x2fi++) // 延时确定数据已经被发送出去
UCB0CTL1 |=UCTXSTP + UCTXNACK // 发送停止位和NACK位
}
/*
** 函数名称:接收中断函数
**/
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
RXData = UCB0RXBUF // Get RX data
Int_char(RXData)
LCD12864_gotoXY(2,0) //第2行,第1列显示
LCD12864_sendstr(Result)
/*
key_code[0]=RXData%10+'0'
key_code[1]=0
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr(key_code)
*/
// __bic_SR_register_on_exit(CPUOFF) // Exit LPM0
}
void Init_UART()
{
P3OUT &= ~(BIT4+BIT5+BIT6+BIT7)
P3SEL = 0xF0// P3.4,5,6,7 = USCI_A0 TXD/RXD USCI_A1 TXD/RXD
UCA0CTL1 |= UCSSEL_1// CLK = ACLK
UCA0BR0 = 0x03 // 32kHz/9600 = 3.41
UCA0BR1 = 0x00 //
UCA0MCTL = UCBRS1 + UCBRS0 // Modulation UCBRSx = 3
UCA0CTL1 &= ~UCSWRST// **Initialize USCI state machine**
IE2 |= UCA0RXIE // Enable USCI_A0 RX interrupt
UCA1CTL1 |= UCSSEL_1// CLK = ACLK
UCA1BR0 = 0x03 // 32kHz/9600 = 3.41
UCA1BR1 = 0x00 //
UCA1MCTL = UCBRS1 + UCBRS0 // Modulation UCBRSx = 3
UCA1CTL1 &= ~UCSWRST// **Initialize USCI state machine**
UC1IE |= UCA1RXIE // Enable USCI_A0 RX interrupt
_BIS_SR(GIE)//使能中断
}
void Init_ADC()
{
ADC12CTL0 = SHT0_2 + ADC12ON// Set sampling time, turn on ADC12
ADC12CTL1 = SHP // Use sampling timer
ADC12IE = 0x01 // Enable interrupt
ADC12CTL0 |= ENC// Conversion enabled
P6DIR &= 0x01 // P6.0, i/p
P6SEL |= 0x01 // P6.0-ADC option select
_BIS_SR(GIE)//使能中断
}
void Start_ADC()
{
ADC12CTL0 |= ADC12SC // Start convn, software controlled
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
while (!(IFG2&UCA0TXIFG)) // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF // TX ->RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF)
}
#pragma vector=USCIAB1RX_VECTOR
__interrupt void USCI1RX_ISR(void)
{
while (!(UC1IFG&UCA1TXIFG)) // USCI_A0 TX buffer ready?
UCA1TXBUF = UCA1RXBUF // TX ->RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF)
//UCA1TXBUF = 'z'
}
// ADC12 interrupt service routine
#pragma vector=ADC12_VECTOR
__interrupt void ADC12_ISR (void)
{
int i=ADC12MEM0
Int_char(i)
LCD12864_gotoXY(2,0) //第1行,第1列显示
LCD12864_sendstr(Result)
/*
key_code[0] =i/1000+'0'
key_code[1] =i/100%10+'0'
key_code[2] =i/10%10+'0'
key_code[3] =i%10+'0'
key_code[4] =0
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr(key_code)
*/
}
void Init_all()
{
LCD12864_initial()//LCD初始化,包含了数码管和LED灯初始化
P7DIR=0x0F //键盘扫描初始化
P7REN=0xF0 //输入上下拉电阻使能,输出上下拉不使能
P7OUT=0xF0//输入上拉
Init_UART()//串口初始化
Init_compa()//比较器初始化
Init_ADC()//ADC初始化
Init_IIC()//IIC初始化
}
void Test_Led()
{
unsigned char i=0
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("1.Test_LED")
for(i<16i++)
{
P8OUT=0xF0|i
Delayms(50)
}
}
void Test_Seg()
{
int i
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("2.Test_SEG")
for(i=0i<500i++)
{
//4,3,2,1
P1OUT&=~0x02
P1OUT|=0x10|0x08|0x04
P5OUT=Seg_Data[9] //清楚数码管显示
Delayms(1)
P1OUT&=~0x04
P1OUT|=0x10|0x08|0x02
P5OUT=Seg_Data[8] //清楚数码管显示
Delayms(1)
P1OUT&=~0x08
P1OUT|=0x10|0x04|0x02
P5OUT=Seg_Data[7] //清楚数码管显示
Delayms(1)
P1OUT&=~0x10
P1OUT|=0x08|0x04|0x02
P5OUT=Seg_Data[6] //清楚数码管显示
Delayms(1)
}
P5OUT=0x00//熄灭所有数码管
}
void Test_Key()
{
unsigned char i=0
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("3.Test_KEY")
LCD12864_gotoXY(2,0) //第2行,第1列显示
LCD12864_sendstr("按键:")
for(i<16i++)
{
Int_char(Get_Keycode())
LCD12864_gotoXY(2,3)
LCD12864_sendstr("")
LCD12864_gotoXY(2,3)
LCD12864_sendstr(Result)
Delayms(100)//防抖
}
}
void Test_Uart()
{
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("4.Test_UART")
LCD12864_gotoXY(2,0) //第2行,第1列显示
}
void Test_Compa()
{
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("5.Test_COMPA")
}
void Test_ADC()
{
int i=0
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("6.Test_ADC")
for(i<200i++)
{
Start_ADC()
Delayms(10)
}
}
void Test_IIC()
{
LCD12864_gotoXY(1,0) //第1行,第1列显示
LCD12864_sendstr("7.Test_IIC")
EEPROM_Write(0x00,0x40,7)// 字节写
Delayms(10)
EEPROM_read(0x00,0x40)
}
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD//关闭看门狗
Init_all()
while(1){
Test_Led() //1.测试LED
LCD12864_gotoXY(2,0) //第1行,第1列显示
LCD12864_sendstr("请按16键!")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
Test_Seg() //2.测试数码管
LCD12864_gotoXY(2,0) //第1行,第1列显示
LCD12864_sendstr("请按16键!")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
Test_Key() //3.测试按键扫描
LCD12864_gotoXY(2,0) //第1行,第1列显示
LCD12864_sendstr("请按16键!")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
LCD12864_gotoXY(3,0) //第3行,第1列显示
LCD12864_sendstr("请按16键!")
Test_Uart() //4.测试串口
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
Test_Compa() //5.测试比较器
LCD12864_gotoXY(2,0) //第2行,第1列显示
LCD12864_sendstr("请按16键!")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
Test_ADC() //6.测试ADC
LCD12864_gotoXY(3,0) //第3行,第1列显示
LCD12864_sendstr("请按16键!")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
Test_IIC() //7.测试IIC
Delayms(100)
LCD12864_gotoXY(3,0) //第3行,第1列显示
LCD12864_sendstr("测试完成")
while(!(Get_Keycode()==15)) //按下最后一键测试下一个例子
LCD12864_clear()
}
}
顶层文件 万年历.C#include<reg51.h>坦孙
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4
bit key_flag1=0,key_flag2=0
SYSTEMTIME adjusted
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0
uchar data_alarm[7]={0}
/************键盘控制******************************/芦模
int key_scan() //扫描是否有键按下
{ int i=0
uint temp
P1=0xf0
temp=P1
if(temp!=0xf0)
i=1
else
i=0
return i
}
uchar key_value() //确定按键的值
{
uint m=0,n=0,temp
uchar value
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'}
P1=0xfe temp=P1if(temp!=0xfe)m=0
P1=0xfdtemp=P1 if(temp!=0xfd)m=1
P1=0xfbtemp=P1 if(temp!=0xfb)m=2
P1=0xf7temp=P1 if(temp!=0xf7)m=3
P1=0xeftemp=P1 if(temp!=0xef)n=0
P1=0xdftemp=P1 if(temp!=0xdf)n=1
P1=0xbftemp=P1 if(temp!=0xbf)n=2
value=v[m][n]
return value
}
/***************************设置闹铃函数*******************************/
void naoling(void)
{
uchar i=0,l=0,j
init1602()
while(key_flag2&&i<12)
if(key_scan()){j=key_value()write_data(j)if(i%2==0)data_alarm[l]=(j-'0')*10else {data_alarm[l]+=(j-'0')l++}i++delay(600)}
write_com(0x01)
}
uchar according(void)
{ uchar k
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1
else k=0
return k
}
void speak(void)
{uint i=50
while(i)
{speaker=0
delay(1)
speaker=1
delay(1)
i--
}
}
void alarm(void)
{uint i=10
while(i)
{
speak()
delay(10)
i--
}
}
/**************************修改时间 *** 作********************************/陪信缓
void reset(void)
{
sec_add=0
min_add=0
hou_add=0
day_add=0
mon_add=0
yea_add=0
}
void adjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++break
case '1':min_add++break
case '2':hou_add++break
case '3':day_add++break
case '4':mon_add++break
case '5':yea_add++break
case 'b':reset()break
default: break
}
adjusted.Second+=sec_add
adjusted.Minute+=min_add
adjusted.Hour+=hou_add
adjusted.Day+=day_add
adjusted.Month+=mon_add
adjusted.Year+=yea_add
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60
if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60
if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24
if(adjusted.Day>31) adjusted.Day=adjusted.Day%31
if(adjusted.Month>12) adjusted.Month=adjusted.Month%12
if(adjusted.Year>100) adjusted.Year=adjusted.Year%100
}
/**************************中断处理函数*********************************/
void changing(void) interrupt 0 using 0 //需要修改时间和日期,或者停止修改
{
if(key_flag1)key_flag1=0
else key_flag1=1
}
void alarming(void) interrupt 3 using 0 //需要设置闹铃或者停止设置
{
if(key_flag2)key_flag2=0
else key_flag2=1
}
/********************************主函数***********************************/
main()
{uint i
uchar *l
uchar p1[]="D:",p2[]="T:"
SYSTEMTIME T
EA=1
EX0=1
IT0=1
EA=1
EX1=1
IT1=1
init1602()
Initial_DS1302()
while(1)
{ write_com(0x80)
write_string(p1,2)
write_com(0xc0)
write_string(p2,2)
DS1302_GetTime(&T)
adjusted.Second=T.Second
adjusted.Minute=T.Minute
adjusted.Hour=T.Hour
adjusted.Week=T.Week
adjusted.Day=T.Day
adjusted.Month=T.Month
adjusted.Year=T.Year
for(i=0i<9i++)
{
adjusted.DateString[i]=T.DateString[i]
adjusted.TimeString[i]=T.TimeString[i]
}
adjust()
if(key_flag2)naoling()
if(according())alarm()
DateToStr(&adjusted)
TimeToStr(&adjusted)
write_com(0x82)
write_string(adjusted.DateString,8)
write_com(0xc2)
write_string(adjusted.TimeString,8)
delay(10)
}
(二)头文件1 显示模块 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0
sbit lcdrw = P2^1
sbit lcden = P2^2
void delay(uint z)// 延时
{
uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
void write_com(uchar com) // 写入指令数据到 lcd
{
lcdrw=0
lcdrs=0
P0=com
delay(5)
lcden=1
delay(5)
lcden=0
}
void write_data(uchar date) // 写入字符显示数据到 lcd
{
lcdrw=0
lcdrs=1
P0=date
delay(5)
lcden=1
delay(5)
lcden=0
}
void init1602() // 初始化设定
{
lcdrw=0
lcden=0
write_com(0x3C)
write_com(0x0c)
write_com(0x06)
write_com(0x01)
write_com(0x80)
}
void write_string(uchar *pp,uint n)
{
int i
for(i=0i<ni++)
write_data(pp[i])
}
#endif
(三)头文件2 时钟模块 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_
sbit DS1302_CLK = P2^6 //实时时钟时钟线引脚
sbit DS1302_IO = P2^7 //实时时钟数据线引脚
sbit DS1302_RST = P2^5 //实时时钟复位线引脚
sbit ACC0 = ACC^0
sbit ACC7 = ACC^7
typedef struct SYSTEM_TIME
{
unsigned char Second
unsigned char Minute
unsigned char Hour
unsigned char Week
unsigned char Day
unsigned char Month
unsigned char Year
unsigned char DateString[9] //用这两个字符串来放置读取的时间
unsigned char TimeString[9]
}SYSTEMTIME//定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2)//用于计算 DS1302_RAM 地址的宏
/******内部指令**********/
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i
ACC = d
for(i=8i>0i--)
{
DS1302_IO = ACC0
DS1302_CLK = 1
DS1302_CLK = 0
ACC = ACC >>1//因为在前面已经定义了ACC0 = ACC^0以便再次利用DS1302_IO = ACC0
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i
for(i=8i>0i--)
{
ACC = ACC >>1
ACC7 = DS1302_IO
DS1302_CLK = 1
DS1302_CLK = 0
}
return(ACC)
}
/********************************/
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0
DS1302_CLK = 0
DS1302_RST = 1
DS1302InputByte(ucAddr) // 地址,命令
DS1302InputByte(ucDa) // 写1Byte数据
DS1302_CLK = 1
DS1302_RST = 0
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData
DS1302_RST = 0
DS1302_CLK = 0
DS1302_RST = 1
DS1302InputByte(ucAddr|0x01) // 地址,命令
ucData = DS1302OutputByte()// 读1Byte数据
DS1302_CLK = 1
DS1302_RST = 0
return(ucData)
}
void DS1302_SetProtect(bit flag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10)
else
Write1302(0x8E,0x00)
}
void DS1302_SetTime(unsigned char Address, unsigned char Value)// 设置时间函数
{
DS1302_SetProtect(0)
Write1302(Address, ((Value/10)<<4 | (Value%10))) //将十进制数转换为BCD码
}//在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue
ReadValue = Read1302(DS1302_SECOND)
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)//将BCD码转换为十进制数
ReadValue = Read1302(DS1302_MINUTE)
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
ReadValue = Read1302(DS1302_HOUR)
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
ReadValue = Read1302(DS1302_DAY)
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
ReadValue = Read1302(DS1302_WEEK)
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
ReadValue = Read1302(DS1302_MONTH)
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
ReadValue = Read1302(DS1302_YEAR)
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8]
D[0]=Time->Second/10<<4+Time->Second%10
D[1]=Time->Minute/10<<4+Time->Minute%10
D[2]=Time->Hour/10<<4+Time->Hour%10
D[3]=Time->Day/10<<4+Time->Day%10
D[4]=Time->Month/10<<4+Time->Month%10
D[5]=Time->Week/10<<4+Time->Week%10
D[6]=Time->Year/10<<4+Time->Year%10
return D
}
void DateToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->DateString[0] = Time->Year/10 + '0'
Time->DateString[1] = Time->Year%10 + '0'
Time->DateString[2] = '-'
Time->DateString[3] = Time->Month/10 + '0'
Time->DateString[4] = Time->Month%10 + '0'
Time->DateString[5] = '-'
Time->DateString[6] = Time->Day/10 + '0'
Time->DateString[7] = Time->Day%10 + '0'
Time->DateString[8] = '\0'
}
void TimeToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0'
Time->TimeString[1] = Time->Hour%10 + '0'
Time->TimeString[2] = ':'
Time->TimeString[3] = Time->Minute/10 + '0'
Time->TimeString[4] = Time->Minute%10 + '0'
Time->TimeString[5] = ':'
Time->TimeString[6] = Time->Second/10 + '0'
Time->TimeString[7] = Time->Second%10 + '0'
Time->DateString[8] = '\0'
}
void Initial_DS1302(void)
{
unsigned char Second
Second=Read1302(DS1302_SECOND)
if(Second&0x80) //初始化时间
DS1302_SetTime(DS1302_SECOND,0)
}
void DS1302_TimeStop(bit flag) // 是否将时钟停止
{
unsigned char Data
Data=Read1302(DS1302_SECOND)
DS1302_SetProtect(0)
if(flag)
Write1302(DS1302_SECOND, Data|0x80)
else
Write1302(DS1302_SECOND, Data&0x7F)
}
#endif
随着人们自身素质提升,报告的用途越来越大,我们在写报告的时候要注意逻辑的合理性。那么报告应该怎么写才合适呢?以下是我为大家整理的电子信息工程毕业论文开题报告,希望能够帮助到大家。
毕业设计的内容返或和意义
毕业设计内容:
1.熟悉单片机系统设计方法,独立完成电路和程序设计。
2.用PROTEUS进行系统调试和仿真。
3.设计、制作并调试硬件系统。
4.完成相关软件文档资料。
毕业设计应完成的技术文件:
1.3000字以上毕业设计开题报告,2000字以上英文参考文献的中文译文。
2.毕业设计论文(15000字以上)。
3.提供设计原理图和相应程序。
毕业设计意义:
随着时代的发展,现代化建设步伐不断加快,对道路照明及道路亮化工程需求也更大,而能源的供需矛盾也越来越突出,节电节能、绿色照明的要求越来越迫切,越来越高。现在再采用那些传统的手控、钟控照明系统的方法已不能满足要求。如何充分利用高科技手段解决上述矛盾也就成为当前照明控制领域一个新的和紧要的课题。路灯照明是日常生活中必不可少的公共设施。路灯照明耗电量约占总耗电量的15%,全国各地无不面对电力紧张带来的各种问题。面对供电紧张形势,路灯巡查对于国家来讲是一项需要耗费大量人力的工作,各种临时应急节电措施被广泛采用:夜晚间隔关灯、调整路灯开关的时间、在用电紧张的日子里关闭景观照明等等,当用电高峰过后,这些措施可能就被束之高阁,明年的用电高峰来临,一切又会重新开始。这样的节电措施,在缓解用电紧张的同时,却带来资源的浪费和对人们日常生活的负面影响。缓解用电紧张的最佳和有效的办法是对用电实施智能化管理,减少浪费,使我们的每一度电都能物尽其用!启用先进路灯监控系统,可以对路灯实施统一启闭,对夜间照明系统和路灯的实时监控和管理,确保高效稳定,全天候运行,控制不必要的“全夜灯照明”,有效节约电能消耗。对于学校公共照明系统来说,采用智能化的管理系统是实现能源节约、减少资源浪费、满足人们生活要桐纯求、显示现代化校园的科学解决方案。
目前已有一小部分校园参考了公路路灯的节能措施,到了后半夜将电灯亮度调低,或采取等间隔亮灯的方式来节约用电,但是这样一个方法却带来路灯过亮或过暗的问题:
1.控制落后
开关灯方式落后:当前路灯控制,还停留在手动、光控、钟控方式。受季节、天气和人为因素影响,自动化管理水平低,经常该亮时不亮,该灭时不灭,极易造成极大的能源浪费,增加了财政负担。
2. *** 控不便
调节 *** 控能力不足,无法远程修改开关灯时间,不能根据实际情况(天气突变,重大事件,节日)及时校时和修改开关灯时间。
3.灯况不明
不具备路灯状况监测,现有的照明设施管理工作主要采用人工巡查模式,不仅工作量大,还浪费人力、物力、财力。故障依据主要来源于巡视人员上报和市民投诉缺乏主动性、及时性和可靠性,不能实时、准确、全面地监控全城的路灯运行状况缺乏有效的故障预警机制。
4.不能很好的应用在前半夜
因为其前半夜6个小时以上全部采取正常亮度,这样就会出现在没有行人、车辆经过校园道路时的电力资源浪费这一现象,而除了晚上6点-9点人车流高峰期以外其余时间人车流量确实相对较少,所以我们认为校园照明有更大的节能潜力。
针局世咐对以上现有节能情况分析,我们设计了一种高效率的智能节能路灯,路灯控制器内应同时设有光控和时控模块,该模块先服从光度控制,再服从时间控制,能满足达到一定光度开关路灯和达到特定时间开关路灯的要求。同时,我们认为路灯应改进为为红外感测路灯。针对校园人、车流量的高低峰时段对路灯分为节能状态和标准状态。在人车流量的高峰期如清晨上班时间和傍晚18点—21点,路灯要保持持续标准亮度,而在深夜路灯将转为节能状态,通过红外感测,只在有人、车通过时才变亮。使用红外感测,与声控相比,感应精度更高,避免了一些噪音而使灯无效闪烁。将所有的路灯连接到单片机上,单片机和计算机通信,用计算机控制路灯工作状态。可设定自动控制方式和人工控制方式。自动控制方式可根据地太阳活动规律,并结合实际情况控制路灯的工作方式。当夜幕降临,或光线已经较暗时,虽然未达到设定时间,也能自动开启。交通高峰期,应达到持续满额亮度高峰期后,进入红外感应,实现智能和节能的控制。人工控制方式可随时设定开关时间、路灯开启比例或单独控制路灯的开与关。另外通过路灯的工作状态可对路灯损坏实现实时报警,并可显示具体的位置,提醒维修人员及时维修,中心控制器带有时钟芯片,该时钟芯片带有EEPROM,可以保持单片机工作参数,即使通信发生错误,路灯也能按照最后的程序进行工作。
文献综述
一、设计方案
本设计选用STC89C52单片机作为系统的核心部件,实现系统的控制和处理的功能。各模块所包含的功能如下:(1)红外模块:夜晚进行检测是否有行人。(2)显示模块12864:显示相应的时间和日期信息。(3)时钟模块:手动切换时间,自己设定开灯时间。(4)光敏电阻传感器模块:用于检测周围环境光强度,若光强低于标准值则开启路灯。
二、硬件电路设计
1.主控制器STC89C52
STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
STC89C52具有以下标准功能:8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4KBEEPROM,MAX810复位电路,3个16位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。另外STC89C52可降至0Hz静态逻辑 *** 作,支持2种软件可选择节电模式。空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35MHz,6T/12T可选。
2.红外模块
本设计采用HC-SR501红外模块,它是基于红外线技术的'自动控制模块,采用德国原装进口LHI778探头设计,灵敏度高,可靠性强,超低电压工作模式,广泛应用于各类自动感应电器设备,尤其是干电池供电的自动控制产品。该模块用于检测夜晚是否有行人路过,因此产生高地电平,并通过软件的方法来处理电平信号。
3.光敏电阻传感器模块
本设计采用3线制光敏电阻传感器模块,是一款灵敏型光敏电阻传感器,用比较器输出,信号干净,波形好,驱动能力强,超过15mA。同时配有可调电位器可调节检测光线亮度,用于检测周围环境光强度,若光强低于标准值则开启路灯。
4.显示模块
本设计采用液晶显示器12864显示时间和日期。液晶显示屏的第一行显示年月日,第二行显示的实时时钟,硬件电路中的12864的数据端口接到单片机P1口,数码管的4,5,6管脚分别与单片机的P3.0-P3.2相连,通过单片机的信息处理,从而在液晶显示屏上显示各段信息。
四、软件设计
主程序主要设计各个部分子程序的调用,子程序有时钟程序和显示子程序两部分。程序初始化后,红外模块子程序判断有没有行人,输出一个信号,经软件处理。12864液晶显示子程序主要通过接收主程序发出的信号,将其设置输入为模式子函数形成,并初始化LCD子函数,显示日期子函数,显示时间子函数。
五、仿真实现
该系统的软件仿真采用Proteus软件,当系统开机时,系统进入初始化界面,液晶显示第一行为时间信息,第二行为日期信息,当白天的时候,打开光强和红外判断,同时成立才开启路灯。设定按钮可手动改变时间信息。
参考文献:
1.胡汉才.单片机原理及其接口技术[M].北京:清华大学出版社.2001.7
2.周润景等.Proteus在MCS-51&ARM7系统中的应用[M].北京:电子工业出版社.2006.10
3.侯玉宝等.基于Proteus的51系列单片机设计与仿真[M].北京:电子工业出版社.2008.8
4.张靖武等.单片机系统的PROTEUS设计与仿真[M].北京:电子工业出版社.2007.4
5.楼然苗等.单片机课程设计指导[M].北京:北京航空航天大学出版社.2007.7
6.周向红等.51系列单片机应用与实践教程[M].北京:北京航空航天大学出版社.2008.5
7.李林功.单片机原理与应用—基于实例驱动和Proteus仿真[M].北京:科学出版社.2010.5
8.薛钧义,张彦斌.MCS-系列单片微机计算机及其应用[M].西安:西安交通大学出版社.1997
9.何利民.单片机应用系统设计.[M]北京航空航天大学出版社.1995
研究内容
红外模块的使用
单片机读取时钟芯片
用液晶显示相关数据
绘出逻辑图
研究计划
第一周——第二周:下毕业设计任务书,明确设计要求。查阅、搜集毕业设计相关资料。着手翻译相关英文资料,并熟悉PROTEUS软件和单片机的相关开发知识。
第三周——第四周:对查阅的文献资料归纳综述撰写开题报告。完成毕业设计需求分析,确定系统框图。
第五周——第六周:方案论证,设计硬件电路。分析设计的电路,提出软件设计思路毕业设计初期检查。
第七周——第八周:在PROTEUS中实现软、硬件设计与调试。分析调试中的问题,改进并重新调试达到技术要求。
第九周——第十周:软、硬件电路进行整体测试,修改并完善程序毕业设计中期检查。
第十一周——第十二周:设计并制作印制电路板完成硬件的安装和调试。完成整个系统的软件、硬件的调试。
第十三周——第十四周:研究工作总结,撰写毕业论文。
第十五周——第十六周:论文修改及评阅,论文答辩。
特色与创新
路灯控制器内应同时设有光控和时控模块,该模块先服从光度控制,再服从时间控制,能满足达到一定光度开关路灯和达到特定时间开关路灯的要求。同时,路灯为红外感测路灯。针对校园人、车流量的高低峰时段对路灯分为节能状态和标准状态。在人车流量的高峰期如清晨上班时间和傍晚18点—23点,路灯要保持持续标准亮度,而在深夜路灯将转为节能状态,通过红外感测,只在有人、车通过时才变亮。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)