標(biāo)題:
利用stm32實(shí)現(xiàn)PID恒流源控制的源程序
[打印本頁]
作者:
nanisnan
時(shí)間:
2019-4-23 16:43
標(biāo)題:
利用stm32實(shí)現(xiàn)PID恒流源控制的源程序
STM32單片機(jī)源程序如下:
/* Includes 包含庫函數(shù)操作的文件---------------------------------------------------*/
#include "main.h"
/*Include SYSTEM 包含操作寄存器的頭文件-------------*/
#include "sys.h"
#include "delay.h"
#include "PWM.h"
/*Include linye 包含用戶linye的文件-----------*/
#include "key.h"
#include "led.h"
#include "exit.h"
#include "adc.h"
#include "time.h"
#include "Adjust.h"
#define ADC1_DR_Address ((u32)0x4001244C)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static vu32 TimingDelay = 0;
ErrorStatus HSEStartUpStatus = SUCCESS;
DMA_InitTypeDef DMA_InitStructure;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void ADC_Configuration(void);
void TIM_Configuration(void);
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u8 Counter_1mS;
u8 Counter_100mS;
u8 Flag_1mS;
u8 Flag_100mS;
u8 Flag_1S;
float Current_set=0.1,Pv; //設(shè)定的電流值(范圍是0.1-0.8A 步進(jìn)0.05A),Pv是PID返回值
u16 U_Set_adcvalue; //設(shè)定的電流值轉(zhuǎn)化成ADC值
u16 CCR1_Val; // PWM的設(shè)定值
u16 ADCConvertedValue; //ADC返回的值
u8 PIDStart=1; //PID調(diào)節(jié)使能標(biāo)識(shí)
u8 x=0,y=0;
u16 ADCConvertedValue_100[100];
u32 ADCConvertedValue_ave;
int main(void)
{
#ifdef DEBUG
debug();
#endif
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration(); //配置時(shí)鐘
/* NVIC configuration ------------------------------------------------------*/
NVIC_Configuration(); //配置串口中斷
/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration();
USART1_Configuration(); //配置串口 在本文件中
/* Configure the systick */
SysTick_Config();
/* Initialize the LCD */
STM3210E_LCD_Init();
/*以下是配置直接操作寄存器的文件--------------*/
led_init();
//key_init();
delay_init(72);
Exit_Init();
Timer2_Init(10,7200);
DMA_Configuration();
ADC_Configuration();
TIM_Configuration();
/* Clear the LCD */
LCD_Clear(White);
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
LCD_DisplayHZLine(Line0,5,"PID恒流源控制系統(tǒng)");
LCD_DisplayStringLine(Line1,0,"ADCConvertedValue:");
LCD_DisplayStringLine(Line2,0,"Current_set:");
LCD_DisplayStringLine(Line2,22,"A");
LCD_DisplayStringLine(Line3,0,"U_Set_adcvalue:");
LCD_DisplayStringLine(Line4,0,"CCR1_Val:");
while (1)
{
U_Set_adcvalue=Current_set*3474.55; //=(Current_set*2.94*4095)/0.8*3.3
if(Flag_100mS==1)
{
LCD_DisplayU16Line(Line1,18,(u16)ADCConvertedValue_ave,0);
LCD_DisplayU16Line(Line1,24,(u16)((ADCConvertedValue_ave*330)/4095),2);
LCD_DisplayU16Line(Line2,18,(u16)(Current_set*100),2);
LCD_DisplayU16Line(Line3,18,U_Set_adcvalue,0);
LCD_DisplayU16Line(Line3,24,(U_Set_adcvalue*33)/4095,1);
LCD_DisplayU16Line(Line4,18,CCR1_Val,0);
LCD_DisplayU16Line(Line7,18,ADCConvertedValue,0);
if(PIDStart==1)
{
if(U_Set_adcvalue-(u16)ADCConvertedValue_ave>=15||U_Set_adcvalue-(u16)ADCConvertedValue_ave<=-15)
{
Pv=Vol(U_Set_adcvalue,(u16)ADCConvertedValue_ave);
CCR1_Val=CCR1_Val+Pv/0.34; //0.68=4095/3000*2
if(CCR1_Val>=11999)
CCR1_Val=11999;
else if(CCR1_Val<=1)
CCR1_Val=1;
TIM3->CCR1=CCR1_Val;
}
}
Flag_100mS=0;
}
if(Flag_1mS==1)
{
ADCConvertedValue_100[x]=ADCConvertedValue;
x=x+1;
if(x==100)
{
x=0;
for(y=0;y<100;y++)
ADCConvertedValue_ave+=ADCConvertedValue_100[y];
ADCConvertedValue_ave=ADCConvertedValue_ave/101;
}
Flag_1mS=0;
}
}
}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
/* Enable peripheral clocks --------------------------------------------------*/
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_TIM3, ENABLE);
/* Enable GPIOx clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures Vector Table base location.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
//#ifdef VECT_TAB_RAM
// /* Set the Vector Table base location at 0x20000000 */
// NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
//#else /* VECT_TAB_FLASH */
// /* Set the Vector Table base location at 0x08000000 */
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
//#endif
NVIC_InitTypeDef NVIC_InitStructure;
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; //通道設(shè)置為串口1中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中斷響應(yīng)優(yōu)先級(jí)0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打開中斷
NVIC_Init(&NVIC_InitStructure); //初始化
}
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PG.08 as input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOG, &GPIO_InitStructure);
/* Configure PB.01 (ADC Channel9) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull| GPIO_Pin_7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : SysTick_Config
* Description : Configure a SysTick Base time to 10 ms.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SysTick_Config(void)
{
/* Configure HCLK clock as SysTick clock source */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
/* SysTick interrupt each 100 Hz with HCLK equal to 72MHz */
SysTick_SetReload(720000);
/* Enable the SysTick Interrupt */
SysTick_ITConfig(ENABLE);
}
/*******************************************************************************
函數(shù)名:USART1_Configuration
輸 入:
輸 出:
功能說明:
初始化串口硬件設(shè)備,啟用中斷
配置步驟:
(1)打開GPIO和USART1的時(shí)鐘
(2)設(shè)置USART1兩個(gè)管腳GPIO模式
(3)配置USART1數(shù)據(jù)格式、波特率等參數(shù)
(4)使能USART1接收中斷功能
(5)最后使能USART1功能
*/
void USART1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* 第1步:打開GPIO和USART部件的時(shí)鐘 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 第2步:將USART Tx的GPIO配置為推挽復(fù)用模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第3步:將USART Rx的GPIO配置為浮空輸入模式
由于CPU復(fù)位后,GPIO缺省都是浮空輸入模式,因此下面這個(gè)步驟不是必須的
但是,我還是建議加上便于閱讀,并且防止其它地方修改了這個(gè)口線的設(shè)置參數(shù)
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第3步已經(jīng)做了,因此這步可以不做
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第4步:配置USART1參數(shù)
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* 若接收數(shù)據(jù)寄存器滿,則產(chǎn)生中斷 */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
/* 第5步:使能 USART1, 配置完畢 */
USART_Cmd(USART1, ENABLE);
/* 如下語句解決第1個(gè)字節(jié)無法正確發(fā)送出去的問題 */
USART_ClearFlag(USART1, USART_FLAG_TC); // 清標(biāo)志
}
/*******************************************************************/
/* */
/* STM32向串口1發(fā)送1字節(jié) */
/* */
/* */
/*******************************************************************/
void Uart1_PutChar(u8 ch)
{
USART_SendData(USART1, (u8) ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
/*******************************************************************************
* Function Name : Delay
* Description : Inserts a delay time.
* Input : nCount: specifies the delay time length (time base 10 ms).
* Output : None
* Return : None
*******************************************************************************/
void Delay(u32 nCount)
{
TimingDelay = nCount;
/* Enable the SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Enable);
while(TimingDelay != 0)
{
}
/* Disable the SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Disable);
/* Clear the SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Clear);
}
/*******************************************************************************
* Function Name : Decrement_TimingDelay
* Description : Decrements the TimingDelay variable.
* Input : None
* Output : TimingDelay
* Return : None
*******************************************************************************/
void Decrement_TimingDelay(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
void DMA_Configuration(void)
{
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel9 PB1 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
TIM3 Frequency = 36 KHz.
……………………
…………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
利用stm32實(shí)現(xiàn)PID 恒流源控制.7z
(632.45 KB, 下載次數(shù): 294)
2019-4-23 18:05 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
admin
時(shí)間:
2019-4-23 18:06
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
作者:
天亮說鬼話
時(shí)間:
2019-5-31 12:32
很好,幫助很大
作者:
slim443
時(shí)間:
2019-8-7 00:11
版主厲害啊
作者:
LEIHU1012
時(shí)間:
2020-10-15 17:14
NB,
作者:
woyaodwn
時(shí)間:
2021-12-28 09:53
補(bǔ)全電路原理圖,源碼了嗎
作者:
2393878659
時(shí)間:
2023-3-1 15:14
樓主您好,求助電路原理圖,給紅牛,摳扣,貳叁玖叁,八柒捌六,伍九
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1