【F769IDISCOVERY评测】评测七 频谱仪
F769I DISCOVERY(STM32官网) 配置了一片800×472 WVGA TFT DSI LCD,非常适合用来进行图形显示的编程练习。在本贴中以DMA方式读取ADC通道12的正弦波,运行1024个点的浮点运算FFT后,将结果以图形方式在LCD上显示。信号连接原理图
ST官方发布的STM32Cube_FW_F7_V1.50固件库中对WVGA TFT DSI LCD的底层操作都编写得很完整,用户只要简单调用几条命令就可以完成包括层参数设定等初始化操作。因此在本评测中将FFT转换结果用图形方式显示变得很简单。
贴出有关WVGA TFT DSI LCD操作的关键代码。有关FFT代码及编译环境设置请参考https://www.stmcu.org.cn/module/forum/thread-609489-1-1.html。
<div>#include "main.h"
ADC_HandleTypeDef AdcHandle;
__IO int16_t ConvertedValue;
extern float outputbuf[];
void SystemClock_Config(void);
static void LCD_Config(void);
static void ADC_Config(void);
static void Error_Handler(void);
static void MPU_Config(void);
static void CPU_CACHE_Enable(void);
int main(void)
{uint16_t i,j,temp;
MPU_Config();
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED1);
BSP_LED_Init(LED2);
LCD_Config();
ADC_Config();
HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&ConvertedValue, 1024);
while (1)
{
FFT_read();
for(i=0,j=150;i<512;i++,j++)
{
temp=outputbuf/200;
if(temp>350)temp=350;
BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
BSP_LCD_DrawVLine(j,29, 350);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_DrawVLine(j,380-temp, temp+1);
}
BSP_LED_Toggle(LED2);
}
}
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 9;
RCC_OscInitStruct.PLL.PLLR = 7;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
while(1) { ; }
}
ret = HAL_PWREx_EnableOverDrive();
if(ret != HAL_OK)
{
while(1) { ; }
}
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
if(ret != HAL_OK)
{
while(1) { ; }
}
}
static void LCD_Config(void)
{
uint32_tlcd_status = LCD_OK;
lcd_status = BSP_LCD_Init();
while(lcd_status != LCD_OK);
BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
BSP_LCD_Clear(LCD_COLOR_DARKBLUE);
BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
BSP_LCD_FillRect(0, 420, BSP_LCD_GetXSize(), 59);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_SetBackColor(LCD_COLOR_BLUE);
BSP_LCD_SetFont(&Font24);
BSP_LCD_DisplayStringAt(0, 430, (uint8_t *)"STM32F769NIH Discovery FFT Demo", CENTER_MODE);
BSP_LCD_SetFont(&Font12);
BSP_LCD_DisplayStringAt(0, 460, (uint8_t *)"Copyright (c) STMicroelectronics 2016", CENTER_MODE);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_SetBackColor(LCD_COLOR_DARKBLUE);
BSP_LCD_SetFont(&Font24);
}
static void ADC_Config(void)
{
ADC_ChannelConfTypeDef sConfig;
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
AdcHandle.Instance = ADC1;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.ScanConvMode = DISABLE;
AdcHandle.Init.ContinuousConvMode = ENABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.NbrOfDiscConversion = 1;
AdcHandle.Init.ExternalTrigConvEdge= ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;//DISABLE;
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel =ADC_CHANNEL_12;// ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void Error_Handler(void)
{
while (1)
{
BSP_LED_Toggle(LED1);
HAL_Delay(20);
}
}
#ifdefUSE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
while (1)
{
}
}
#endif
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
HAL_MPU_Disable();
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20010000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
static void CPU_CACHE_Enable(void)
{
SCB_EnableICache();
SCB_EnableDCache();
}</div><div>
</div>
HEX文件:
http://player.youku.com/player.php/sid/XMTg0OTI3MjAyOA==/v.swf
视频。
好强大啊 要用到傅立叶吗? 五哥1 发表于 2016-12-5 18:29
要用到傅立叶吗?
是用到傅里叶函数 谢谢分享! 点赞
谢谢分享 谢谢分享 :handshake 谢谢谢谢! damiaa 发表于 2016-12-29 15:17
谢谢谢谢!
:)。。。。
页:
[1]