1、PIC24FJ单片机RTCC程序有感 (2008-08-05 18:08:41) 转载▼ 标签: 杂谈 分类: IC程序 RTCC很是简单,但是别人写出来就太漂亮了,要借鉴的太多太多。。。。工程实用 ********************************************************************** * ?2007 Microchip Technology Inc. * * FileName: RTCC.c * Dependencies: Header (.h) files if applicable, se
2、e below * Processor: PIC24Fxxxx * Compiler: MPLAB?C30 v3.00 or higher * * SOFTWARE LICENSE AGREEMENT: * Microchip Technology Incorporated ("Microchip") retains all * ownership and intellectual property rights in the code accompanying * this message and in all derivatives hereto.
3、 You may use this code, * and any derivatives created by any person or entity by or on your * behalf, exclusively with Microchip's proprietary products. Your * acceptance and/or use of this code constitutes agreement to the * terms and conditions of this notice. * * CODE ACCOMPANYING THIS MES
4、SAGE IS SUPPLIED BY MICROCHIP "AS IS". NO * WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT * NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS * CODE, ITS INTERACTION WITH MICROCHIP'S PRODUCTS, COMBINAT
5、ION WITH * ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. * * YOU ACKNOWLEDGE AND AGREE THAT, IN NO EVENT, SHALL MICROCHIP BE * LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR * BREACH OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY, * CONTRIBUTION, OR OTHERWISE, FOR ANY I
6、NDIRECT, SPECIAL, PUNITIVE, * EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR * EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE CODE, HOWSOEVER * CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE * DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWABLE BY LAW
7、 * MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS * CODE, SHALL NOT EXCEED THE PRICE YOU PAID DIRECTLY TO MICROCHIP * SPECIFICALLY TO HAVE THIS CODE DEVELOPED. * * You agree that you are solely responsible for testing the code and * determining its suitability. Microchi
8、p has no obligation to modify, * test, certify, or support the code. * * REVISION HISTORY: *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Author Date Comments on this revision *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Alb
9、ert Z. 03/24/08 First release of source file * Albert Z. 07/10/08 Add RTCC alarm *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * ADDITIONAL NOTES: * Copy the RTCC functions to your application. * * Code Tested on: * Explorer 16 Development Board with PIC24FJ128
10、GA010 controller * * DESCRIPTION: * Microchip's PIC24F microcontrollers feature a useful Real Time Clock * for users to get an on chip clock in their applications. * This code example demonstrates how to grab and set the RTC, set alarm * and RTCC clock output / alarm output. *****************
11、/
#include
12、 and CLK monitor, OSCO or Fosc/2, HS oscillator, // Primary oscillator _CONFIG2(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_PRI) // Union to access rtcc registers typedef union tagRTCC { struct { unsigned char sec; unsigned char min; unsigned char hr; unsigned char wkd; u
13、nsigned char day; unsigned char mth; unsigned char yr; }; struct { unsigned int prt00; unsigned int prt01; unsigned int prt10; unsigned int prt11; }; } RTCC; RTCC _time; RTCC _time_chk; RTCC _alarm; // macro #define mRTCCDec2Bin(Dec) (10*(Dec>>4)+(Dec&0x0f)) #define mR
14、TCCBin2Dec(Bin) (((Bin/10)<<4)|(Bin%10)) void RTCCgrab(void); void RTCCInit(void); void RTCCSet(void); void RTCCALMSet(void); void RTCCUnlock(void); void RTCCSetBinSec(unsigned char ); void RTCCSetBinMin(unsigned char ); void RTCCSetBinHour(unsigned char ); void RTCCCalculateWeekDay(void)
15、 void RTCCSetBinDay(unsigned char ); void RTCCSetBinMonth(unsigned char ); void RTCCSetBinYear(unsigned char ); // main int main(void) { // I/O initialization ODCAbits.ODA6 = 0; TRISAbits.TRISA6 = 0; RTCCInit(); // initialization includes set the time and date RTCCgrab(
16、); // grab once while (1); // TO DO: // observe D9 on Explorer 16, it will toggle every 10 seconds as set. // probe RTCC pin on #68 of PIC24FJ128GA010, it is a second clock of RTCC. return (0); } ********************************************************************* * Function:
17、 RTCCProcessEvents * * Preconditions: RTCCInit must be called before. * * Overview: The function grabs the current time from the RTCC and * translate it into strings. * * Input: None. * * Output: It update time and date strings _time_str, _date_str, * and _time, _time_chk struct
18、ures. * ********************************************************************/ void RTCCgrab(void) { // Process time object only if time is not being set // Grab the time RCFGCALbits.RTCPTR = 3; _time.prt11 = RTCVAL; _time.prt10 = RTCVAL; _time.prt01 = RTCVAL; _time.prt00
19、 = RTCVAL; // Grab the time again RCFGCALbits.RTCPTR = 3; _time_chk.prt11 = RTCVAL; _time_chk.prt10 = RTCVAL; _time_chk.prt01 = RTCVAL; _time_chk.prt00 = RTCVAL; // Verify there is no roll-over if ((_time.prt00 == _time_chk.prt00) && (_time.prt01 == _time_chk.prt01) &&
20、 (_time.prt10 == _time_chk.prt10) && (_time.prt11 == _time_chk.prt11)) { // Here, you can watch structure _time, // which has the data from RTCC registers. // TO DO: do something as you like here. } } *****************************************************************
21、 * Function: RTCCInit * * Preconditions: RTCCInit must be called before. * * Overview: Enable the oscillator for the RTCC * * Input: None. * * Output: None. ********************************************************************/ void RTCCInit(void) { // Enables the LP OS
22、C for RTCC operation asm("mov #OSCCON,W1"); // move address of OSCCON to W1 asm("mov.b #0x02, W0"); // move 8-bit literal to W0, 16-bit. asm("mov.b #0x46, W2"); // unlock byte 1 for OSCCONL(low byte) asm("mov.b #0x57, W3"); // unlock byte 2 for OSCCONL(low byte) // move 8-bit of Wn t
23、o OSCCON register asm("mov.b W2, [W1]"); // write unlock byte 1 asm("mov.b W3, [W1]"); // write unlock byte 2 asm("mov.b W0, [W1]"); // enable SOSCEN // Unlock sequence must take place for RTCEN to be written RCFGCAL = 0x0000; RTCCUnlock(); RCFGCALbits.RTCEN = 1; // bit15
24、 //RTCC pin pad conected to RTCC second clock PADCFG1bits.RTSECSEL = 1; RCFGCALbits.RTCOE = 1; //RTCC Output Enable bit IFS3bits.RTCIF = 0; //clear the RTCC interrupt flag IEC3bits.RTCIE = 1; //enable the RTCC interrupt // TO DO: Write the time and date to RTCC as follow.
25、 _time_chk.sec = 0x00; _time_chk.min = 0x05; _time_chk.hr = 0x7; _time_chk.wkd = 0x2; _time_chk.day = 0x24; _time_chk.mth = 0x07; _time_chk.yr = 0x07; RTCCCalculateWeekDay(); // To calculate and confirm the weekday // Set it after you change the time and date. RTCCSet(); //
26、Set alarm _alarm.sec = 0x01; _alarm.min = 0x01; _alarm.hr = 0x01; _alarm.wkd = 0x01; _alarm.day = 0x01; _alarm.mth = 0x01; RTCCALMSet(); } ********************************************************************* * Function: RTCCSet * * Preconditions: None. * * Overview: * Th
27、e function upload time and date from _time_chk into clock. * * Input: _time_chk - structure containing time and date. * * Output: None. * ********************************************************************/ void RTCCSet(void) { RTCCUnlock(); // Unlock the RTCC RCFGCALbits.RT
28、CPTR = 3; // Set the time RTCVAL = _time_chk.prt11; // set year RTCVAL = _time_chk.prt10; // set month:day RTCVAL = _time_chk.prt01; // set week:hour RTCVAL = _time_chk.prt00; // set min:sec RCFGCALbits.RTCWREN = 0; // Lock the RTCC // Here, you can watch the RTCC register, // the
29、 new time and date has been updated. } ********************************************************************* * Function: RTCCALMSet * * Preconditions: None. * * Overview: * The function upload time and date from _alarm into RTCC alarm. * * Input: _alarm - structure containing time
30、and date. * * Output: None. * ********************************************************************/ void RTCCALMSet(void) { RTCCUnlock(); // Unlock the RTCC while(RCFGCALbits.RTCSYNC==1); //wait for RTCSYNC bit to become 0 ALCFGRPTbits.ALRMEN = 0; //disable alarm to update i
31、t ALCFGRPTbits.ALRMPTR = 2; //Point to Month/Day register ALRMVAL = _alarm.prt10; //load month & day ALRMVAL = _alarm.prt01; //load weekday & hour ALRMVAL = _alarm.prt00; //load minute & seconds ALCFGRPTbits.AMASK = 2; //alarm every 10 seconds ALCFGRPTbits.ARPT = 0xff
32、 //alarm 255 times ALCFGRPTbits.CHIME = 1; //enable chime ALCFGRPTbits.ALRMEN = 1; //enable the alarm RCFGCALbits.RTCWREN = 0; // Lock the RTCC } ********************************************************************* * Function: RTCCUnlock * * Preconditions: None. * * Ov
33、erview: The function allows a writing into the clock registers. * * Input: None. * * Output: None. * ********************************************************************/ void RTCCUnlock() { asm volatile("disi #5"); asm volatile("mov #0x55, w7"); // write 0x55 and 0xAA to asm vo
34、latile("mov w7, _NVMKEY"); // NVMKEY to disable asm volatile("mov #0xAA, w8"); // write protection asm volatile("mov w8, _NVMKEY"); asm volatile("bset _RCFGCAL, #13"); // set the RTCWREN bit asm volatile("nop"); asm volatile("nop"); } **********************************************
35、 * Function: RTCCSetBinSec * * Preconditions: None. * * Overview: The function verifies setting seconds range, translates * it into BCD format and writes into _time_chk structure. To write * the structure into clock RTCCSet must be called. * * Input: Seconds
36、binary value. * * Output: Checked BCD value in _time_chk structure. * ********************************************************************/ void RTCCSetBinSec(unsigned char Sec) { if(Sec >= 60) Sec = 0; _time_chk.sec = mRTCCBin2Dec(Sec); } *************************************
37、 * Function: RTCCSetBinMin * * Preconditions: None. * * Overview: The function verifies a setting minutes range, translates * it into BCD format and writes into _time_chk structure. To write * the structure into clock RTCCSet must be called. * * Input
38、 Minutes binary value. * * Output: Checked BCD value in _time_chk structure. * ********************************************************************/ void RTCCSetBinMin(unsigned char Min) { if(Min >= 60) Min = 0; _time_chk.min = mRTCCBin2Dec(Min); } ***************************
39、 * Function: RTCCSetBinHour * * Preconditions: None. * * Overview: The function verifies a setting hours range, translates * it into BCD format and writes into _time_chk structure. To write * the structure into clock RTCCSet must be called. *
40、 * Input: Hours binary value. * * Output: Checked BCD value in _time_chk structure. * ********************************************************************/ void RTCCSetBinHour(unsigned char Hour) { if(Hour >= 24) Hour = 0; _time_chk.hr = mRTCCBin2Dec(Hour); } ****************
41、 * Function: RTCCCalculateWeekDay * * Preconditions: * Valid values of day, month and year must be presented in * _time_chk structure. * * Overview: The function reads day, month and year from _time_chk and * calculates week day. T
42、han It writes result into _time_chk. To write * the structure into clock RTCCSet must be called. * * Input: _time_chk with valid values of day, month and year. * * Output: Zero based week day in _time_chk structure. * ********************************************************************
43、/ void RTCCCalculateWeekDay() { const char MonthOffset[] = //jan feb mar apr may jun jul aug sep oct nov dec { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 }; unsigned Year; unsigned Month; unsigned Day; unsigned Offset; // calculate week day Year = mRTCCDec2Bin(_time_c
44、hk.yr); Month = mRTCCDec2Bin(_time_chk.mth); Day = mRTCCDec2Bin(_time_chk.day); // 2000s century offset = 6 + // every year 365%7 = 1 day shift + // every leap year adds 1 day Offset = 6 + Year + Year/4; // Add month offset from table Offset += MonthOffs
45、et[Month-1]; // Add day Offset += Day; // If it's a leap year and before March there's no additional day yet if((Year%4) == 0) if(Month < 3) Offset -= 1; // Week day is Offset %= 7; _time_chk.wkd = Offset; } ****************************
46、 * Function: RTCCSetBinDay * * Preconditions: None. * * Overview: The function verifies a setting day range, translates it * into BCD format and writes into _time_chk structure. To write the * structure into clock RTCCSet must be called. * *
47、 Input: Day binary value. * * Output: Checked BCD value in _time_chk structure. * ********************************************************************/ void RTCCSetBinDay(unsigned char Day) { const char MonthDaymax[] = //jan feb mar apr may jun jul aug sep oct nov dec { 31, 28, 31,
48、30, 31, 30, 31, 31, 30, 31, 30, 31 }; unsigned Daymax; unsigned Month; unsigned Year; Month = mRTCCDec2Bin(_time_chk.mth); Year = mRTCCDec2Bin(_time_chk.yr); Daymax = MonthDaymax[Month-1]; // February has one day more for a leap year if(Month == 2) if( (Year%4) ==
49、 0) Daymax++; if(Day == 0) Day = Daymax; if(Day > Daymax) Day = 1; _time_chk.day = mRTCCBin2Dec(Day); } ********************************************************************* * Function: RTCCSetBinMonth * * Preconditions: None. * * Overview: The function verifies a
50、 setting month range, translates * it into BCD format and writes into _time_chk structure. To write * the structure into clock RTCCSet must be called. * * Input: Month binary value. * * Output: Checked BCD value in _time_chk structure. * **********************************************






