lab
Fork of Adafruit_GFX by
Revision 18:694480a1463c, committed 2016-05-04
- Comitter:
- chaolyu14
- Date:
- Wed May 04 17:52:57 2016 +0000
- Parent:
- 17:4191e754fe07
- Commit message:
- main
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 4191e754fe07 -r 694480a1463c main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed May 04 17:52:57 2016 +0000 @@ -0,0 +1,227 @@ +#include "mbed.h" +#include "Adafruit_SSD1306.h" + +//Switch input definition +#define SW_PIN_0 p21 +#define SW_PIN_1 p22 +#define SW_PIN_2 p23 +#define SW_PIN_3 p24 + +#define Digital_Out_1 p17 +//Sampling period for the switch oscillator (us) +#define SW_PERIOD 20000 + +//Display interface pin definitions +#define D_MOSI_PIN p5 +#define D_CLK_PIN p7 +#define D_DC_PIN p8 +#define D_RST_PIN p9 +#define D_CS_PIN p10 + +//an SPI sub-class that sets up format and clock speed +class SPIPreInit : public SPI +{ +public: + SPIPreInit(PinName mosi, PinName miso, PinName clk) : SPI(mosi,miso,clk) + { + format(8,3); + frequency(2000000); + }; +}; + +bool status(volatile uint16_t scount, bool preVal); + +//Interrupt Service Routine prototypes (functions defined below) +void sedge0(); +void sedge1(); +void sedge2(); +void sedge3(); +void tout(); +void flip(); +void incrementer(uint8_t& x); + +//Output for the alive LED +DigitalOut alive(LED1); +DigitalOut OUT_1(Digital_Out_1); + +//External interrupt input from the switch oscillator +InterruptIn sw0in(SW_PIN_0); +InterruptIn sw1in(SW_PIN_1); +InterruptIn sw2in(SW_PIN_2); +InterruptIn sw3in(SW_PIN_3); + +//Switch sampling timer +Ticker swtimer; +Ticker flipper; +//Registers for the switch counter, switch counter latch register and update flag +volatile uint16_t scounter0=0;volatile uint16_t scounter1=0;volatile uint16_t scounter2=0;volatile uint16_t scounter3=0; + +volatile uint16_t scount0=0;volatile uint16_t scount1=0;volatile uint16_t scount2=0;volatile uint16_t scount3=0; + +volatile uint16_t update=0; + +//Initialise SPI instance for communication with the display +SPIPreInit gSpi(D_MOSI_PIN,NC,D_CLK_PIN); //MOSI,MISO,CLK + +//Initialise display driver instance +Adafruit_SSD1306_Spi gOled1(gSpi,D_DC_PIN,D_RST_PIN,D_CS_PIN,64,128); //SPI,DC,RST,CS,Height,Width + +int main() { + //Initialisation + gOled1.setRotation(2); //Set display rotation + + //Attach switch oscillator counter ISR to the switch input instance for a rising edge + sw0in.rise(&sedge0);sw1in.rise(&sedge1);sw2in.rise(&sedge2);sw3in.rise(&sedge3); + + //Attach switch sampling timer ISR to the timer instance with the required period + swtimer.attach_us(&tout, SW_PERIOD); + //Main loop + bool preVal0 = false; + bool preVal1 = false; + bool preVal2 = false; + bool preVal3 = false; + + uint8_t out_period_3 = 0; + uint8_t out_period_2 = 0; + uint8_t out_period_1 = 0; + uint8_t out_period_0 = 0; + + uint16_t out_period = 0; + + while(1) + { + //Has the update flag been set? + if (update) { + //Clear the update flag + update = 0; + + //Set text cursor + gOled1.setTextCursor(0,0); + + //Write the latest switch osciallor count + gOled1.printf("F_sw0: "); + gOled1.printf("%02u", scount0); + gOled1.printf(" kHz" ); + + if(status(scount0,preVal0)){ + if(preVal0 == false ){ + incrementer(out_period_3); + } + preVal0 = true; + gOled1.printf(" ON" ); + + }else{ + preVal0 = false; + gOled1.printf(" OFF" ); + } + + gOled1.printf("\nF_sw1: "); + gOled1.printf("%02u", scount1); + gOled1.printf(" kHz" ); + if(status(scount1,preVal1)){ + if(preVal1 == false){ + incrementer(out_period_2); + } + preVal1 = true; + gOled1.printf(" ON" ); + }else{ + preVal1 = false; + gOled1.printf(" OFF" ); + } + + gOled1.printf("\nF_sw2: "); + gOled1.printf("%02u", scount2); + gOled1.printf(" kHz" ); + if(status(scount2,preVal2)){ + if(preVal2 == false){ + incrementer(out_period_1); + } + preVal2 = true; + gOled1.printf(" ON" ); + }else{ + preVal2 = false; + gOled1.printf(" OFF" ); + } + + gOled1.printf("\nF_sw3: "); + gOled1.printf("%02u", scount3); + gOled1.printf(" kHz" ); + if(status(scount3,preVal3)){ + if(preVal3 == false){ + incrementer(out_period_0); + } + preVal3 = true; + gOled1.printf(" ON" ); + }else{ + preVal3 = false; + gOled1.printf(" OFF" ); + } + gOled1.printf("\n\nOutput Frequency : "); + out_period = out_period_3*1000 + out_period_2*100 + out_period_1*10 + out_period_0; + gOled1.printf("\n%04u", out_period); + gOled1.printf(" kHz"); + if(out_period != 0){ + flipper.attach(&flip, float(0.5/out_period)); + } + //Copy the display buffer to the display + gOled1.display(); + + //Toggle the alive LED + alive = !alive; + } + } +} + +void flip() { + OUT_1 = !OUT_1; +} + +//Interrupt Service Routine for rising edge on the switch oscillator input +void sedge0() { + //Increment the edge counter + scounter0++; +} +void sedge1() { + //Increment the edge counter + scounter1++; +} +void sedge2() { + //Increment the edge counter + scounter2++; +} +void sedge3() { + //Increment the edge counter + scounter3++; +} + +void incrementer(uint8_t& x){ + if(x < 9){ + x++; + }else{ + x=0; + } +} + +//Interrupt Service Routine for the switch sampling timer +void tout() { + //Read the edge counter into the output register + scount0 = scounter0 / 20;scount1 = scounter1 / 20;scount2 = scounter2 / 20;scount3 = scounter3 / 20; + + //Reset the edge counter + scounter0 = 0;scounter1 = 0;scounter2 = 0; scounter3 = 0; + + //Trigger a display update in the main loop + update = 1; +} + +bool status(volatile uint16_t scount, bool preVal) +{ + if(scount <= 55){ + return true; + }else if(scount >= 65){ + return false; + }else{ + return preVal; + } +} +