[STM32F4]

【F446RE开发板试用】硬件IIC驱动ADXL345,并使用LCD绘制三个轴...

[复制链接]
3457|3
手机看帖
扫描二维码
随时随地手机跟帖
wgsxsm|  楼主 | 2015-10-20 17:47 | 显示全部楼层 |阅读模式
本帖最后由 wgsxsm 于 2015-10-20 17:51 编辑
接上篇:https://bbs.21ic.com/icview-1130438-1-1.html
驱动成功LCD之后,使用LCD来画个什么参数呢?
刚好手头有个自己DIY的NUCLEO+ADXL345模块板
之前是采集三个轴上的值发送到串口,通过串口来绘制的图像,下图为串口接收后数据的绘制的曲线 QQ截图20151020173850.jpg
而现在想把采集的值直接显示到LCD上来
~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~
ADXL345的通讯选择的是IIC模式,虽然都说STM32的硬件IIC有问题,用起来可能会有问题,但是还是想试一下。
结合stm32cubef4压缩包里提供的例子I2C_TwoBoards_ComPolling:STM32Cube_FW_F4_V1.8.0\Projects\STM32446E-Nucleo\Examples\I2C\I2C_TwoBoards_ComPolling
由于该例程使用的硬件IIC的PIN分别是SCL-PB6和SDA-PB9,而我想采用的是PB8和PB9,
为了保险起见,还是使用了STM32CubeMX生成的工程,将生成的代码重新来配置工程中的IIC
QQ截图20151020170015.jpg
QQ截图20151020170926.jpg
硬件部分的图纸如下(BOTTOM层隐藏了一些其他模块的元器件):
QQ截图20151020171255.jpg
QQ截图20151020171646.jpg
模块实物图如下:
1445334345111.jpg

软件部分主要是采用的中值滤波,为了能完全显示到320*240分辨率的LCD上,采集之后的数据比较大,进行了幅值缩小;
然后采用以画线的形式,将采集到的值画在了LCD屏幕上。其中,红色曲线为X轴,绿色曲线为Y轴,蓝色曲线为Z轴
int16_t GetMedianNum(int16_t * bArray, int16_t iFilterLen)
{
    uint16_t i,j;// Ñ­»·±äÁ¿
    int32_t bTemp;

    // ÓÃðÅÝ·¨¶ÔÊý×é½øÐÐÅÅÐò
    for (j = 0; j < iFilterLen - 1; j ++)
    {
        for (i = 0; i < iFilterLen - j - 1; i ++)
        {
            if (bArray[i] > bArray[i + 1])
            {
                // »¥»»
                bTemp = bArray[i];
                bArray[i] = bArray[i + 1];
                bArray[i + 1] = bTemp;
            }
        }
    }

    // ¼ÆËãÖÐÖµ
    if ((iFilterLen & 1) > 0)
    {
        // Êý×éÓÐÆæÊý¸öÔªËØ£¬·µ»ØÖмäÒ»¸öÔªËØ
        bTemp = bArray[(iFilterLen + 1) / 2];
    }
    else
    {
        // Êý×éÓÐżÊý¸öÔªËØ£¬·µ»ØÖмäÁ½¸öÔªËØƽ¾ùÖµ
        bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
    }

    return (int16_t)bTemp;
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
        
    uint16_t i=0,j=0;
    int16_t readingX[20],readingY[20],readingZ[20];
    int16_t o_X0=0,o_Y0=0,o_Z0=0;
                int16_t o_X1,o_Y1,o_Z1;
        
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */
  HAL_Init();
  
  /* Configure the system clock to 180 MHz */
  SystemClock_Config();
   
  /* Configure LED2 */
  BSP_LED_Init(LED2);        
        
        MX_I2C1_Init();

  /* Output SYSCLK  on MCO2 pin(PC.09) */
  HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1);
        
        LCD_Init();
        GetFontsWidth();        //fonts width get
        
        if(ADXL_getDevId() == 0xE5)        LCD_WriteString(0,0,(uint8_t *)"ADXL345 is OK!",&Font32x32,BLACK,WHITE,USEBACKCOLOR);
        else                                                                                                return        1;
        
        //Go into standby mode to configure the device.
        ADXL_setPowerControl(0x00);

        //Full resolution, +/-16g, 4mg/LSB.
        ADXL_setDataFormatControl(0x0B);

        //3.2kHz data rate.
        ADXL_setDataRate(ADXL345_3200HZ);

        //Measurement mode.
        ADXL_setPowerControl(0x08);        

  /*##-3- Toggle PA05 IO in an infinite loop #################################*/  
  while (1)
  {
                readingX[j]=ADXL_getAx()/3;                //ËõСÕñ·ù
                readingY[j]=ADXL_getAy()/3;                //ËõСÕñ·ù
                readingZ[j]=ADXL_getAz()/3;                //ËõСÕñ·ù

                j++;
                if(j==20)   j=0;
               
                LCD_DrawLine(i+2,40,i+2,239,WHITE);
                LCD_DrawLine(i+3,40,i+3,239,WHITE);
               
                o_X1=GetMedianNum(readingX,20);
                LCD_DrawLine(i,o_X0+139,i+1,o_X1+139,RED);
                o_X0=o_X1;
               
                o_Y1=GetMedianNum(readingY,20);
                LCD_DrawLine(i,o_Y0+139,i+1,o_Y1+139,GREEN);
                o_Y0=o_Y1;
               
                o_Z1=GetMedianNum(readingZ,20);
                LCD_DrawLine(i,o_Z0+139,i+1,o_Z1+139,BLUE);
                o_Z0=o_Z1;
               
                i++;
                if(i==320)        
                {
                        i=0;               
                        LCD_DrawLine(0,40,0,239,WHITE);
                        LCD_DrawLine(1,40,1,239,WHITE);
                }

                BSP_LED_Toggle(LED2);
                HAL_Delay(50);

  }
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 180000000
  *            HCLK(Hz)                       = 180000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 8000000
  *            PLL_M                          = 8
  *            PLL_N                          = 360
  *            PLL_P                          = 2
  *            PLL_Q                          = 7
  *            PLL_R                          = 2
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 5
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef ret = HAL_OK;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* The voltage scaling allows optimizing the power consumption when the device is
     clocked below the maximum system frequency, to update the voltage scaling value
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /* Enable HSE Oscillator and activate PLL with HSE as source */
  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 = 8;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  RCC_OscInitStruct.PLL.PLLR = 2;
  
  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  
  /* Activate the OverDrive to reach the 180 MHz Frequency */  
  ret = HAL_PWREx_EnableOverDrive();
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
  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_5);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
}
采集的视频如下,由于LCD的坐标原点为左上角,所以显示的时候可能会有倒置的现象。

~~~~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~
代码包如下:
压缩包解压到你的这个目录下面:
XX\XX\NUCLEO-STM32F446\STM32Cube_FW_F4_V1.8.0\Projects\STM32446E-Nucleo\Examples
GPIO-20151020.zip (279.24 KB)
xizoukou| | 2016-12-26 10:34 | 显示全部楼层
工程不能编译啊,

使用特权

评论回复
冰河w| | 2016-12-27 21:26 | 显示全部楼层
楼主用的什么编译软件,能不能分享一下

使用特权

评论回复
wahahaheihei| | 2016-12-27 23:35 | 显示全部楼层
驱动程序还可以,弄到我的工程里试试

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

652

帖子

4

粉丝