下边给各位分享的是我利用MSP430F5310单片机实现的关于自带日历时间输出和调整的程序,分享给大家了。。
/*************************************************
** 版权: 杭州利尔达科技有限公司
** 文件名: LSD-TEST430F5529-RTC.c
** 版本: IAR 4.21
** 工作环境:
** 作者:
** 生成日期:
** 功能: RTC实时时钟
MSP430F5529
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P8.0 |--> LED5
// | P1.0 |--> LED3
** 相关文件: LSD-TEST430F5529 V1.0
** 修改日志
**相关说明:
*************************************************************/
#include "msp430f5310.h"
#define uchar unsigned char
#define uint unsigned int
typedef struct {
uint year ; //
uchar month; //
uchar day; //
uchar week;
uchar hour; //
uchar min; //
uchar second;
uchar flag;
} time;
time RTC;
uchar temp,temp1,data1,receive_buffer[15],receive_flag =0,receive_count=0,count=0;
void Init_Rtc(void);
void Init_Clk(void);
void Init_System(void);
void UartConfig(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关看门狗
PMAPPWD = 0x02D52; // Enable Write-access to modify port mapping registers
P4MAP7 = PM_MCLK;
PMAPPWD = 0; // Disable Write-Access to modify port mapping registers
Init_System(); // 系统初始化
__bis_SR_register(GIE);
// for(uchar i=0;i<200;i++) //UART1 test
// {
// while (!(UCA1IFG&UCTXIFG));
// UCA1TXBUF = 0xAA;
// _NOP();
// }
while(1)
{
if(RTC.flag ==0x01)
{
RTC.flag =0;
temp =RTC.year>>8;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =RTC.year;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x2D;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =RTC.month;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x2D;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =RTC.day;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x20;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
// temp =RTC.week;
//while (!(UCA1IFG&UCTXIFG));
// UCA1TXBUF = temp;
temp =RTC.hour;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x3A;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =RTC.min;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x3A;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =RTC.second;
temp1 =temp;
temp =temp>>4;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =temp1&0x0f;
temp +=48;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
temp =0x20;
while (!(UCA1IFG&UCTXIFG));
UCA1TXBUF = temp;
_NOP();
}
if((receive_flag &0x04)==0x04)
{
receive_flag =0;
RTCCTL01 = RTCBCD + RTCHOLD + RTCMODE + RTCTEV_0 ;
RTCPS0CTL = RT0PSHOLD ; //配置两个计数器分频
RTCPS1CTL = RT1PSHOLD ;
RTCSEC = receive_buffer[10]; //初始化秒
RTCMIN = receive_buffer[9] ; //初始化分钟
RTCHOUR = receive_buffer[8]; //初始化小时
RTCDOW = receive_buffer[7] ;
RTCDAY = receive_buffer[6]; //日期初始化
RTCMON = receive_buffer[5]; //初始化月份
RTCYEAR = 0x2000+receive_buffer[4]; //初始化年份
RTCAMINHR = 0X2200 + BIT7; //闹钟小时和分钟设置
RTCADOWDAY = 0X2402; //闹钟星期和日期设置
RTCCTL01 &= ~RTCHOLD; //打开RTC模块
RTCPS0CTL &= ~RT0PSHOLD; //打开RTCPS0CTL
RTCPS1CTL &= ~RT1PSHOLD; //打开RTCPS1CTL
RTCCTL0 |= RTCAIE + RTCRDYIE; //打开安全访问使能 ,闹钟使能
}
// __bis_SR_register(LPM3_bits); //// 进入低功耗3
}
}
/************************ RTC中断*****************************/
#pragma vector=RTC_VECTOR
__interrupt void basic_timer(void)
{
switch(RTCIV)
{
case 2 : P1OUT ^= BIT1;
RTC.year=RTCYEAR;
RTC.month= RTCMON;
RTC.day=RTCDAY;
RTC.week=RTCDOW;
RTC.hour= RTCHOUR;
RTC.min=RTCMIN;
RTC.second=RTCSEC;
RTC.flag =0x01;
break; //RTCRDYIFG
case 4 : break;
case 6 : break; //RTCAIFG P8OUT |= BIT0;
case 8 : break;
case 10 : break;
}
}
/*************************************************
函数(模块)名称:void Init_System(void)
功能: 该程序系统初始化
本函数(模块)调用的函数(模块)清单:
调用本函数(模块)的函数(模块)清单:
输入参数: void
输出参数: void
函数返回值说明 :void
使用的资源
其它说明:
*************************************************/
void Init_System(void)
{
Init_Clk(); //调用时钟函数
Init_Rtc(); //RTC 初始化
UartConfig();
P1DIR |= BIT1; //P1.0为输出
P1OUT &= ~BIT1;
// P8DIR |= BIT0; //P7.7为输出
// P8OUT &= ~BIT0;
}
/*************************************************
函数(模块)名称:void Init_Rtc(void)
功能: RTC初始化
本函数(模块)调用的函数(模块)清单:
调用本函数(模块)的函数(模块)清单:
输入参数: void
输出参数: void
函数返回值说明 :void
使用的资源
其它说明:
*************************************************/
void Init_Rtc(void)
{ // BCD码日历格式输出
RTCCTL01 = RTCBCD + RTCHOLD + RTCMODE + RTCTEV_0 ;
RTCPS0CTL = RT0PSHOLD ; //配置两个计数器分频
RTCPS1CTL = RT1PSHOLD ;
RTCSEC = 0x54; //初始化秒
RTCMIN = 0X59 ; //初始化分钟
RTCHOUR = 0X10; //初始化小时
RTCDOW = 0X01 ;
RTCDAY = 0x15; //日期初始化
RTCMON = 0X10 ; //初始化月份
RTCYEAR = 0x2012; //初始化年份
RTCAMINHR = 0X2200 + BIT7; //闹钟小时和分钟设置
RTCADOWDAY = 0X2402; //闹钟星期和日期设置
RTCCTL01 &= ~RTCHOLD; //打开RTC模块
RTCPS0CTL &= ~RT0PSHOLD; //打开RTCPS0CTL
RTCPS1CTL &= ~RT1PSHOLD; //打开RTCPS1CTL
RTCCTL0 |= RTCAIE + RTCRDYIE; //打开安全访问使能 ,闹钟使能
}
/*************************************************
函数(模块)名称:void Init_Clk(void)
功能: 时钟初始化
本函数(模块)调用的函数(模块)清单:
调用本函数(模块)的函数(模块)清单:
输入参数: void
输出参数: void
函数返回值说明 :void
使用的资源
其它说明:
*************************************************/
void Init_Clk(void)
{
P1DIR |= BIT0; // MCLK set out to pins
P1SEL |= BIT0;
//P5SEL = BIT3 + BIT2; //启动XT2
P5SEL = BIT4 + BIT5; //启动XT1
// UCSCTL6 &= ~XT2OFF; // Enable XT2
UCSCTL6 &= ~XT1OFF; // Enable XT2
UCSCTL1 = DCORSEL_2; //DCO 范围配置
UCSCTL3 |= SELREF_2; // FLLref = REFO
// Since LFXT1 is not used,
// sourcing FLL with LFXT1 can cause
// XT1OFFG flag to set
UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO
while (SFRIFG1 & OFIFG) //等待时钟系统正常工作
{
__delay_cycles(100000);
UCSCTL7 &= ~( XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
__delay_cycles(100000);
}
UCSCTL4 = SELM_3 + SELA_0 + SELS_4; //设置时钟源
}
void UartConfig(void)
{
P4SEL = 0x30; // P4.4,4,5 USCI_A0 option select
P4DIR |=BIT4;
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL__ACLK; // SMCLK//ACLK
UCA1BR0 = 3; // 32768Hz 9600 (see User's Guide)
UCA1BR1 = 0; // 32768Hz 9600
UCA1MCTL = UCBRS_3 + UCBRF_0; // Modln UCBRSx=0, UCBRFx=0,
// over sampling
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA1IFG&UCTXIFG));
data1=UCA1RXBUF;
if(data1 ==0xA4)
{
receive_flag =0x01; //
receive_buffer[receive_count ++]=data1;
}
else if(receive_flag ==0x01)
{
receive_flag =0x02;
receive_buffer[receive_count ++]=data1;
count =data1+4;
}
else if(receive_flag ==0x02)
{
if(receive_count<count)
{
receive_buffer[receive_count ++]=data1;
if(receive_count ==count)
{
if(receive_buffer[3]==0xFF)
receive_flag |=0x04;
receive_count =0;
}
}
else
{
receive_flag =0;
receive_count =0;
}
}
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
} |