找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6670|回复: 5
收起左侧

STM32+LabVIEW的USB数据采集与显示源程序

  [复制链接]
ID:585986 发表于 2019-7-18 11:30 | 显示全部楼层 |阅读模式
基于STM32和LabVIEW的USB数据采集与显示
(Based STM32 USB data acquisition and LabVIEW display)
0.png
1、打开电脑的“控制面板” -->“字体”,把“数码管字体”文件夹中的两个文件,复制到“字体”中

2、重新打开labview,就可以在您的字体设置栏找到NI7SEG字体了

3、本labview采集程序采用了自动识别单片机串口技术,用户不必手动选择串口

4、旋动开发板上的可调电阻,可以看到ADC值在变化

5、本实验的采样率是:10/秒,即labview可以在100ms之内处理完一个数据。如果用户的采样率加大,请采用labview生产者/消费者结构

单片机源程序如下:
  1. /*****************************************************************
  2. *
  3. * 文件名: main.c
  4. * 内容简述: 本程序演示了可调电阻(PC0)的ADC(非DMA)以及过采样技术的使用
  5. *
  6. *
  7. ******************************************************************/

  8. /* Includes ------------------------------------------------------------------*/
  9. #include "stm32f10x.h"
  10. #include "usb_lib.h"
  11. #include "usb_desc.h"
  12. #include "hw_config.h"
  13. #include "usb_pwr.h"
  14. #include "stm32f10x_tim.h"
  15. #include "platform_config.h"

  16. u8 comm = 0;
  17. u8 ah,al;
  18. u16 ad;
  19. u32 tempu32 = 0;

  20. u8 gototime = 0;

  21. /*************************************************
  22. 函数: void RCC_Configuration(void)
  23. 功能: 复位和时钟控制 配置
  24. 参数: 无
  25. 返回: 无
  26. **************************************************/
  27. void RCC_Configuration(void)
  28. {
  29.   ErrorStatus HSEStartUpStatus;                    //定义外部高速晶体启动状态枚举变量
  30.   GPIO_InitTypeDef GPIO_InitStructure;

  31.   RCC_DeInit();                                    //复位RCC外部设备寄存器到默认值
  32.   RCC_HSEConfig(RCC_HSE_ON);                       //打开外部高速晶振
  33.   HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速时钟准备好
  34.   if(HSEStartUpStatus == SUCCESS)                  //外部高速时钟已经准别好
  35.   {
  36.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
  37.     FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延时
  38.              
  39.     RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)时钟等于==SYSCLK
  40.     RCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)钟==AHB时钟
  41.     RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)钟==AHB1/2时钟
  42.          
  43.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
  44.     RCC_PLLCmd(ENABLE);                                   //使能PLL时钟
  45.    
  46.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)    //等待PLL时钟就绪
  47.     {
  48.     }
  49.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系统时钟 = PLL时钟
  50.     while(RCC_GetSYSCLKSource() != 0x08)                  //检查PLL时钟是否作为系统时钟
  51.     {
  52.     }
  53.   }
  54.   
  55.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    //允许AFIO时钟

  56.   /* Enable USB_DISCONNECT GPIO clock */
  57.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE);

  58.   /* Configure USB pull-up pin */
  59.   GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN;
  60.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  61.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  62.   GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure);
  63. }

  64. /*******************************************************************************
  65.         函数名:ADC_Configuration
  66.         输  入:
  67.         输  出:
  68.         功能说明:配置ADC, PC0
  69. */
  70. static void ADC_Configuration(void)
  71. {
  72.         GPIO_InitTypeDef GPIO_InitStructure;
  73.         ADC_InitTypeDef ADC_InitStructure;
  74.         volatile u16 ADCConvertedValue;

  75.     /* 使能 ADC1 and GPIOC clock */
  76.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
  77.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);              //72M/6=12,ADC最大时间不能超过14M

  78.         /* 配置PC0为模拟输入(ADC Channel10) */
  79.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  80.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  81.         GPIO_Init(GPIOC, &GPIO_InitStructure);

  82.         /* 配置ADC1, 不用DMA, 用软件自己触发 */
  83.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                 //ADC1工作模式:独立模式
  84.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;                         //单通道模式
  85.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                 //单次转换
  86.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;          //转换由软件而不是外部触发启动
  87.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;         //ADC1数据右对齐
  88.         ADC_InitStructure.ADC_NbrOfChannel = 1;           //顺序进行规则转换的ADC通道的数目
  89.         ADC_Init(ADC1, &ADC_InitStructure);                   //根据ADC_InitStruct中指定的参数,初始化外设ADC1的寄存器

  90.         /* ADC1 regular channel10 configuration */
  91.         ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5);        //ADC1,ADC通道10,规则采样顺序值为1,采样时间为239.5周期

  92.         /* Enable ADC1 */
  93.         ADC_Cmd(ADC1, ENABLE);                  //使能ADC1

  94.         /* Enable ADC1 reset calibaration register */
  95.         ADC_ResetCalibration(ADC1);                                                //重置ADC1的校准寄存器
  96.         /* Check the end of ADC1 reset calibration register */
  97.         while(ADC_GetResetCalibrationStatus(ADC1));                //获取ADC1重置校准寄存器的状态,设置状态则等待

  98.         /* Start ADC1 calibaration */
  99.         ADC_StartCalibration(ADC1);                                        //开始ADC1的校准状态
  100.         /* Check the end of ADC1 calibration */
  101.         while(ADC_GetCalibrationStatus(ADC1));                //等待校准完成

  102.         /* Start ADC1 Software Conversion */
  103.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能ADC1的软件转换启动功能
  104. }

  105. /*************************************************
  106. 函数: void Timer2_Configuration(void)
  107. 功能: TIM2 配置
  108. 参数: 无
  109. 返回: 无
  110. 定时计算:(1 /(72 / (36 - 1 + 1))) * 781 us = 390.5us
  111. **************************************************/
  112. void Timer2_Configuration(void)
  113. {
  114.   TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
  115.    
  116.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);            //打开TIM2定时器的时钟
  117.   
  118.   
  119.   TIM_DeInit(TIM2);                                                    //TIMx寄存器重设为缺省值
  120.   
  121.   TIM_TimeBaseStructure.TIM_Period = 781;                            //自动重装载寄存器周期的值
  122.   TIM_TimeBaseStructure.TIM_Prescaler=36 - 1;               //TIMx 时钟频率除数的预分频值
  123.   TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;     //采样分频
  124.   TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
  125.   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  126.   
  127.   TIM_ARRPreloadConfig(TIM2, ENABLE);                       //允许自动重装载寄存器(ARR)
  128.   TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);                        //允许TIM2溢出中断
  129.   
  130.   TIM_Cmd(TIM2, ENABLE);                                        //开启时钟
  131. }

  132. /*******************************************************************************
  133. * Function Name   : NVIC_Configuration
  134. * Description        : Configures NVIC and Vector Table base location.
  135. * Input                    : None
  136. * Output                 : None
  137. * Return                 : None
  138. *******************************************************************************/
  139. void NVIC_Configuration(void)
  140. {
  141.    NVIC_InitTypeDef NVIC_InitStructure;
  142.   
  143.    /* Set the Vector Table base location at 0x08000000 */
  144.    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  145.   
  146.    /* Configure the NVIC Preemption Priority Bits */  
  147.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);                                 //中断分组设置

  148.   //配置TIM2中断
  149.   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  150.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                 //指定抢占式优先级别0
  151.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                         //指定响应优先级别0
  152.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                 //使能TIM2中断
  153.   NVIC_Init(&NVIC_InitStructure);
  154. }

  155. /*************************************************
  156. 函数: void TIM2_IRQHandler(void)
  157. 功能: TIM2中断处理函数
  158. 参数: 无
  159. 返回: 无
  160. 说明:390.5us中断1次
  161. **************************************************/
  162. void TIM2_IRQHandler(void)
  163. {
  164.    if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
  165.    {      
  166.       TIM_ClearITPendingBit(TIM2,TIM_IT_Update);         //清除中断标志
  167.       gototime = 1;
  168.    }
  169. }

  170. /*******************************************************************************
  171. * Function Name  : main.
  172. * Description    : Main routine.
  173. * Input          : None.
  174. * Output         : None.
  175. * Return         : None.
  176. *******************************************************************************/
  177. int main(void)
  178. {
  179.   u16 i;

  180.   RCC_Configuration();
  181.   ADC_Configuration();
  182.   NVIC_Configuration();
  183.   Timer2_Configuration();

  184.   Set_USBClock();
  185.   USB_Interrupts_Config();
  186.   USB_Init();

  187.   while (1)
  188.   {
  189.     if (bDeviceState == CONFIGURED)  
  190.     {
  191.           if (comm == 0x63)                    //上位机自动查找采集器是否在线
  192.           {                         
  193.             comm = 0;      
  194.         USART_To_USB_Send_Data(0x63);      //发送CP的ASCII码
  195.         USART_To_USB_Send_Data(0x70);                                                                 
  196.           }
  197.       if (comm == 0x7a)                             //单片机发送数据给PC机
  198.           {      
  199.         for(i = 0;i < 256;i++)                      //根据过采样技术,每提高一位AD分辨率,需要增加4倍的采样率;从12位AD分辨率增加到16位AD分辨率,即增加4位,所以需要增加256倍的采样率
  200.         {
  201.           gototime = 0;
  202.           TIM_Cmd(TIM2, ENABLE);                                //开启时钟
  203.               ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //软件启动ADC转换
  204.               while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));   //等待转换结束
  205.               ad = 0;
  206.                   ad = ADC_GetConversionValue(ADC1);                        //读取ADC值                     
  207.           tempu32 += ad;                                          //累加        
  208.           while(gototime == 0);                                                    //延时:390.5us。采样率:10/秒
  209.           TIM_Cmd(TIM2, DISABLE);                                //关闭时钟
  210.         }

  211.           //以下数据处理和发送会占用一定的时间,如果我们不采用过采样技术,可以把以下代码放在TIM2定时之内处理                            
  212.         ad = tempu32 >> 4;                 //16位分辨率,累加值右移4位
  213.         ah = ad >> 8;                                           //高8位
  214.         al = ad & 0xff;                              //低8位
  215.         USART_To_USB_Send_Data(ah);                                          
  216.         USART_To_USB_Send_Data(al);
  217.                             
  218.         tempu32 = 0;   
  219.       }
  220.     }                      
  221.   }
  222. }
复制代码
0.png
所有资料51hei提供下载:
69491704Based-STM32-USB-data-acquisition.rar (1.7 MB, 下载次数: 198)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:358642 发表于 2021-7-7 08:37 | 显示全部楼层
谢谢分享,下载下来好好学习
回复

使用道具 举报

ID:77126 发表于 2021-4-24 09:07 | 显示全部楼层
谢谢分享,下来好好学习学习
回复

使用道具 举报

ID:523997 发表于 2021-4-4 12:40 | 显示全部楼层
谢谢楼主分享,感觉很有用
回复

使用道具 举报

ID:544005 发表于 2020-1-20 09:10 | 显示全部楼层
谢谢分享!!
回复

使用道具 举报

ID:373684 发表于 2019-7-23 00:32 | 显示全部楼层
是不是要编Labview和单片机的程序啊?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表