Frequency counter using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Dependencies: QEI DRV8830 PID ADT7410 TextLCD Frq_cuntr_Nucleo-F746ZG RingBuffer
Fork of Frequency_Counter_w_GPS_1PPS by
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
main.cpp
- Committer:
- kenjiArai
- Date:
- 2014-10-22
- Revision:
- 7:0c09d29c4cf3
- Parent:
- 6:44c2bcbdd77b
- Child:
- 8:7b033903c8fb
File content as of revision 7:0c09d29c4cf3:
/* * mbed Application program / Frequency Counter * * Copyright (c) 2014 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: October 18th, 2014 * Revised: October 22nd, 2014 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define USE_COM // use Communication with PC(UART) #define USE_TEXT_LCD // use Text LCD/I2C Interface #define USE_GRAP_LCD // use Grafic LCD/SPI interface // Include --------------------------------------------------------------------------------------- #include "mbed.h" #include "freq_counter.h" #if defined(USE_TEXT_LCD) #include "TextLCD.h" // Std. lib./ LCD control #endif #if defined(USE_GRAP_LCD) #include "ST7565_SPI_LCD.h" #endif // Definition ------------------------------------------------------------------------------------ #ifdef USE_COM #define BAUD(x) pc.baud(x) #define GETC(x) pc.getc(x) #define PUTC(x) pc.putc(x) #define PRINTF(...) pc.printf(__VA_ARGS__) #define READABLE(x) pc.readable(x) #else #define BAUD(x) {;} #define GETC(x) {;} #define PUTC(x) {;} #define PRINTF(...) {;} #define READABLE(x) {;} #endif #if defined(TARGET_LPC1768) // LPC1768 Frequency example // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx) #define CLK_REFRENCE() PWM6_SETCLK(19) // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx) //#define CLK_REFRENCE() PWM6_SETCLK(96) #elif defined(TARGET_LPC1114) #define led_not_zero temp_ram #define led_01 temp_ram #define led_10 temp_ram #define CLK_REFRENCE() clock_out() #warning "Don't forget LPC1114 runs with internal clock. Measurement data is not accurate!!" #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) #define led_not_zero temp_ram #define led_01 temp_ram #define led_10 temp_ram #define CLK_REFRENCE() port_mco1_mco2_set() #else #error "No support for this CPU" #endif // Object ---------------------------------------------------------------------------------------- #if defined(TARGET_LPC1768) DigitalOut led_gate(LED1); DigitalOut led_not_zero(LED2); DigitalOut led_01(LED3); DigitalOut led_10(LED4); DigitalIn sw_01(p19); DigitalIn sw_10(p20); Serial pc(USBTX, USBRX); I2C i2cBus(p9, p10); // SDA, SCL #if defined(USE_TEXT_LCD) TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) #endif #if defined(USE_GRAP_LCD) ST7565 glcd(p5, p7, p19, p8, p20, ST7565::AD12864SPI); // mosi, sck, reset, a0, ncs #endif PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6] F_COUNTER fc(p30); #elif defined(TARGET_LPC1114) DigitalOut led_gate(LED2); DigitalIn sw_01(dp25); DigitalIn sw_10(dp26); Serial pc(dp16,dp15); // Communication with Host I2C i2cBus(dp5,dp27); // SDA, SCL #if defined(USE_TEXT_LCD) TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) #endif #if defined(USE_GRAP_LCD) ST7565 glcd(dp2, dp6, dp10, dp4, dp9, ST7565::AQM1248A); // mosi, sck, reset, a0, ncs #endif F_COUNTER fc(dp14); // dp24 uses for CLOCKOUT -> Clock output for checking #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) DigitalOut led_gate(LED1); DigitalIn sw_01(PC_0); DigitalIn sw_10(PC_1); Serial pc(USBTX, USBRX); I2C i2cBus(PB_9,PB_8); // SDA, SCL #if defined(USE_TEXT_LCD) TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) #endif #if defined(USE_GRAP_LCD) ST7565 glcd(PB_5, PB_3, PA_10, PB_10, PA_9, ST7565::AD12864SPI); // mosi, sck, reset, a0, ncs #endif F_COUNTER fc(PA_0); // PA8 & PC9 uses for MCO_1 % MCO_2 -> Clock output for checking #else #error "No support for this CPU" #endif // RAM ------------------------------------------------------------------------------------------- float freqency; double t_gate; uint8_t sw; uint32_t temp_ram; // dummy ram (please keep it!) // ROM / Constant data --------------------------------------------------------------------------- // Function prototypes --------------------------------------------------------------------------- // Function prototypes --------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- #if defined(TARGET_LPC1768) // Clock Output From pin21(PWM6) // Set Clock Freq with div. // if mbed is running at 96MHz, div is set 96 to Get 1MHz. void PWM6_SETCLK(int div) { LPC_PWM1->TCR = (1 << 1); // 1)Reset counter, disable PWM LPC_SC->PCLKSEL0 &= ~(0x3 << 12); LPC_SC->PCLKSEL0 |= (1 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock LPC_PWM1->MR0 = div - 1; // 3)Match Register 0 is shared period counter for all PWM1 LPC_PWM1->MR6 = (div + 1)>> 1; // LPC_PWM1->LER |= 1; // 4)Start updating at next period start LPC_PWM1->TCR = (1 << 0) || (1 << 3); // 5)Enable counter and PWM } #elif defined(TARGET_LPC1114) // CLOCKOUT from pin24(dp18) // Freq = 48MHz/4 = 12MHz void clock_out(void) { LPC_SYSCON->CLKOUTCLKSEL = 3; // System clock LPC_SYSCON->CLKOUTDIV = 4; // div 1/4 LPC_IOCON->PIO0_1 = 1; // select CLKOUT to P0_1(pin24)/dp18 LPC_SYSCON->CLKOUTUEN = 1; // enable output } #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) void port_mco1_mco2_set(void) { uint32_t temp = 0x00; // PA8 -> MCO_1 temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)8 & (uint32_t)0x07) * 4)) ; GPIOA->AFR[8 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(8 & (uint32_t)0x07) * 4)) ; GPIOA->AFR[8 >> 3] |= temp; GPIOA->MODER &= ~(GPIO_MODER_MODER0 << (8 * 2)); GPIOA->MODER |= (0x2 << (8 * 2)); // PC9 -> MCO_2 temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)9 & (uint32_t)0x07) * 4)) ; GPIOC->AFR[9 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(9 & (uint32_t)0x07) * 4)) ; GPIOC->AFR[9 >> 3] |= temp; GPIOC->MODER &= ~(GPIO_MODER_MODER0 << (9 * 2)); GPIOC->MODER |= (0x2 << (9 * 2)); // Select output clock source RCC->CFGR &= 0x009fffff; // MC0_1 output HSE 1/4, MCO_2 output SYSCLK 1/4 // MCO2 MCO2PRE MCO1PRE MCO1 RCC->CFGR |= (0x0 << 30) + (0x6 << 27) + (0x6 << 24) + (0x3 << 22); } #else #error "No support for this CPU" #endif void read_sw_and_set_gate_time(void) { if (sw_10) { led_10 = 1; sw = 2; } else { led_10 = 0; sw = 0; } if (sw_01) { led_01 = 1; sw += 1; } else { led_01 = 0; } switch (sw) { case 0: t_gate = 0.001; break; case 1: t_gate = 0.01; break; case 2: t_gate = 0.1; break; case 3: default: t_gate = 1.0; break; } } int main() { PRINTF("\r\nFrequency Counter by JH1PJL created on "__DATE__"\r\n"); t_gate = 1.0; // Initialize LCD #if defined(USE_TEXT_LCD) lcd.locate(0, 0); // 1st line top // 12345678 lcd.printf("Fre-Cntr"); lcd.locate(0, 1); // 2nd line top // 12345678 lcd.puts(" JH1PJL "); lcd.setContrast(0x16); #endif #if defined(USE_GRAP_LCD) glcd.cls(); glcd.locate(0, 0); glcd.printf("--- Frequency Counter --\r\n"); glcd.printf(" Kenji Arai / JH1PJL\r\n" ); glcd.printf(" \r\n"); #if defined(TARGET_LPC1768) glcd.set_contrast(0x06); glcd.printf(" Input: P30 PWM out: P21\r\n" ); glcd.printf(" LED1:Gate LED2:signal \r\n" ); #elif defined(TARGET_LPC1114) glcd.set_contrast(0x01); glcd.printf(" LED2:Gate " ); #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) glcd.set_contrast(0x06); glcd.printf(" Input: PA0 PWM out: PA8\r\n" ); glcd.printf(" LED1:Gate \r\n" ); #else #error "No support for this CPU" #endif #endif // defined(USE_GRAP_LCD) #if defined(USE_TEXT_LCD) wait(5.0); lcd.locate(0, 1); // 2nd line top // 12345678 lcd.puts(" "); #endif // Set Internalclock for reference CLK_REFRENCE(); freqency = 0; while(true) { led_gate = 1; freqency = (float)fc.read_frequency(t_gate); led_gate = 0; wait(1.1 - t_gate); if (freqency == 0) { led_not_zero = 1; } else { led_not_zero = 0; } read_sw_and_set_gate_time(); PRINTF("f= %9.0f [Hz], gate= %4.3f [Sec]\r\n", freqency/t_gate, t_gate); #if defined(USE_TEXT_LCD) lcd.locate(0, 0); // 1st line top lcd.printf("%8.0f", freqency); lcd.locate(0, 1); // 2nd line top #endif #if defined(USE_GRAP_LCD) glcd.locate(0, 10); glcd.printf(" \r\n"); glcd.locate(10, 10); glcd.printf("%8.0f Hz", freqency); glcd.locate(10, 20); #endif switch (sw) { case 0: #if defined(USE_TEXT_LCD) // 12345678 lcd.printf("x1000 Hz"); #endif #if defined(USE_GRAP_LCD) glcd.printf(" x1000 "); #endif break; case 1: #if defined(USE_TEXT_LCD) // 12345678 lcd.printf("x100 Hz"); #endif #if defined(USE_GRAP_LCD) glcd.printf(" x100 "); #endif break; case 2: #if defined(USE_TEXT_LCD) // 12345678 lcd.printf("x10 Hz"); #endif #if defined(USE_GRAP_LCD) glcd.printf("x10 "); #endif break; case 3: default: #if defined(USE_TEXT_LCD) // 12345678 lcd.printf("x1 Hz"); #endif #if defined(USE_GRAP_LCD) glcd.printf(" x1 "); #endif break; } } }