無料ブログはココログ

« Weekender by HITEC Q4i HD200 RTF LED消灯方法 | トップページ | OLED 128*32 SPI+BMP085 I2C 気圧センサー+LPC811でお天気予測ガジェット作成中 »

2014年5月16日 (金)

LPC810でGPS(GT-723F)→WWVB出力

最近、枕元に置くための電波時計を購入したのですが、アメリカ製で、電波信号の種類がWWVBしかないんです。

ということで、これを解決するためにGPS-WWVB変換器を作りました。
使うCPUは、LPC810です。
GPSは、GT-723Fでデフォルト設定で使います。
 
3ピンがGPS入力、4ピンがWWVB出力です。
同期は、GPSの1秒間隔出力をを使っています。
うるう年計算がこれで良いかわかりません。その時おかしかったら修正予定です。
一応、これで動作しましたので結果オーライということで・・・・・・・・・。
 
プログラムは以下。 
/*
===============================================================================
Name        : main.c
Author      : $(author)
Version     : 0.8
Copyright   : (copyright)
Description : main definition
===============================================================================
*/
#include "LPC8xx.h"
#include "lpc8xx_uart.h"
extern volatile uint32_t UARTRxCount;           //UART受信カウント変数
extern volatile uint8_t UARTRxBuffer[BUFSIZE];  //UART受信データ変数
volatile uint8_t gps_data; //GPS入力データ
volatile uint8_t gprmc[12]; //GPS日時データ
volatile uint8_t doy[3]; //day of year
volatile uint8_t msec; //ミリsec
volatile uint32_t msTicks = 0;
volatile uint8_t uruu;
void SysTick_Handler(void) {
 msTicks++;
}
void systick_delay (uint32_t delayTicks) {
 uint32_t currentTicks = msTicks;
 while ((msTicks - currentTicks) < delayTicks);
}
void SwitchMatrix_Init()
{
    /* Enable SWM clock */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
    /* Pin Assign 8 bit Configuration */
    /* U0_RXD */
    LPC_SWM->PINASSIGN0 = 0xffff03ffUL;
    /* Pin Assign 1 bit Configuration */
    /* RESET */
    LPC_SWM->PINENABLE0 = 0xffffffbfUL;
}
void OUT_ON(void){
// LPC_GPIO_PORT->SET0 = 1 << 2;      // PIO0_2 H
 LPC_GPIO_PORT->CLR0 = 1 << 2;      // PIO0_2 L
}
void OUT_OFF(void){
// LPC_GPIO_PORT->CLR0 = 1 << 2;      // PIO0_2 L
 LPC_GPIO_PORT->SET0 = 1 << 2;      // PIO0_2 H
}
void GPS_IN(void){
 while(UARTRxCount == 0){
 }
 LPC_USART0->INTENCLR = RXRDY; /* Disable RXRDY */
 UARTRxCount = 0;
 gps_data = UARTRxBuffer[0];
 LPC_USART0->INTENSET = RXRDY;  /* Re-enable RXRDY */
}
void GPS_TIMING(void){
 l1:
 GPS_IN();
 if(gps_data != '$'){
 goto l1;
 }
 GPS_IN();
 if(gps_data != 'G'){
 goto l1;
 }
 GPS_IN();
 if(gps_data != 'P'){
 goto l1;
 }
 GPS_IN();
 if(gps_data != 'R'){
 goto l1;
 }
 GPS_IN();
 if(gps_data != 'M'){
 goto l1;
 }
 GPS_IN();
 if(gps_data != 'C'){
 goto l1;
 }
}
void GPS_WAIT(void){
 int32_t lp1;
 for(lp1 = 0 ; lp1 < 65 ; lp1++){
 GPS_IN();
 }
}
void WWVB_0(void){
 GPS_TIMING();
 GPS_WAIT();
 OUT_OFF();
 systick_delay(200);
 OUT_ON();
}
void WWVB_1(void){
 GPS_TIMING();
 GPS_WAIT();
 OUT_OFF();
 systick_delay(500);
 OUT_ON();
}
void WWVB_P(void){
 GPS_TIMING();
 GPS_WAIT();
 OUT_OFF();
 systick_delay(800);
 OUT_ON();
}
void WWVB_P2(void){
 OUT_OFF();
 systick_delay(800);
 OUT_ON();
}
void WWVB_PL(uint8_t d1,uint8_t b1){
 if((d1 & b1) == 0){
 WWVB_0();
 }
 else
 {
 WWVB_1();
 }
}
void WWVB_OUT(void){
 WWVB_P2(); //00:P0
 WWVB_PL(gprmc[2],4); //01:MIN 40
 WWVB_PL(gprmc[2],2); //02:MIN 20
 WWVB_PL(gprmc[2],1); //03:MIN 10
 WWVB_0(); //04
 WWVB_PL(gprmc[3],8); //05:MIN 8
 WWVB_PL(gprmc[3],4); //06:MIN 4
 WWVB_PL(gprmc[3],2); //07:MIN 2
 WWVB_PL(gprmc[3],1); //08:MIN 1
 WWVB_P(); //09:P1
 WWVB_0(); //10
 WWVB_0(); //11
 WWVB_PL(gprmc[0],2); //12:HOUR 20
 WWVB_PL(gprmc[0],1); //13:HOUR 10
 WWVB_0(); //14
 WWVB_PL(gprmc[1],8); //15:HOUR 8
 WWVB_PL(gprmc[1],4); //16:HOUR 4
 WWVB_PL(gprmc[1],2); //17:HOUR 2
 WWVB_PL(gprmc[1],1); //18:HOUR 1
 WWVB_P(); //19:P2
 WWVB_0(); //20
 WWVB_0(); //21
 WWVB_PL(doy[0],2); //22:DAY OF YEAR 200
 WWVB_PL(doy[0],1); //23:DAY OF YEAR 100
 WWVB_0(); //24
 WWVB_PL(doy[1],8); //25:DAY OF YEAR 80
 WWVB_PL(doy[1],4); //26:DAY OF YEAR 40
 WWVB_PL(doy[1],2); //27:DAY OF YEAR 20
 WWVB_PL(doy[1],1); //28:DAY OF YEAR 10
 WWVB_P(); //29:P3
 WWVB_PL(doy[2],8); //30:DAY OF YEAR 8
 WWVB_PL(doy[2],4); //31:DAY OF YEAR 4
 WWVB_PL(doy[2],2); //32:DAY OF YEAR 2
 WWVB_PL(doy[2],1); //33:DAY OF YEAR 1
 WWVB_0(); //34
 WWVB_0(); //35
 WWVB_1(); //36:UT! ADD
 WWVB_0(); //37:UT1 SUB
 WWVB_1(); //38:UT1 ADD
 WWVB_P(); //39:P4
 WWVB_PL(msec,8); //40:UT1 0.8
 WWVB_PL(msec,4); //41:UT1 0.4
 WWVB_PL(msec,2); //42:UT1 0.2
 WWVB_PL(msec,1); //43:UT1 0.1
 WWVB_0(); //44
 WWVB_PL(gprmc[10],8); //45:YEAR 80
 WWVB_PL(gprmc[10],4); //46:YEAR 40
 WWVB_PL(gprmc[10],2); //47:YEAR 20
 WWVB_PL(gprmc[10],1); //48:YEAR 10
 WWVB_P(); //49:P5
 WWVB_PL(gprmc[11],8); //50:YEAR 8
 WWVB_PL(gprmc[11],4); //51:YEAR 4
 WWVB_PL(gprmc[11],2); //52:YEAR 2
 WWVB_PL(gprmc[11],1); //53:YEAR 1
 WWVB_0(); //54:
 WWVB_PL(uruu,1); //55:LEAP YEAR
 WWVB_0(); //56:LEAP SECOND
 WWVB_0(); //57:DAYLIGHT SAVING
 WWVB_0(); //58:DAYLIGHT SAVING
 WWVB_P(); //59:P0
}
int main(void) {
 int32_t loop1,day_of_year = 0;
 uint8_t day,month,year,hour,doy_add;
 SystemCoreClockUpdate();
 SysTick_Config(SystemCoreClock / 1000);
 UARTInit(LPC_USART0, 9600); //UART初期化9600BPS
    SwitchMatrix_Init(); //スイッチマトリックス設定
    LPC_GPIO_PORT->DIR0 |= (1 << 2); //PIO0_2 を出力ポートに設定
    OUT_ON(); //OUT_ON
    /*-------------- MAIN LOOP ----------------------*/
    while(1)  {
     l2:
     GPS_TIMING();
     GPS_IN();
     for(loop1 = 0 ; loop1 < 6 ; loop1++){
     GPS_IN();
     gprmc[loop1] = gps_data - 0x30;
     }
     GPS_IN();
     GPS_IN();
     msec = gps_data -0x30;
     for(loop1 = 0 ; loop1 < 42 ; loop1++){
     GPS_IN();
     }
     for(loop1 = 6 ; loop1 < 12 ; loop1++){
     GPS_IN();
     gprmc[loop1] = gps_data - 0x30;
     }
     if(gprmc[10] == 0){
     goto l2;
     }
     if(gprmc[4] != 0){
     goto l2;
     }
     if(gprmc[5] != 0){
     goto l2;
     }
     month = gprmc[8] * 10 + gprmc[9];
     year = gprmc[10] * 10 + gprmc[11];
     hour = gprmc[0] * 10 + gprmc[1];
     hour = hour + 14;
     if(hour >  23){
     hour = hour - 24;
     doy_add = 1;
     }
     else
     {
     doy_add = 0;
     }
     day = gprmc[6] * 10 + gprmc[7] + doy_add;
     if((year & 3) == 0){
     uruu = 1;
     }
     else
     {
     uruu = 0;
     }
     if(month == 1){
     day_of_year = day;
     }
     if(month == 2){
     day_of_year = 31 + day;
     }
     if(month == 3){
     day_of_year = 59 +day + uruu;
     }
     if(month == 4){
     day_of_year = 90 + day + uruu;
     }
     if(month == 5){
     day_of_year = 120 + day + uruu;
     }
     if(month == 6){
     day_of_year = 151 + day + uruu;
     }
     if(month == 7){
     day_of_year = 181 + day + uruu;
     }
     if(month == 8){
     day_of_year = 212 + day + uruu;
     }
     if(month == 9){
     day_of_year = 243 + day + uruu;
     }
     if(month == 10){
     day_of_year = 273 + day + uruu;
     }
     if(month == 11){
     day_of_year = 304 + day + uruu;
     }
     if(month == 12){
     day_of_year = 334 + day + uruu;
     }
     if((day_of_year - uruu) > 365){
     year = year + 1;
         if((year & 3) == 0){
         uruu = 1;
         }
         else
         {
         uruu = 0;
         }
     day_of_year = 1;
     }
     doy[0] = day_of_year / 100;
     doy[1] = day_of_year / 10 - (doy[0] * 10);
     doy[2] = day_of_year - (doy[0] * 100) - (doy[1] * 10);
     gprmc[10] = year / 10;
     gprmc[11] = year - (gprmc[10] * 10);
     gprmc[0] = hour / 10;
     gprmc[1] = hour - (gprmc[0] * 10);
     WWVB_OUT();
    }
    /*-----------------------------------------------*/
}

« Weekender by HITEC Q4i HD200 RTF LED消灯方法 | トップページ | OLED 128*32 SPI+BMP085 I2C 気圧センサー+LPC811でお天気予測ガジェット作成中 »

趣味」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: LPC810でGPS(GT-723F)→WWVB出力:

« Weekender by HITEC Q4i HD200 RTF LED消灯方法 | トップページ | OLED 128*32 SPI+BMP085 I2C 気圧センサー+LPC811でお天気予測ガジェット作成中 »