/***************************************************************************** ** �������: LCD_WriteBMP ** ��������: ��ָ����λ����ʾһ��ͼƬ Xpos��YposΪͼƬ��ʾ��ַ��Height��Width ΪͼƬ�Ŀ�Ⱥ߶� ** �� ����: Dream ** �ա� ��: 2010��12��06�� *****************************************************************************/ void LCD_WriteBMP(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width, uint8_t *bitmap) { uint32_t index; uint32_t size = Height * Width; uint16_t *bitmap_ptr = (uint16_t *)bitmap; LCD_SetDisplayWindow(Xpos, Ypos, Width-1, Height-1); //LCD_WriteReg(0x03, 0x1038); //�����Ҫ������ʾͼƬ������ȥ������ ��ͬʱ��Width��Hight����һ�¾Ϳ��� LCD_WriteRAM_Prepare(); for(index = 0; index < size; index++) { Write_Dat(*bitmap_ptr++); } //�ָ������С LCD_WriteReg(R80, 0x0000); //ˮƽ����GRAM��ʼ��ַ LCD_WriteReg(R81, 0x00EF); //ˮƽ����GRAM�����ַ LCD_WriteReg(R82, 0x0000); //��ֱ����GRAM��ʼ��ַ LCD_WriteReg(R83, 0x013F); //��ֱ����GRAM�����ַ }
static void displaySMeter(int RSL) { int x = 80; int y = 68; LCD_SetDisplayWindow(x, y, SMETER_HEIGHT, FFT_WIDTH); LCD_WriteRAM_PrepareDir(LCD_WriteRAMDir_Down); int Signal_Level = ((RSL + 120) * 26) / 10; for (int x = 0; x < FFT_WIDTH; x++) { for (int y = 0; y < SMETER_HEIGHT; y++) { if (x <= Signal_Level) { LCD_WriteRAM(LCD_COLOR_GREEN); } else { LCD_WriteRAM(LCD_COLOR_DGRAY); } } } char SMeter$[7]; if (Signal_Level < 120) { if (Signal_Level < 0) Signal_Level = 0; int SLevel = Signal_Level / 12; sprintf(SMeter$, "S%i ", SLevel); } else { int SLevel = 9; int R = (Signal_Level - 100) / 3; sprintf(SMeter$, "S%i+%2i", SLevel, R); } GL_SetBackColor(LCD_COLOR_BLACK); GL_SetTextColor(LCD_COLOR_WHITE); GL_PrintString(1, 64, SMeter$, 0); }
static void LCD_Config(void) { /* Initialise the LCD */ LCD_Init(); /* Initialise the LCD Layers */ LCD_LayerInit(); /* Clear the Hole LCD */ LCD_Clear(LCD_COLOR_WHITE); /* Set the Foreground as active Layer */ LCD_SetLayer(LCD_FOREGROUND_LAYER); /* Configure the window size and position */ LCD_SetDisplayWindow(0, 0, 100, 100); /* Configure the LCD frame Buffer Address */ LCD_SetAddress((uint32_t)&aBufferResult); /* Configure the LCD Pixel Format */ LCD_SetPixelFormat(LTDC_Pixelformat_ARGB4444); }
/** * @brief RCR receiver demo exec. * @param None * @retval None */ void Menu_RC5Decode_Func(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Disable the TIM15, LED Toggling */ TIM_Cmd(TIM15, DISABLE); /* Disable the JoyStick interrupt */ Demo_IntExtOnOffCmd(DISABLE); while (Menu_ReadKey() != NOKEY) {} /* Clear the LCD */ LCD_Clear(LCD_COLOR_WHITE); /* Display Image */ LCD_SetDisplayWindow(120, 192, 64, 64); Storage_OpenReadFile(120, 192, "STFILES/TV.BMP"); LCD_WindowModeDisable(); /* Set the LCD Back Color */ LCD_SetBackColor(LCD_COLOR_BLUE); /* Set the LCD Text Color */ LCD_SetTextColor(LCD_COLOR_WHITE); LCD_DisplayStringLine(LCD_LINE_9, " To exit press UP "); /* Initialize the InfraRed application: RC5 */ RFDemoStatus = RC5DEMO; RC5_Init(); while(Menu_ReadKey() != UP) { /* Decode the RC5 frame */ RC5_Decode(&RC5_FRAME); } LCD_Clear(LCD_COLOR_WHITE); TIM_DeInit(TIM2); /* Time Base configuration 100ms*/ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 1000; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 0x0C80; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Channel 1, 2, 3 and 4 Configuration in Timing mode */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0x0; TIM_OC1Init(TIM2, &TIM_OCInitStructure); Demo_LedShow(ENABLE); /* Exit the RF5 demo */ RFDemoStatus = 0; /* Enable the JoyStick interrupt */ Demo_IntExtOnOffCmd(ENABLE); /* Display menu */ Menu_DisplayMenu(); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); Redbull_Init(); char buff[128] = { 0 }; LCD_DisplayStringLine(LINE(10), (uint8_t*) " Analog .............................."); Analog_Config(); printRight(10, "ok"); LCD_DisplayStringLine(LINE(11), (uint8_t*) " DAC ................................."); DAC_Config(); printRight(11, "ok"); f_mount(0, &fatfs); LCD_DisplayStringLine(LINE(12), (uint8_t*) " TEMP ................................"); OneWireInit(); float c = Read_Temperature(); sprintf(buff, "%.1f", c); printRight(12, buff); printf("%s\n", buff); RGBLED_GPIO_Config(0xff); RGBLED_Update(0xff,0xff,0xff); Delay(200); RGBLED_Update(0xff,0,0); Delay(200); RGBLED_Update(0,0xff,0); Delay(200); RGBLED_Update(0,0,0xff); Delay(200); RGBLED_Update(0,0,0); //static char path[1024] = "0:"; //LCD_Clear(LCD_COLOR_BLUE); //LCD_DisplayStringLine(0, (uint8_t*) "Loading..."); Delay(1000); //int i = 10; LCD_Clear(LCD_COLOR_BLACK); LCD_SetDisplayWindow(0, 0, 239, 319); LCD_WriteReg(3, 0x1000); LCD_WriteRAM_Prepare(); TIM_Cmd(TIM7, ENABLE); DMARead(); //float h = 0, s = 1, v = 1; while (1) { while (DMA_GetFlagStatus(DMA1_FLAG_TE1) == SET) { printf("DMA error\n"); Delay(100); } //uint32_t ms = millis(); uint16_t rem = DMA_GetCurrDataCounter(DMA1_Channel1); uint16_t cnt = 0xffff - rem; if (cnt >= 80 && cnt < 512) { continue; } uint32_t buff[160] = { 0 }; uint16_t tillend = cnt > 160 ? 160 : cnt; uint16_t fromstart = 160 - tillend; uint16_t bcnt = cnt - 160; // before SRAM_ReadBuffer((uint16_t*) &buff[0], bcnt * 4, tillend * 2); // after if (fromstart) { SRAM_ReadBuffer((uint16_t*) &buff[tillend], 0, fromstart * 2); } uint8_t prevsv = 0; for (uint16_t i = 0; i < 320; i++) { uint16_t val = 0; if (i & 1) { val = buff[i >> 1] & 0x0fff; } else { val = (buff[i >> 1] >> 16) & 0x0fff; } #define MAXV (17 * 238) val = val > MAXV ? MAXV : val; uint8_t sv = val / 17; sv = sv > 238 ? 238 : sv; sv++; if (!prevsv) { prevsv = sv; } uint16_t pbuf[240]; uint8_t minv = sv > prevsv ? prevsv : sv; uint8_t maxv = sv < prevsv ? prevsv : sv; for (uint8_t y = 0; y < 240; y++) { if (y >= minv && y <= maxv) { pbuf[y] = LCD_COLOR_YELLOW; } else { pbuf[y] = LCD_COLOR_BLACK; } } prevsv = sv; DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA2_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) pbuf; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &LCD->LCD_RAM; // FSMC DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 240; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; DMA_Init(DMA2_Channel5, &DMA_InitStructure); DMA_Cmd(DMA2_Channel5, ENABLE); RTC_t rtc; RTC_GetTime(&rtc); //RGBLED_Update((rtc.min & 1) ? 0 : (rtc.hour * 10), ((rtc.sec >> 2) & 1) ? 0 : (rtc.min * 4), rtc.sec * 4); while (!DMA_GetFlagStatus(DMA2_FLAG_TC5)) ; DMA_ClearFlag(DMA2_FLAG_TC5); while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == RESET) ; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { //RCC_Config(); //GPIO_Config(); //RCC_MCO1Config(RCC_MCO1Source_PLLCLK,RCC_MCO1Div_1); uint8_t tmpreg; LIS302DL_InitTypeDef LIS302DL_InitStruct; /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); //NVIC_SetPriority(SysTick_IRQn, -1); /* MEMS configuration and set int1/int2 pins*/ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); //Set INT1/INT2 pins tmpreg = 0x40; LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG3_ADDR, 1); //Initialize the touchscreen TSC_Init(); /* Initialize LEDs and push-buttons mounted on STM324xG-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); //STM_EVAL_LEDInit(LED3); //STM_EVAL_LEDInit(LED4); /* Initialize the LCD */ STM324xG_LCD_Init(); //STM_EVAL_LEDOn(LED1); LCD_Clear(Black); LCD_SetTextColor(White); LCD_LOG_SetHeader("STM32 Camera Demo"); LCD_LOG_SetFooter (" Copyright (c) STMicroelectronics" ); /* ADC configuration */ ADC_Config(); /* Initializes the DCMI interface (I2C and GPIO) used to configure the camera */ //OV9655_HW_Init(); OV9712_HW_Init(); /* Read the OV9655/OV2640 Manufacturer identifier */ //OV9655_ReadID(&OV9655_Camera_ID); OV9712_ReadID(&OV9712_Camera_ID); //while(1); if(OV9655_Camera_ID.PID == 0x96) { Camera = OV9712_CAMERA; sprintf((char*)buffer, "OV9655 Camera ID 0x%x", OV9655_Camera_ID.PID); ValueMax = 2; } else if(OV9712_Camera_ID.PIDH == 0x97) { Camera = OV9712_CAMERA; sprintf((char*)buffer, "OV9712 Camera ID 0x%x", OV9712_Camera_ID.PIDH); ValueMax = 2; } else { LCD_SetTextColor(LCD_COLOR_RED); sprintf((char*)buffer, "OV Camera ID 0x%02x%02x", OV9655_Camera_ID.Version, OV9712_Camera_ID.PIDH); LCD_DisplayStringLine(LINE(4), buffer); while(1); } LCD_SetTextColor(LCD_COLOR_YELLOW); LCD_DisplayStringLine(LINE(4), (uint8_t*)buffer); LCD_SetTextColor(LCD_COLOR_WHITE); Delay(200); /* Initialize demo */ ImageFormat = (ImageFormat_TypeDef)BMP_QVGA; /* Configure the Camera module mounted on STM324xG-EVAL board */ Demo_LCD_Clear(); LCD_DisplayStringLine(LINE(4), "Camera Init.. "); Camera_Config(); sprintf((char*)buffer, " Image selected: %s", ImageForematArray[ImageFormat]); LCD_DisplayStringLine(LINE(4),(uint8_t*)buffer); LCD_ClearLine(LINE(4)); Demo_LCD_Clear(); if(ImageFormat == BMP_QQVGA) { /* LCD Display window */ LCD_SetDisplayWindow(60, 80, 160, 120); ReverseLCD(); LCD_WriteRAM_Prepare(); } else if(ImageFormat == BMP_QVGA) { /* LCD Display window */ LCD_SetDisplayWindow(0, 0, 320, 240); ReverseLCD(); LCD_WriteRAM_Prepare(); } { int i, j; for (j = 0; j < 16; j++) { LCD_SetDisplayWindow(0, (240 / 16) * j, 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(0x0003 << j); } } } /* Enable DMA2 stream 1 and DCMI interface then start image capture */ DMA_Cmd(DMA2_Stream1, ENABLE); DCMI_Cmd(ENABLE); /* Insert 100ms delay: wait 100ms */ //Delay(200); DCMI_CaptureCmd(ENABLE); while(1) { OV9655_BrightnessConfig(0x7F);// //static int step = 0; int i, block, begin; unsigned short *p; if (!bShot) { begin = (datablock - 11 + 48) % 48; for (block = begin; block < begin + 11; block++) { p = (unsigned short *)(0x20000000 + (320 * 240 * 2 / 16) * ((block) % 12)); LCD_SetDisplayWindow(0, (block % 16) * (240 / 16), 320, (240 / 16)); //LCD_SetCursor(0, (block % 16) * (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*p++); } } } if (TSC_TouchDet()) { int x, y; TP_GetAdXY(&x, &y); if (x > 300 && x < 2800 && y > 300 && y < 2800) { if (x < 1550 && y < 1550) { uint32_t StartSector = 0, EndSector = 0, Address = 0, SectorCounter = 0; int m; //拍照bShot bShot = 1; while(datablock % 16); DMA_Cmd(DMA2_Stream1, DISABLE); DCMI_Cmd(DISABLE); //STM_EVAL_LEDOn(LED2); DMA_ClearFlag(DMA2_Stream1, 0x2F7D0F7D); DMA_ClearFlag(DMA2_Stream1, 0x0F7D0F7D); DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); datablock = 0; DMA2_Stream1->M0AR = 0x20000000 + 9600 * (datablock % 12); DMA_SetCurrDataCounter(DMA2_Stream1, (320 * 240 * 2 / 4) / 16); DCMI_Cmd(ENABLE); DMA_Cmd(DMA2_Stream1, ENABLE); { unsigned long *p, *q; while(datablock < 4); //等待准备好前4块数据,就将这4块数据导入到0x10000000+0x50000之后。 q = (unsigned long *)(0x20000000); p = (unsigned long *)(0x10000000 + 0x5000); while (q < (unsigned long *)(0x20000000 + 4 * (320 * 240 * 2 / 16))) { *p = *q; p++; q++; } } while(datablock < 16); //等待全部采集完成。 STM_EVAL_LEDOn(LED2); //LED2亮表示采集完成。 LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); LCD_Clear(Black); //RAM位置 /* 序号 地址 大小 1: 0x10005000+9600*0 9600 2: 0x10005000+9600*1 9600 3: 0x10005000+9600*2 9600 4: 0x10005000+9600*3 9600 5: 0x20000000+9600*5 9600 6: 0x20000000+9600*6 9600 7: 0x20000000+9600*7 9600 8: 0x20000000+9600*8 9600 9: 0x20000000+9600*9 9600 10: 0x20000000+9600*10 9600 11: 0x20000000+9600*11 9600 12: 0x20000000+9600*0 9600 13: 0x20000000+9600*1 9600 14: 0x20000000+9600*2 9600 15: 0x20000000+9600*3 9600 */ for (m = 0; m < 16; m++) //显示保存的图片 { unsigned short *q; if (m < 4) { q = (unsigned short *)(0x10000000 + 0x5000 + m * (320 * 240 * 2 / 16)); } else { q = (unsigned short *)(0x20000000 + (m % 12) * (320 * 240 * 2 / 16)); } LCD_SetDisplayWindow(0, m * (240 / 16), 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*q++); } } /* Erase the user Flash area ***********/ FLASH_Unlock(); /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); /* Get the number of the start and end sectors */ StartSector = GetSector(FLASH_USER_START_ADDR); EndSector = GetSector(FLASH_USER_END_ADDR); for (SectorCounter = StartSector; SectorCounter < EndSector; SectorCounter += 8) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ if (FLASH_EraseSector(SectorCounter, VoltageRange_3) != FLASH_COMPLETE) { /* Error occurred while sector erase. User can add here some code to deal with this error */ while (1) { } } } for (m = 0; m < 16; m++) //保存图片到flash { unsigned long *q; Address = FLASH_USER_START_ADDR + m * (320 * 240 * 2 / 16); if (m < 4) { q = (unsigned long *)(0x10000000 + 0x5000 + m * (320 * 240 * 2 / 16)); } else { q = (unsigned long *)(0x20000000 + (m % 12) * (320 * 240 * 2 / 16)); } while (Address < FLASH_USER_START_ADDR + (m + 1) *(320 * 240 * 2 / 16)) { if (FLASH_ProgramWord(Address, *q) == FLASH_COMPLETE) { Address = Address + 4; q++; } else { /* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ while (1) { } } } } STM_EVAL_LEDOff(LED2); LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); LCD_Clear(Black); for (m = 0; m < 16; m++) //显示flash中的图片 { unsigned short *q; q = (unsigned short *)(FLASH_USER_START_ADDR + m * (320 * 240 * 2 / 16)); LCD_SetDisplayWindow(0, m * (240 / 16), 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*q++); } } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ FLASH_Lock(); } else if (x >= 1550 && y < 1550) { //righttop STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED2); bShot = 0; datablock = 0; DMA_Cmd(DMA2_Stream1, ENABLE); DCMI_Cmd(ENABLE); } else if (x < 1550 && y >= 1550) { //righttop //DMA_Cmd(DMA2_Stream1, ENABLE); //DCMI_Cmd(ENABLE); } else if (x >= 1550 && y >= 1550) { //righttop //DMA_Cmd(DMA2_Stream1, ENABLE); //DCMI_Cmd(ENABLE); } } } //Delay(10); } }
/******************************************************************************* * Function Name : Time_Show * Description : Shows the current time (HH/MM/SS) on LCD. * Input : None * Output : None * Return : None ******************************************************************************/ void Time_Show(void) { uint32_t testvalue = 0, pressedkey = 0; /* Set the Back Color */ LCD_SetBackColor(White); /* Set the Text Color */ LCD_SetTextColor(Blue); /* Disable the JoyStick interrupts */ IntExtOnOffConfig(DISABLE); while(ReadKey()!= NOKEY) { } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Clear the LCD screen */ LCD_Clear(White); LCD_SetDisplayWindow(160, 223, 128, 128); LCD_NORDisplay(WATCH_ICON); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Disable LCD Window mode */ LCD_WindowModeDisable(); if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { LCD_DisplayStringLine(Line7, "Time and Date Config"); LCD_DisplayStringLine(Line8, "Select: Press SEL "); LCD_DisplayStringLine(Line9, "Abort: Press Any Key"); while(testvalue == 0) { pressedkey = ReadKey(); if(pressedkey == SEL) { /* Adjust Time */ Time_PreAdjust(); /* Clear the LCD */ LCD_Clear(White); testvalue = 0x01; } else if (pressedkey != NOKEY) { /* Clear the LCD */ LCD_ClearLine(Line8); /* Display the menu */ DisplayMenu(); /* Enable the JoyStick interrupts */ IntExtOnOffConfig(ENABLE); return; } } /* Display time separators ":" on Line8 */ LCD_DisplayChar(Line8, 212, ':'); LCD_DisplayChar(Line8, 166, ':'); /* Wait a press on any JoyStick pushbuttons */ while(ReadKey() == NOKEY) { /* Display current time */ Time_Display(RTC_GetCounter()); } } else { while(ReadKey() != NOKEY) { } /* Display time separators ":" on Line8 */ LCD_DisplayChar(Line8, 212, ':'); LCD_DisplayChar(Line8, 166, ':'); /* Wait a press on any JoyStick pushbuttons */ while(ReadKey() == NOKEY) { /* Display current time */ Time_Display(RTC_GetCounter()); } } /* Clear the LCD */ LCD_ClearLine(Line8); /* Display the menu */ DisplayMenu(); /* Enable the JoyStick interrupts */ IntExtOnOffConfig(ENABLE); }
static void WidgetFFT_DrawHandler(GL_PageControls_TypeDef* pThis, _Bool force) { // Bail if nothing to draw. if (!force && !DSP_Flag) { return; } int x = pThis->objCoordinates.MinX; int y = pThis->objCoordinates.MinY; /* * Calculate the data to draw: * - Use FFT_Magnitude[0..127] which is 0 to +4kHz of frequency * (don't use last half which is -4kHz to 0kHz) * - Scale the values up to fill a wider portion of the display. * (by averaging with neighboring data). This helps allow the * user to tap on frequencies to select them with better resolution. * - Average with "old" data from the previous pass to give it an * effective time-based smoothing (as in, display does not change * as abruptly as it would when using new data samples each time). */ //uint8_t FFT_Display[256]; static uint8_t FFT_Output[128]; // static because use last rounds data now. // TODO: Where are all these FFT constants from? for (int16_t j = 0; j < 128; j++) { // Changed for getting right display with SR6.3 // Convert from Q15 (fractional numeric representation) into integer FFT_Output[j] = (uint8_t) (6 * log((float32_t) (FFT_Magnitude[j] + 1))); if (FFT_Output[j] > 64) FFT_Output[j] = 64; FFT_Display[2 * j] = FFT_Output[j]; // Note that calculation uses values from last pass through. FFT_Display[2 * j + 1] = 0; //FFT_Display[2 * j + 1] = (FFT_Output[j] + FFT_Output[j + 1]) / 2; } /* * Display the FFT * - Drop the bottom 8, and top 8 frequency-display bins to discard * noisy sections near band edges due to filtering. */ float selectedFreqX = (float) (NCO_Frequency - 125) / 15.625; if (selectedFreqX < 0) { selectedFreqX = 0; } // Draw the FFT using direct memory writes (fast). LCD_SetDisplayWindow(x, y, FFT_HEIGHT, FFT_WIDTH); LCD_WriteRAM_PrepareDir(LCD_WriteRAMDir_Down); for (int x = 0; x < FFT_WIDTH; x++) { // Plot this column of the FFT. for (int y = 0; y < FFT_HEIGHT; y++) { // Draw red line for selected frequency if (x == (int) selectedFreqX) { // Leave some white at the top if (y <= SELFREQ_ADJ) { LCD_WriteRAM(LCD_COLOR_WHITE); } else { LCD_WriteRAM(LCD_COLOR_RED); } } // Draw data else if (FFT_HEIGHT - y < FFT_Display[x + 8]) { LCD_WriteRAM(LCD_COLOR_BLUE); } // Draw background else { LCD_WriteRAM(LCD_COLOR_WHITE); } } } // Update the frequency offset displayed (text): static double oldSelectedFreq = -1; if (force || oldSelectedFreq != NCO_Frequency) { oldSelectedFreq = NCO_Frequency; int textY = y + FFT_HEIGHT + TEXT_OFFSET_BELOW_FFT; int numberX = x + FFT_WIDTH - MAX_FREQ_DIGITS * CHARACTER_WIDTH; int labelX = numberX - CHARACTER_WIDTH * 8; // 7=# letters in label w/ a space GL_SetFont(GL_FONTOPTION_8x16); GL_SetBackColor(LCD_COLOR_BLACK); GL_SetTextColor(LCD_COLOR_WHITE); GL_PrintString(labelX, textY, "Offset:", 0); // Display location on label. GL_SetTextColor(LCD_COLOR_RED); char number[MAX_FREQ_DIGITS + 1]; intToCommaString((int)NCO_Frequency, number, MAX_FREQ_DIGITS + 1); GL_PrintString(numberX, textY, number, 0); } DSP_Flag = 0; // added per Charley }
/** * @brief Disables LCD Window mode. * @param None * @retval None */ void GL_LCD_WindowModeDisable(void) { LCD_SetDisplayWindow(0, 0, LCD_HEIGHT, LCD_WIDTH); }
/** * @brief Sets a display window * @param Xpos: specifies the X bottom left position. * @param Ypos: specifies the Y bottom left position. * @param Height: display window height. * @param Width: display window width. * @retval None */ void GL_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Height, uint16_t Width) { LCD_SetDisplayWindow(Xpos, Ypos, Height, Width); }
/******************************************************************************* * Function Name : Mass_Storage_Start * Description : Starts the mass storage demo. * Input : None * Output : None * Return : None *******************************************************************************/ void Mass_Storage_Start (void) { NVIC_InitTypeDef NVIC_InitStructure; /* Disble the JoyStick interrupts */ IntExtOnOffConfig(DISABLE); while(ReadKey() != NOKEY) { } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Clear the LCD screen */ LCD_Clear(White); LCD_SetDisplayWindow(160, 223, 128, 128); LCD_NORDisplay(USB_ICON); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Disable LCD Window mode */ LCD_WindowModeDisable(); /* Set the Back Color */ LCD_SetBackColor(Blue); /* Set the Text Color */ LCD_SetTextColor(White); /* Display the " Plug the USB " message */ LCD_DisplayStringLine(Line8, " Plug the USB Cable "); LCD_DisplayStringLine(Line9, "Exit: Push JoyStick"); /* Enable and GPIOD clock */ USB_Disconnect_Config(); /* MAL configuration */ MAL_Config(); Set_USBClock(); NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USB_Init(); while (bDeviceState != CONFIGURED) { if(ReadKey() != NOKEY) { PowerOff(); LCD_Clear(White); DisplayMenu(); IntExtOnOffConfig(ENABLE); return; } } LCD_ClearLine(Line9); /* Display the "To stop Press SEL" message */ LCD_DisplayStringLine(Line8, " To stop Press SEL "); /* Loop until SEL key pressed */ while(ReadKey() != SEL) { } PowerOff(); LCD_Clear(White); DisplayMenu(); IntExtOnOffConfig(ENABLE); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); LIS302DL_Reset(); /* SET USER Key */ /* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */ EXTILine0_Config(); /* Initialize the LCD */ STM32f4_Discovery_LCD_Init(); LCD_Clear(LCD_COLOR_WHITE); LCD_SetTextColor(LCD_COLOR_BLUE); DCMI_Control_IO_Init(); LCD_DisplayStringLine(LINE(2), " Camera Init.."); /* OV9655 Camera Module configuration */ if (DCMI_OV9655Config() == 0x00) { LCD_DisplayStringLine(LINE(2), " "); LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); /* Start Image capture and Display on the LCD *****************************/ /* Enable DMA transfer */ DMA_Cmd(DMA2_Stream1, ENABLE); /* Enable DCMI interface */ DCMI_Cmd(ENABLE); /* Start Image capture */ DCMI_CaptureCmd(ENABLE); /*init the picture count*/ init_picture_count(); KeyPressFlg = 0; while (1) { /* Insert 100ms delay */ Delay(100); if (KeyPressFlg) { KeyPressFlg = 0; /* press user KEY take a photo */ if (capture_Flag == ENABLE) { DCMI_CaptureCmd(DISABLE); capture_Flag = DISABLE; Capture_Image_TO_Bmp(); LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); DCMI_CaptureCmd(ENABLE); capture_Flag = ENABLE; } } } } else { LCD_SetTextColor(LCD_COLOR_RED); LCD_DisplayStringLine(LINE(2), "Camera Init.. fails"); LCD_DisplayStringLine(LINE(4), "Check the Camera HW "); LCD_DisplayStringLine(LINE(5), " and try again "); /* Go to infinite loop */ while (1); } }
/******************************************************************************* * Function Name : Thermometer_Temperature * Description : Displays the temperature in Celsius and fahrenheit degree. * Input : None * Output : None * Return : None *******************************************************************************/ void Thermometer_Temperature(void) { uint32_t i = 0; while(ReadKey() != NOKEY) { } if(I2C_LM75_Status() == SUCCESS) { /* Disable the JoyStick Interrupts */ IntExtOnOffConfig(DISABLE); /* Clear the LCD */ LCD_Clear(White); /* Set the Icon display window */ LCD_SetDisplayWindow(150, 210, 64, 84); /* Display the Thermometer icon */ LCD_DrawBMP(0x0062A300); /* Disable LCD Window mode */ LCD_WindowModeDisable(); /* Set the Back Color */ LCD_SetBackColor(Red); /* Set the Text Color */ LCD_SetTextColor(White); LCD_DisplayStringLine(Line2, " Temperature "); /* Set the Back Color */ LCD_SetBackColor(Blue); /* Set the Text Color */ LCD_SetTextColor(Green); /* Wait until no key is pressed */ while(ReadKey() != NOKEY) { } /* Wait until a key is beiing pressed */ while(ReadKey() == NOKEY) { /* Get double of Temperature value */ TempCelsius_Value = I2C_LM75_Temp_Read(); if(TempCelsius_Value <= 1023) { /* Positive temperature measured */ TempCelsius_Display[5] = '+'; TempFahrenheit_Display[5] = '+'; } else { /* Negative temperature measured */ TempCelsius_Display[5] = '-'; TempFahrenheit_Display[5] = '-'; /* Remove temperature value sign */ TempCelsius_Value = 0x800 - TempCelsius_Value; } /* Calculate temperature digits in °C */ Temp_Decimal = ((TempCelsius_Value & 7) * 1000 / 8); TempCelsius_Display[10] = (Temp_Decimal / 100) + 0x30; TempCelsius_Display[11] = ((Temp_Decimal % 100) / 10) + 0x30; TempCelsius_Display[12] = ((Temp_Decimal % 100) % 10) + 0x30; TempCelsius_Value >>= 3; TempCelsius_Display[6] = (TempCelsius_Value / 100) + 0x30; TempCelsius_Display[7] = ((TempCelsius_Value % 100) / 10) + 0x30; TempCelsius_Display[8] = ((TempCelsius_Value % 100) % 10) + 0x30; /* Convert temperature °C to Fahrenheit */ Temp_Value_Fahrenheit = ((9 * ((TempCelsius_Value * 1000) + Temp_Decimal)) / 5) + 32000; /* Calculate temperature digits in °F */ TempFahrenheit_Display[6] = (Temp_Value_Fahrenheit / 100000) + 0x30; TempFahrenheit_Display[7] = ((Temp_Value_Fahrenheit % 100000) /10000) + 0x30; TempFahrenheit_Display[8] = ((Temp_Value_Fahrenheit % 100000) %10000/1000) + 0x30; TempFahrenheit_Display[10] = ((((Temp_Value_Fahrenheit % 100000) %10000) %1000) /100) + 0x30; TempFahrenheit_Display[11] = (((((Temp_Value_Fahrenheit % 100000) %10000) %1000) %100) /10) + 0x30; TempFahrenheit_Display[12] = (((((Temp_Value_Fahrenheit % 100000) %10000) %1000) %100) %10) + 0x30; /* Display Fahrenheit value on LCD */ for(i = 0; i < 20; i++) { LCD_DisplayChar(Line7, (319 - (16 * i)), TempCelsius_Display[i]); LCD_DisplayChar(Line8, (319 - (16 * i)), TempFahrenheit_Display[i]); } } }
/******************************************************************************* * Function Name : LCD_WindowModeDisable * Description : Disables LCD Window mode. * Input : None * Output : None * Return : None *******************************************************************************/ void LCD_WindowModeDisable(void) { LCD_SetDisplayWindow(0, 0, 239, 319); }
/******************************************************************************* * Function Name : Alarm_Show * Description : Shows alarm time (HH/MM/SS) on LCD. * Input : None * Output : None * Return : None *******************************************************************************/ void Alarm_Show(void) { uint32_t tmp = 0; /* Disable the JoyStick interrupts */ IntExtOnOffConfig(DISABLE); while(ReadKey() != NOKEY) { } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Clear the LCD screen */ LCD_Clear(White); LCD_SetDisplayWindow(160, 223, 128, 128); LCD_NORDisplay(ALARM_ICON); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Disable LCD Window mode */ LCD_WindowModeDisable(); /* Set the LCD Back Color */ LCD_SetBackColor(Blue); /* Set the LCD Text Color */ LCD_SetTextColor(White); if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { LCD_DisplayStringLine(Line8, "Time not configured "); LCD_DisplayStringLine(Line9, " Press SEL "); while(ReadKey() == NOKEY) { } /* Clear the LCD */ LCD_Clear(White); /* Display the menu */ DisplayMenu(); /* Enable the JoyStick interrupts */ IntExtOnOffConfig(ENABLE); return; } /* Read the alarm value stored in the Backup register */ tmp = BKP_ReadBackupRegister(BKP_DR6); tmp |= BKP_ReadBackupRegister(BKP_DR7) << 16; LCD_ClearLine(Line8); /* Display alarm separators ":" on Line2 */ LCD_DisplayChar(Line8, 212, ':'); LCD_DisplayChar(Line8, 166, ':'); /* Display actual alarm value */ Alarm_Display(tmp); /* Wait a press on pushbuttons */ while(ReadKey() != NOKEY) { } /* Wait a press on pushbuttons */ while(ReadKey() == NOKEY) { } /* Clear the LCD */ LCD_Clear(White); /* Display the menu */ DisplayMenu(); /* Enable the JoyStick interrupts */ IntExtOnOffConfig(ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. */ /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); /* Initialize LEDs mounted on EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); STM_EVAL_LEDOn(LED1); /* Initialize the LCD */ LCD_Init(); LCD_Clear(Black); LCD_SetTextColor(White); LCD_LOG_SetHeader((uint8_t*)"STM32 Camera Demo"); LCD_LOG_SetFooter ((uint8_t*)" Copyright (c) STMicroelectronics" ); /* ADC configuration */ ADC_Config(); /* Initializes the DCMI interface (I2C and GPIO) used to configure the camera */ OV2640_HW_Init(); /* Read the OV9655/OV2640 Manufacturer identifier */ OV9655_ReadID(&OV9655_Camera_ID); OV2640_ReadID(&OV2640_Camera_ID); if(OV9655_Camera_ID.PID == 0x96) { Camera = OV9655_CAMERA; sprintf((char*)abuffer, "OV9655 Camera ID 0x%x", OV9655_Camera_ID.PID); ValueMax = 2; } else if(OV2640_Camera_ID.PIDH == 0x26) { Camera = OV2640_CAMERA; sprintf((char*)abuffer, "OV2640 Camera ID 0x%x", OV2640_Camera_ID.PIDH); ValueMax = 2; } else { LCD_SetTextColor(LCD_COLOR_RED); LCD_DisplayStringLine(LINE(4), (uint8_t*)"Check the Camera HW and try again"); while(1); } LCD_SetTextColor(LCD_COLOR_YELLOW); LCD_DisplayStringLine(LINE(4), (uint8_t*)abuffer); LCD_SetTextColor(LCD_COLOR_WHITE); Delay(200); /* Initialize demo */ ImageFormat = (ImageFormat_TypeDef)Demo_Init(); /* Configure the Camera module mounted on STM324xG-EVAL/STM324x7I-EVAL boards */ Demo_LCD_Clear(); LCD_DisplayStringLine(LINE(4), (uint8_t*)"Camera Init.. "); Camera_Config(); sprintf((char*)abuffer, " Image selected: %s", ImageForematArray[ImageFormat]); LCD_DisplayStringLine(LINE(4),(uint8_t*)abuffer); /* Enable DMA2 stream 1 and DCMI interface then start image capture */ DMA_Cmd(DMA2_Stream1, ENABLE); DCMI_Cmd(ENABLE); /* Insert 100ms delay: wait 100ms */ Delay(200); DCMI_CaptureCmd(ENABLE); LCD_ClearLine(LINE(4)); Demo_LCD_Clear(); if(ImageFormat == BMP_QQVGA) { /* LCD Display window */ LCD_SetDisplayWindow(179, 239, 120, 160); LCD_WriteReg(LCD_REG_3, 0x1038); LCD_WriteRAM_Prepare(); } else if(ImageFormat == BMP_QVGA) { /* LCD Display window */ LCD_SetDisplayWindow(239, 319, 240, 320); LCD_WriteReg(LCD_REG_3, 0x1038); LCD_WriteRAM_Prepare(); } while(1) { /* Blink LD1, LED2 and LED4 */ STM_EVAL_LEDToggle(LED1); STM_EVAL_LEDToggle(LED2); STM_EVAL_LEDToggle(LED3); STM_EVAL_LEDToggle(LED4); /* Insert 100ms delay */ Delay(10); /* Get the last ADC3 conversion result data */ uhADCVal = ADC_GetConversionValue(ADC3); /* Change the Brightness of camera using "Brightness Adjustment" register: For OV9655 camera Brightness can be positively (0x01 ~ 0x7F) and negatively (0x80 ~ 0xFF) adjusted For OV2640 camera Brightness can be positively (0x20 ~ 0x40) and negatively (0 ~ 0x20) adjusted */ if(Camera == OV9655_CAMERA) { OV9655_BrightnessConfig(uhADCVal); } if(Camera == OV2640_CAMERA) { OV2640_BrightnessConfig(uhADCVal/2); } } }
/******************************************************************************* * Function Name : Time_PreAdjust * Description : Returns the time entered by user, using demoboard keys. * Input : None * Output : None * Return : None *******************************************************************************/ static void Time_PreAdjust(void) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Clear the LCD screen */ LCD_Clear(White); LCD_SetDisplayWindow(160, 223, 128, 128); LCD_NORDisplay(WATCH_ICON); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); /* Disable LCD Window mode */ LCD_WindowModeDisable(); if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE); LCD_DisplayStringLine(Line7, "RTC Config PLZ Wait."); /* RTC Configuration */ RTC_Configuration(); LCD_DisplayStringLine(Line7, " TIME "); /* Clear Line8 */ LCD_ClearLine(Line8); /* Display time separators ":" on Line4 */ LCD_DisplayChar(Line8, 212, ':'); LCD_DisplayChar(Line8, 166, ':'); /* Display the current time */ Time_Display(RTC_GetCounter()); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Change the current time */ RTC_SetCounter(Time_Regulate()); BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); /* Clear Line7 */ LCD_ClearLine(Line7); /* Clear Line8 */ LCD_ClearLine(Line8); /* Adjust Date */ Date_PreAdjust(); } else { /* Clear Line8 */ LCD_ClearLine(Line8); /* Display time separators ":" on Line4 */ LCD_DisplayChar(Line8, 212, ':'); LCD_DisplayChar(Line8, 166, ':'); /* Display the current time */ Time_Display(RTC_GetCounter()); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Change the current time */ RTC_SetCounter(Time_Regulate()); } }
/******************************************************************************* * Function Name : LCD_WindowModeDisable * Description : Disables LCD Window mode. * Input : None * Output : None * Return : None *******************************************************************************/ void LCD_WindowModeDisable(void) { LCD_SetDisplayWindow(239, 0x13F, 240, 320); LCD_WriteReg(R3, 0x1018); }
static void displayFFT(int x, int y) { for (int16_t j = 0; j < 256; j++) { if (FFT_Filter[j] > 64.0) { FFT_Display[j] = 64; } else { FFT_Display[j] = (uint8_t)FFT_Filter[j]; } } /* * Display the FFT * - Drop the bottom 8, and top 8 frequency-display bins to discard * noisy sections near band edges due to filtering. */ float selectedFreqX = (float) (NCO_Frequency - 125) / 15.625; if (selectedFreqX < 0) { selectedFreqX = 0; } NCO_Bin = (int)selectedFreqX + 8; _Bool isShowingAFOffset = showAFOffsetOnScreen(); if (!WF_Flag) { // Draw the FFT using direct memory writes (fast). LCD_SetDisplayWindow(x, y, FFT_HEIGHT, FFT_WIDTH); LCD_WriteRAM_PrepareDir(LCD_WriteRAMDir_Down); for (int x = 0; x < FFT_WIDTH; x++) { // Plot this column of the FFT. for (int y = 0; y < FFT_HEIGHT; y++) { // Draw red line for selected frequency if ((x == (int) (selectedFreqX + 0.5)) && isShowingAFOffset) { // Leave some white at the top if (y <= SELFREQ_ADJ) { LCD_WriteRAM(LCD_COLOR_WHITE); } else { LCD_WriteRAM(LCD_COLOR_RED); } } // Draw data else if (FFT_HEIGHT - y < FFT_Display[x + 8]) { LCD_WriteRAM(LCD_COLOR_BLUE); } // Draw background else { LCD_WriteRAM(LCD_COLOR_WHITE); } } } } else { if (WF_Count == 0) { // Draw the Waterfall using direct memory writes (fast). LCD_SetDisplayWindow(x, y, FFT_HEIGHT, FFT_WIDTH); LCD_WriteRAM_PrepareDir(LCD_WriteRAMDir_Right); // Send colorized FFT data to Waterfall Buffer for (int x = 0; x < FFT_WIDTH; x++) { *(pWFBfr + (FFT_WIDTH*WF_Line0) + x) = WFPalette[(FFT_Display[x + 8] )]; } // Refresh the waterfall display--scrolling begins after 64 lines for (int y = WF_Line0; y < FFT_HEIGHT; y++) { for (int x = 0; x <FFT_WIDTH; x++) { if (x == (int)(selectedFreqX +0.5) && isShowingAFOffset) { //LCD_WriteRAM(LCD_COLOR_RED); LCD_WriteRAM(LCD_COLOR_WHITE); } else { LCD_WriteRAM(*(pWFBfr + y*FFT_WIDTH + x)); } } } for ( int y = 0; y < WF_Line0; y++) { for (int x = 0; x < FFT_WIDTH; x++) { if (x == (int)(selectedFreqX +0.5) && isShowingAFOffset) { //LCD_WriteRAM(LCD_COLOR_RED); LCD_WriteRAM(LCD_COLOR_WHITE); } else { LCD_WriteRAM(*(pWFBfr + y*FFT_WIDTH + x)); } } } } if (++WF_Count == MAX_WF_COUNT) { WF_Count = 0; WF_Line0--; if (WF_Line0 < 0) WF_Line0 = FFT_HEIGHT-1; } } }