找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6688|回复: 6
收起左侧

利用stm32实现PID恒流源控制的源程序

  [复制链接]
ID:233255 发表于 2019-4-23 16:43 | 显示全部楼层 |阅读模式
STM32单片机源程序如下:
  1. /* Includes 包含库函数操作的文件---------------------------------------------------*/
  2. #include "main.h"



  3. /*Include SYSTEM 包含操作寄存器的头文件-------------*/
  4. #include "sys.h"
  5. #include "delay.h"
  6. #include "PWM.h"

  7. /*Include linye 包含用户linye的文件-----------*/
  8. #include "key.h"
  9. #include "led.h"
  10. #include "exit.h"
  11. #include "adc.h"
  12. #include "time.h"
  13. #include "Adjust.h"



  14. #define ADC1_DR_Address    ((u32)0x4001244C)




  15. /* Private typedef -----------------------------------------------------------*/
  16. /* Private define ------------------------------------------------------------*/
  17. /* Private macro -------------------------------------------------------------*/
  18. /* Private variables ---------------------------------------------------------*/
  19. static vu32 TimingDelay = 0;
  20. ErrorStatus HSEStartUpStatus = SUCCESS;
  21. DMA_InitTypeDef DMA_InitStructure;

  22. /* Private function prototypes -----------------------------------------------*/
  23. /* Private functions ---------------------------------------------------------*/
  24. void RCC_Configuration(void);
  25. void NVIC_Configuration(void);
  26. void GPIO_Configuration(void);
  27. void DMA_Configuration(void);
  28. void ADC_Configuration(void);
  29. void TIM_Configuration(void);




  30. /*******************************************************************************
  31. * Function Name  : main
  32. * Description    : Main program.
  33. * Input          : None
  34. * Output         : None
  35. * Return         : None
  36. *******************************************************************************/
  37. u8 Counter_1mS;
  38. u8 Counter_100mS;

  39. u8 Flag_1mS;
  40. u8 Flag_100mS;
  41. u8 Flag_1S;

  42. float Current_set=0.1,Pv;  //设定的电流值(范围是0.1-0.8A 步进0.05A),Pv是PID返回值
  43. u16 U_Set_adcvalue;          //设定的电流值转化成ADC值
  44. u16 CCR1_Val;                 //        PWM的设定值
  45. u16 ADCConvertedValue;        //ADC返回的值
  46. u8 PIDStart=1;  //PID调节使能标识
  47. u8 x=0,y=0;
  48. u16 ADCConvertedValue_100[100];
  49. u32 ADCConvertedValue_ave;
  50. int main(void)
  51. {




  52. #ifdef DEBUG
  53.   debug();
  54. #endif
  55.   


  56.   /* System clocks configuration ---------------------------------------------*/
  57.   RCC_Configuration();           //配置时钟
  58.   /* NVIC configuration ------------------------------------------------------*/
  59.   NVIC_Configuration();           //配置串口中断
  60.   /* GPIO configuration ------------------------------------------------------*/

  61.   GPIO_Configuration();

  62.   USART1_Configuration();  //配置串口 在本文件中

  63.   /* Configure the systick */   
  64.   SysTick_Config();
  65.   /* Initialize the LCD */
  66.   STM3210E_LCD_Init();

  67.   /*以下是配置直接操作寄存器的文件--------------*/
  68.   led_init();
  69.   //key_init();
  70.   delay_init(72);
  71.   Exit_Init();


  72.    

  73.   Timer2_Init(10,7200);


  74.   DMA_Configuration();
  75.   ADC_Configuration();
  76.   TIM_Configuration();

  77.   /* Clear the LCD */
  78.   LCD_Clear(White);
  79.   LCD_SetBackColor(White);
  80.   LCD_SetTextColor(Blue);
  81.   LCD_DisplayHZLine(Line0,5,"PID恒流源控制系统");
  82.   LCD_DisplayStringLine(Line1,0,"ADCConvertedValue:");
  83.   LCD_DisplayStringLine(Line2,0,"Current_set:");
  84.   LCD_DisplayStringLine(Line2,22,"A");
  85.   LCD_DisplayStringLine(Line3,0,"U_Set_adcvalue:");
  86.   LCD_DisplayStringLine(Line4,0,"CCR1_Val:");

  87.   while (1)
  88.   {       
  89.     U_Set_adcvalue=Current_set*3474.55;        //=(Current_set*2.94*4095)/0.8*3.3
  90.          
  91.         if(Flag_100mS==1)
  92.         {
  93.                 LCD_DisplayU16Line(Line1,18,(u16)ADCConvertedValue_ave,0);
  94.                 LCD_DisplayU16Line(Line1,24,(u16)((ADCConvertedValue_ave*330)/4095),2);
  95.                 LCD_DisplayU16Line(Line2,18,(u16)(Current_set*100),2);
  96.                 LCD_DisplayU16Line(Line3,18,U_Set_adcvalue,0);
  97.                 LCD_DisplayU16Line(Line3,24,(U_Set_adcvalue*33)/4095,1);
  98.                 LCD_DisplayU16Line(Line4,18,CCR1_Val,0);

  99.                 LCD_DisplayU16Line(Line7,18,ADCConvertedValue,0);
  100.                 if(PIDStart==1)
  101.                 {
  102.                         if(U_Set_adcvalue-(u16)ADCConvertedValue_ave>=15||U_Set_adcvalue-(u16)ADCConvertedValue_ave<=-15)
  103.                         {
  104.                                 Pv=Vol(U_Set_adcvalue,(u16)ADCConvertedValue_ave);
  105.                                 CCR1_Val=CCR1_Val+Pv/0.34;                      //0.68=4095/3000*2

  106.                                 if(CCR1_Val>=11999)
  107.                                 CCR1_Val=11999;
  108.                                 else if(CCR1_Val<=1)
  109.                                 CCR1_Val=1;
  110.                                
  111.                                 TIM3->CCR1=CCR1_Val;
  112.                         }
  113.                 }
  114.        
  115.        

  116.                 Flag_100mS=0;

  117.        
  118.         }
  119.         if(Flag_1mS==1)
  120.         {
  121.                
  122.                 ADCConvertedValue_100[x]=ADCConvertedValue;
  123.                 x=x+1;
  124.                 if(x==100)
  125.                 {
  126.                   x=0;
  127.                   for(y=0;y<100;y++)
  128.                       ADCConvertedValue_ave+=ADCConvertedValue_100[y];
  129.                   ADCConvertedValue_ave=ADCConvertedValue_ave/101;
  130.                
  131.                 }
  132.                 Flag_1mS=0;
  133.                  
  134.        
  135.         }

  136.    }
  137. }

  138. /*******************************************************************************
  139. * Function Name  : RCC_Configuration
  140. * Description    : Configures the different system clocks.
  141. * Input          : None
  142. * Output         : None
  143. * Return         : None
  144. *******************************************************************************/
  145. void RCC_Configuration(void)
  146. {
  147.   /* RCC system reset(for debug purpose) */
  148.   RCC_DeInit();

  149.   /* Enable HSE */
  150.   RCC_HSEConfig(RCC_HSE_ON);

  151.   /* Wait till HSE is ready */
  152.   HSEStartUpStatus = RCC_WaitForHSEStartUp();

  153.   if(HSEStartUpStatus == SUCCESS)
  154.   {
  155.     /* Enable Prefetch Buffer */
  156.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  157.     /* Flash 2 wait state */
  158.     FLASH_SetLatency(FLASH_Latency_2);
  159.        
  160.     /* HCLK = SYSCLK */
  161.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
  162.   
  163.     /* PCLK2 = HCLK */
  164.     RCC_PCLK2Config(RCC_HCLK_Div1);

  165.     /* PCLK1 = HCLK/2 */
  166.     RCC_PCLK1Config(RCC_HCLK_Div2);

  167.     /* ADCCLK = PCLK2/4 */
  168.     RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  169.   
  170.     /* PLLCLK = 8MHz * 9 = 72 MHz */
  171.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

  172.     /* Enable PLL */
  173.     RCC_PLLCmd(ENABLE);

  174.     /* Wait till PLL is ready */
  175.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  176.     {
  177.     }

  178.     /* Select PLL as system clock source */
  179.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  180.     /* Wait till PLL is used as system clock source */
  181.     while(RCC_GetSYSCLKSource() != 0x08)
  182.     {
  183.     }
  184.   }
  185.   /* Enable peripheral clocks --------------------------------------------------*/
  186.   /* Enable DMA1 clock */
  187.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  188.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_TIM3, ENABLE);  
  189.   /* Enable GPIOx clock */
  190.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
  191.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  192.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  193. }
  194. /*******************************************************************************
  195. * Function Name  : NVIC_Configuration
  196. * Description    : Configures Vector Table base location.
  197. * Input          : None
  198. * Output         : None
  199. * Return         : None
  200. *******************************************************************************/
  201. void NVIC_Configuration(void)
  202. {

  203. //#ifdef  VECT_TAB_RAM  
  204. //  /* Set the Vector Table base location at 0x20000000 */
  205. //  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  206. //#else  /* VECT_TAB_FLASH  */
  207. //  /* Set the Vector Table base location at 0x08000000 */
  208. //  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
  209. //#endif

  210.    
  211.    
  212.    NVIC_InitTypeDef NVIC_InitStructure;
  213.   
  214.    /* Set the Vector Table base location at 0x08000000 */
  215.    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  216.   
  217.    /* Configure the NVIC Preemption Priority Bits */  
  218.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  219.   
  220.    /* Enable the USART1 Interrupt */
  221.    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;       //通道设置为串口1中断
  222.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
  223.    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;           //中断响应优先级0
  224.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                   //打开中断
  225.    NVIC_Init(&NVIC_InitStructure);                                                    //初始化

  226. }

  227. /*******************************************************************************
  228. * Function Name  : GPIO_Configuration
  229. * Description    : Configures the different GPIO ports.
  230. * Input          : None
  231. * Output         : None
  232. * Return         : None
  233. *******************************************************************************/
  234. void GPIO_Configuration(void)
  235. {
  236.   GPIO_InitTypeDef GPIO_InitStructure;

  237.   /* Configure PG.08 as input */
  238.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  239.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  240.   GPIO_Init(GPIOG, &GPIO_InitStructure);



  241.     /* Configure PB.01 (ADC Channel9) as analog input -------------------------*/
  242.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  243.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  244.   GPIO_Init(GPIOB, &GPIO_InitStructure);

  245.   /*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull| GPIO_Pin_7 */
  246.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 ;
  247.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  248.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  249.   GPIO_Init(GPIOA, &GPIO_InitStructure);

  250. }

  251. /*******************************************************************************
  252. * Function Name  : SysTick_Config
  253. * Description    : Configure a SysTick Base time to 10 ms.
  254. * Input          : None
  255. * Output         : None
  256. * Return         : None
  257. *******************************************************************************/
  258. void SysTick_Config(void)
  259. {
  260.   /* Configure HCLK clock as SysTick clock source */
  261.   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

  262.   /* SysTick interrupt each 100 Hz with HCLK equal to 72MHz */
  263.   SysTick_SetReload(720000);

  264.   /* Enable the SysTick Interrupt */
  265.   SysTick_ITConfig(ENABLE);
  266. }

  267. /*******************************************************************************
  268.         函数名:USART1_Configuration
  269.         输  入:
  270.         输  出:
  271.         功能说明:
  272.         初始化串口硬件设备,启用中断
  273.         配置步骤:
  274.         (1)打开GPIO和USART1的时钟
  275.         (2)设置USART1两个管脚GPIO模式
  276.         (3)配置USART1数据格式、波特率等参数
  277.         (4)使能USART1接收中断功能
  278.         (5)最后使能USART1功能
  279. */
  280. void USART1_Configuration(void)
  281. {
  282.         GPIO_InitTypeDef GPIO_InitStructure;
  283.         USART_InitTypeDef USART_InitStructure;

  284.         /* 第1步:打开GPIO和USART部件的时钟 */
  285.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  286.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  287.         /* 第2步:将USART Tx的GPIO配置为推挽复用模式 */
  288.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  289.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  290.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  291.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  292.         /* 第3步:将USART Rx的GPIO配置为浮空输入模式
  293.                 由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
  294.                 但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
  295.         */
  296.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  297.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  298.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  299.         /*  第3步已经做了,因此这步可以不做
  300.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  301.         */
  302.         GPIO_Init(GPIOA, &GPIO_InitStructure);


  303.         /* 第4步:配置USART1参数
  304.             - BaudRate = 115200 baud
  305.             - Word Length = 8 Bits
  306.             - One Stop Bit
  307.             - No parity
  308.             - Hardware flow control disabled (RTS and CTS signals)
  309.             - Receive and transmit enabled
  310.         */
  311.         USART_InitStructure.USART_BaudRate = 9600;
  312.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  313.         USART_InitStructure.USART_StopBits = USART_StopBits_1;
  314.         USART_InitStructure.USART_Parity = USART_Parity_No;
  315.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  316.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  317.         USART_Init(USART1, &USART_InitStructure);

  318.     /* 若接收数据寄存器满,则产生中断 */
  319.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  320.         /* 第5步:使能 USART1, 配置完毕 */
  321.         USART_Cmd(USART1, ENABLE);

  322.     /* 如下语句解决第1个字节无法正确发送出去的问题 */
  323.     USART_ClearFlag(USART1, USART_FLAG_TC);     // 清标志
  324. }





  325. /*******************************************************************/
  326. /*                                                                 */
  327. /* STM32向串口1发送1字节                                           */
  328. /*                                                                 */
  329. /*                                                                 */
  330. /*******************************************************************/
  331. void Uart1_PutChar(u8 ch)
  332. {
  333.   USART_SendData(USART1, (u8) ch);
  334.   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  335. }



  336. /*******************************************************************************
  337. * Function Name  : Delay
  338. * Description    : Inserts a delay time.
  339. * Input          : nCount: specifies the delay time length (time base 10 ms).
  340. * Output         : None
  341. * Return         : None
  342. *******************************************************************************/
  343. void Delay(u32 nCount)
  344. {
  345.   TimingDelay = nCount;

  346.   /* Enable the SysTick Counter */
  347.   SysTick_CounterCmd(SysTick_Counter_Enable);
  348.   
  349.   while(TimingDelay != 0)
  350.   {
  351.   }

  352.   /* Disable the SysTick Counter */
  353.   SysTick_CounterCmd(SysTick_Counter_Disable);

  354.   /* Clear the SysTick Counter */
  355.   SysTick_CounterCmd(SysTick_Counter_Clear);
  356. }

  357. /*******************************************************************************
  358. * Function Name  : Decrement_TimingDelay
  359. * Description    : Decrements the TimingDelay variable.
  360. * Input          : None
  361. * Output         : TimingDelay
  362. * Return         : None
  363. *******************************************************************************/
  364. void Decrement_TimingDelay(void)
  365. {
  366.   if (TimingDelay != 0x00)
  367.   {
  368.     TimingDelay--;
  369.   }
  370. }
  371. void DMA_Configuration(void)
  372. {
  373. /* DMA1 channel1 configuration ----------------------------------------------*/
  374.   DMA_DeInit(DMA1_Channel1);
  375.   DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  376.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
  377.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  378.   DMA_InitStructure.DMA_BufferSize = 1;
  379.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  380.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  381.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  382.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  383.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  384.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  385.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  386.   DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  387.   
  388.   /* Enable DMA1 channel1 */
  389.   DMA_Cmd(DMA1_Channel1, ENABLE);
  390. }



  391. void ADC_Configuration(void)
  392. {
  393.   ADC_InitTypeDef ADC_InitStructure;   
  394.   /* ADC1 configuration ------------------------------------------------------*/
  395.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  396.   ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  397.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  398.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  399.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  400.   ADC_InitStructure.ADC_NbrOfChannel = 1;
  401.   ADC_Init(ADC1, &ADC_InitStructure);

  402.   /* ADC1 regular channel9 PB1 configuration */
  403.   ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);

  404.   /* Enable ADC1 DMA */
  405.   ADC_DMACmd(ADC1, ENABLE);
  406.   
  407.   /* Enable ADC1 */
  408.   ADC_Cmd(ADC1, ENABLE);

  409.   /* Enable ADC1 reset calibaration register */   
  410.   ADC_ResetCalibration(ADC1);
  411.   /* Check the end of ADC1 reset calibration register */
  412.   while(ADC_GetResetCalibrationStatus(ADC1));

  413.   /* Start ADC1 calibaration */
  414.   ADC_StartCalibration(ADC1);
  415.   /* Check the end of ADC1 calibration */
  416.   while(ADC_GetCalibrationStatus(ADC1));
  417.      
  418.   /* Start ADC1 Software Conversion */
  419.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  420. }


  421. void TIM_Configuration(void)
  422. {

  423.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  424.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  425.   /* -----------------------------------------------------------------------
  426.     TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
  427.     TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
  428.     TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
  429.     TIM3 Frequency = 36 KHz.
  430. ……………………

  431. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
利用stm32实现PID 恒流源控制.7z (632.45 KB, 下载次数: 278)
回复

使用道具 举报

ID:1 发表于 2019-4-23 18:06 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

ID:386983 发表于 2019-5-31 12:32 | 显示全部楼层
很好,帮助很大
回复

使用道具 举报

ID:302666 发表于 2019-8-7 00:11 | 显示全部楼层
版主厉害啊
回复

使用道具 举报

ID:485487 发表于 2020-10-15 17:14 | 显示全部楼层
NB,
回复

使用道具 举报

ID:462629 发表于 2021-12-28 09:53 | 显示全部楼层
补全电路原理图,源码了吗
回复

使用道具 举报

ID:576063 发表于 2023-3-1 15:14 | 显示全部楼层
楼主您好,求助电路原理图,给红牛,抠扣,贰叁玖叁,八柒捌六,伍九
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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