找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9594|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

STM32磁懸浮

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主

上學(xué)期做的課程設(shè)計(jì)的一部分,


  以前做過基于模電的磁懸浮,誤差很大,調(diào)節(jié)不方便,需要多各元件進(jìn)行,三極管發(fā)熱的情況也不容樂觀。所以在學(xué)習(xí)stm32的adc功能之后,想使用stm32單片機(jī)取代電位比較器。
  stm32的adc功能比較強(qiáng)大,根據(jù)讀的st官方技術(shù)手冊,使用多通道后,adc的采樣速度甚至能達(dá)到us級,能滿足很多設(shè)計(jì)要求很高的場景,足夠磁懸浮使用。


1. 了解掌握stm32的綜合運(yùn)用方法
2. 加強(qiáng)了解 l298模塊的使用
3. 加強(qiáng)了解霍爾傳感器的使用
4. 加強(qiáng)了解 adc的使用


二、主要儀器設(shè)備、試劑或材料


1. PC,stm32
2. 霍爾傳感器
3. L298n
4. 杜邦線 電線若干
      




三、實(shí)驗(yàn)方法與步驟
代碼(部分)
  1. /* Includes------------------------------------------------------------------*/
  2. //# include <stdio. h>
  3. //# include <stdlib. h>
  4. #include "stm32f10x.h"
  5. #include"lcd1602.h"
  6. //#include "misc.h"
  7. //#include "misc.c"
  8. #include<stm32f10x_adc.h>
  9. //#include<stm32f10x_flash.h>
  10. /********************************宏定義------------------------------------*/
  11. #define ADC1_DR_Address    ((u32)0x4001244C)
  12. #define ADC3_DR_Address    ((u32)0x40013C4C)
  13. /********************************變量定義------------------------------------*/
  14. ADC_InitTypeDefADC_InitStructure;
  15. DMA_InitTypeDefDMA_InitStructure;
  16. GPIO_InitTypeDefGPIO_InitStructure; //定義GPIO初始化結(jié)構(gòu)體
  17. vu16 ADC1ConvertedValue = 0,ADC3ConvertedValue = 0;
  18. ErrorStatus HSEStartUpStatus;
  19. int AD_value;
  20. float CountV;
  21. float Std = (3.3)/4096;
  22. int CountV1;
  23. int CountV2;
  24. int CountV3;
  25. int hall;
  26. unsigned int jj = 0;
  27. //此表為 LED 的字模, 共陰數(shù)碼管 0-9  -
  28. unsigned int Disp_Tab[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};  //段碼控制
  29. //此表為8個數(shù)碼管位選控制, 共陰數(shù)碼管 1-8個 -
  30. unsigned intdispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F};    //位選控制   查表的方法控制
  31. unsigned int LedOut[10];        //變量定義
  32.    
  33. /*********************************聲明函數(shù) -----------------------------------------------*/
  34. void RCC_Configuration(void);
  35. voidGPIO_Configuration(void);
  36. voidNVIC_Configuration(void);
  37. void delay_nms(u16 time);
  38. void Delay(vu32 nCount);
  39. /*******************************************************************************
  40. *
  41. *            主函數(shù)
  42. *
  43. *******************************************************************************/
  44. int main(void)
  45. { unsigned int  LedNumVal = 0 ,LedNumVal1 = 0;     //變量定義
  46. #ifdef DEBUG
  47.   debug();
  48. #endif
  49.                                                                                                                  
  50.   //RCC配置
  51.   RCC_Configuration();
  52.   // NVIC配置
  53.   NVIC_Configuration();
  54.   //GPIO配置
  55.   GPIO_Configuration();
  56.   //DMA1 通道配置
  57.   DMA_DeInit(DMA1_Channel1); //設(shè)置成CH1 DMA中包含了7個通道(CH1-CH7)
  58.   DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address; //給DMA起始地址
  59.   DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC1ConvertedValue;//DMA連接在內(nèi)存中的變量地址
  60.   DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralSRC; //設(shè)置DMA傳輸方向單向傳輸
  61.   DMA_InitStructure.DMA_BufferSize = 1; //設(shè)置DMA在傳輸時緩沖區(qū)的長度
  62.   DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable; //設(shè)置DMA的外設(shè)遞增模式
  63.   DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Disable;//設(shè)置DMA的內(nèi)存遞增模式
  64.   DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;//DMA在訪問時每次操作的數(shù)據(jù)長度
  65.   DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;
  66.   DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;//DMA的傳輸模式,連續(xù)不斷的循環(huán)模式
  67.   DMA_InitStructure.DMA_Priority =DMA_Priority_High; //DMA的優(yōu)先級別:可以分為4級
  68.   DMA_InitStructure.DMA_M2M =DMA_M2M_Disable;//DMA的2個memory中的變量互相訪問的
  69.   DMA_Init(DMA1_Channel1, &DMA_InitStructure);//DMA整個模塊初始化
  70.   //開啟DMA通道1
  71.   DMA_Cmd(DMA1_Channel1, ENABLE);
  72.      
  73.   // ADC1 配置
  74.   ADC_InitStructure.ADC_Mode =ADC_Mode_FastInterl; //ADC1工作在獨(dú)立模式
  75.   ADC_InitStructure.ADC_ScanConvMode =ENABLE;//使能掃描
  76.   ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;;//ADC轉(zhuǎn)換工作在連續(xù)模式
  77.   ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;//由軟件控制轉(zhuǎn)換
  78.   ADC_InitStructure.ADC_DataAlign =ADC_DataAlign_Right;//轉(zhuǎn)換數(shù)據(jù)右對齊
  79.   ADC_InitStructure.ADC_NbrOfChannel = 14;//轉(zhuǎn)換通道為通道1
  80.   ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
  81.   //ADC1選擇信道14,音序器等級1,采樣時間239.5個周期
  82.   ADC_RegularChannelConfig(ADC1,ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);   
  83.   //使能ADC1模塊DMA
  84.   ADC_DMACmd(ADC1, ENABLE);
  85.     //打開ADC1
  86.   ADC_Cmd(ADC1, ENABLE);
  87. //重置ADC1校準(zhǔn)寄存器
  88.   ADC_ResetCalibration(ADC1);
  89. //等待ADC1校準(zhǔn)重置完成
  90. while(ADC_GetResetCalibrationStatus(ADC1));  
  91.   //開始ADC1校準(zhǔn)
  92.   ADC_StartCalibration(ADC1);
  93. //等待ADC1校準(zhǔn)完成
  94.   while(ADC_GetCalibrationStatus(ADC1));
  95. //使能ADC1軟件開始轉(zhuǎn)換
  96.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  97. //*****************************************************************************//
  98.     L1602_init();
  99.         L1602_Clear();
  100.        GPIO_SetBits(GPIOC,GPIO_Pin_2);
  101.             L1602_string(1,1,"    wj works   ");
  102.            L1602_string(2,1,"   ALL SET OK  ");
  103.            delay_nms(1000);
  104.   while (1)
  105.   {  unsignedint i ;
  106.       
  107. // L1602_Clear();
  108.            int num = 100;
  109.     int str[4];
  110.     //itoa(num, str, 10);
  111.             AD_value =ADC_GetConversionValue(ADC1);
  112.          CountV   = ADC_GetConversionValue(ADC1)*    Std;
  113.             CountV1  = CountV/1;
  114.       str[0] = CountV1 ;
  115.            
  116. //                      "WJWORKSVoltage "
  117. //L1602_string(1,1,"WJWORKS");
  118. //L1602_string(2,1,"Voltage is  ");
  119. //L1602_DispFloatNum(2,12,CountV);
  120.            // L1602_string(2,16,"V");
  121.            if(CountV>=1.1) GPIO_SetBits(GPIOE,GPIO_Pin_5);
  122.         elseGPIO_ResetBits(GPIOE,GPIO_Pin_5);
  123. //delay_nms(200);
  124.    }
  125. }
  126. void Delay(vu32 nCount)
  127. {
  128.   for(; nCount != 0; nCount--);
  129. }
  130. /*******************************************************************************
  131. *
  132. *            RCC配置
  133. *
  134. *******************************************************************************/
  135. void RCC_Configuration(void)
  136.                      
  137.       
  138. {
  139. //復(fù)位RCC外部設(shè)備寄存器到默認(rèn)值
  140.   RCC_DeInit();
  141.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOB的時鐘
  142.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOB的時鐘
  143.             RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的時鐘
  144.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOA的時鐘
  145.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//使能GPIOD的時鐘
  146.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打開USART的定時器
  147.                  
  148.                  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  149.   //打開外部高速晶振
  150.   RCC_HSEConfig(RCC_HSE_ON);
  151. //等待外部高速時鐘準(zhǔn)備好
  152.   HSEStartUpStatus = RCC_WaitForHSEStartUp();
  153.   //外部高速時鐘已經(jīng)準(zhǔn)別好
  154.   if(HSEStartUpStatus == SUCCESS)  
  155.   {
  156.    
  157.    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
  158.    
  159.     FLASH_SetLatency(FLASH_Latency_2);
  160.   
  161.    //配置AHB(HCLK)時鐘=SYSCLK
  162.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
  163.   
  164.     //配置APB2(PCLK2)鐘=AHB時鐘
  165.     RCC_PCLK2Config(RCC_HCLK_Div1);
  166.     //配置APB1(PCLK1)鐘=AHB 1/2時鐘
  167.     RCC_PCLK1Config(RCC_HCLK_Div2);  
  168.     //配置ADC時鐘=PCLK2 1/4
  169.     RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  170.   
  171.     //配置PLL時鐘 == 外部高速晶體時鐘*9
  172.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
  173.    
  174.       //配置ADC時鐘= PCLK2/4
  175.     RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  176.    //使能PLL時鐘
  177.     RCC_PLLCmd(ENABLE);  
  178.    //等待PLL時鐘就緒
  179.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) ==RESET)  
  180.     {
  181.     }
  182.     //配置系統(tǒng)時鐘 = PLL時鐘
  183.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  184.    //檢查PLL時鐘是否作為系統(tǒng)時鐘
  185.     while(RCC_GetSYSCLKSource() != 0x08)  
  186.     {
  187.     }
  188.   }
  189.   // 開啟DMA1時鐘 Enable
  190.    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 ,ENABLE);
  191.   //開啟ADC1時鐘
  192.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1   , ENABLE);
  193.                   
  194.     //下面是給各模塊開啟時鐘
  195.     //啟動GPIO
  196.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB ,ENABLE);
  197.     //啟動AFIO
  198.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  199.     //啟動DMA時鐘
  200.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  201.     //啟動ADC1時鐘
  202.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  203. }
  204. /*************************************************
  205. 函數(shù): voidGPIO_Config(void)
  206. 功能: GPIO配置
  207. **************************************************/
  208. void GPIO_Configuration(void)
  209. {
  210.    
  211.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//| RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO
  212.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
  213.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  214.     GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
  215.     GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz; //引腳頻率50M
  216.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  217.       
  218.        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  219.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  220.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
  221.            GPIO_Init(GPIOC,&GPIO_InitStructure);
  222.       
  223.       
  224.     //配置PA0為模擬輸入
  225.       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  226.       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  227.       GPIO_Init(GPIOA, &GPIO_InitStructure);
  228.       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  229.       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  230.       GPIO_Init(GPIOA, &GPIO_InitStructure);
  231.    
  232.            
  233.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//*************指示燈配置
  234.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  235.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  236.            GPIO_Init(GPIOE,&GPIO_InitStructure);
  237.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  238.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  239.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
  240.            GPIO_Init(GPIOE,&GPIO_InitStructure);
  241.            
  242.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  243.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  244.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_13|GPIO_Pin_14;
  245.            GPIO_Init(GPIOD,&GPIO_InitStructure);
  246.            
  247.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  248.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  249.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
  250.            GPIO_Init(GPIOB,&GPIO_InitStructure);
  251.                  
  252.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  253.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  254.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  255.            GPIO_Init(GPIOA,&GPIO_InitStructure);
  256.            
  257.                  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  258.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  259.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13;
  260.            GPIO_Init(GPIOE,&GPIO_InitStructure);
  261.            
  262.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置
  263.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  264.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
  265.            GPIO_Init(GPIOC,&GPIO_InitStructure);
  266.            
  267.            GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//-------------------------------------輸出配置d10
  268.            GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  269.            GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
  270.            GPIO_Init(GPIOD,&GPIO_InitStructure);
  271. }
  272. void delay_nms(u16 time)
  273.            {  
  274.                  u16 i=0;  
  275.                  while(time--)
  276.                       {
  277.                             i=12000;
  278.                             while(i--) ;}}
  279.                            
  280. /*******************************************************************************
  281. * Function Name  : NVIC_Configuration
  282. * Description    : Configures Vector Table base location.
  283. * Input          : None
  284. * Output         : None
  285. * Return         : None
  286. *******************************************************************************/
  287. void NVIC_Configuration(void)
  288. {
  289.   NVIC_InitTypeDef NVIC_InitStructure;
  290. #ifdef  VECT_TAB_RAM
  291.   /* Set the Vector Table base location at0x20000000 */
  292.   NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  293. #else  /* VECT_TAB_FLASH  */
  294.   /* Set the Vector Table base location at0x08000000 */
  295.   NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);   
  296. #endif
  297.   /* Configure and enable ADC interrupt */
  298.   NVIC_InitStructure.NVIC_IRQChannel =ADC1_2_IRQn;
  299. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  300.   NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
  301.   NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
  302.   NVIC_Init(&NVIC_InitStructure);
  303. }
  304. #ifdef  DEBUG
  305. /*******************************************************************************
  306. * Function Name  : assert_failed
  307. * Description    : Reports the name of the source file andthe source line number
  308. *                  where the assert_param errorhas occurred.
  309. * Input          : - file: pointer to the source filename
  310. *                  - line: assert_param errorline source number
  311. * Output         : None
  312. * Return         : None
  313. *******************************************************************************/
  314. void assert_failed(u8* file,u32 line)
  315. {
  316.   /* User can add his own implementation toreport the file name and line number,
  317.      ex: printf("Wrong parameters value:file %s on line %d\r\n", file, line) */
  318.   /* Infinite loop */
  319.   while (1)
  320.   {
  321.   }
  322. }
  323. #endif
復(fù)制代碼

四、實(shí)驗(yàn)總結(jié)
  彌補(bǔ)了之前使用電位比較器的缺點(diǎn),因?yàn)辄c(diǎn)位比較器沒有反饋的機(jī)制,所以最后小球在空中震蕩的頻率會越來越快,最后超過閾值會吸在通電線圈上。
現(xiàn)在通過stm32可以通過程序,例如
增加一個剎車的機(jī)制,設(shè)置一個隨時間變化的比例,通過改變in1,in2,ena的電平狀態(tài),逐步增加剎車時間,完成穩(wěn)定懸浮體的作用。

評分

參與人數(shù) 1黑幣 +11 收起 理由
564654654 + 11 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂2 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:230171 發(fā)表于 2017-8-31 09:22 | 只看該作者
我實(shí)驗(yàn)用電源直接給電磁鐵通電 磁鐵會在線圈中間懸浮,在外面根本懸停不了 請問是不是在線圈上面加塊鐵片?
回復(fù)

使用道具 舉報(bào)

板凳
ID:68875 發(fā)表于 2017-9-3 22:12 | 只看該作者
不錯的東西,收藏了
回復(fù)

使用道具 舉報(bào)

地板
ID:377919 發(fā)表于 2019-5-19 13:04 | 只看該作者
最近正要動手,謝謝分享
回復(fù)

使用道具 舉報(bào)

5#
ID:1092471 發(fā)表于 2023-9-2 15:04 | 只看該作者
可以發(fā)下源代碼嗎?
回復(fù)

使用道具 舉報(bào)

6#
ID:149043 發(fā)表于 2024-9-22 11:09 來自手機(jī) | 只看該作者
大佬,有完整的代碼嗎
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表