标题:
利用stm32实现PID恒流源控制的源程序
[打印本页]
作者:
nanisnan
时间:
2019-4-23 16:43
标题:
利用stm32实现PID恒流源控制的源程序
STM32单片机源程序如下:
/* Includes 包含库函数操作的文件---------------------------------------------------*/
#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; //设定的电流值(范围是0.1-0.8A 步进0.05A),Pv是PID返回值
u16 U_Set_adcvalue; //设定的电流值转化成ADC值
u16 CCR1_Val; // PWM的设定值
u16 ADCConvertedValue; //ADC返回的值
u8 PIDStart=1; //PID调节使能标识
u8 x=0,y=0;
u16 ADCConvertedValue_100[100];
u32 ADCConvertedValue_ave;
int main(void)
{
#ifdef DEBUG
debug();
#endif
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration(); //配置时钟
/* 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恒流源控制系统");
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; //通道设置为串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级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);
}
/*******************************************************************************
函数名:USART1_Configuration
输 入:
输 出:
功能说明:
初始化串口硬件设备,启用中断
配置步骤:
(1)打开GPIO和USART1的时钟
(2)设置USART1两个管脚GPIO模式
(3)配置USART1数据格式、波特率等参数
(4)使能USART1接收中断功能
(5)最后使能USART1功能
*/
void USART1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* 第1步:打开GPIO和USART部件的时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 第2步:将USART Tx的GPIO配置为推挽复用模式 */
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复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第3步已经做了,因此这步可以不做
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第4步:配置USART1参数
- 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);
/* 若接收数据寄存器满,则产生中断 */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
/* 第5步:使能 USART1, 配置完毕 */
USART_Cmd(USART1, ENABLE);
/* 如下语句解决第1个字节无法正确发送出去的问题 */
USART_ClearFlag(USART1, USART_FLAG_TC); // 清标志
}
/*******************************************************************/
/* */
/* STM32向串口1发送1字节 */
/* */
/* */
/*******************************************************************/
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.
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
利用stm32实现PID 恒流源控制.7z
(632.45 KB, 下载次数: 294)
2019-4-23 18:05 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2019-4-23 18:06
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
作者:
天亮说鬼话
时间:
2019-5-31 12:32
很好,帮助很大
作者:
slim443
时间:
2019-8-7 00:11
版主厉害啊
作者:
LEIHU1012
时间:
2020-10-15 17:14
NB,
作者:
woyaodwn
时间:
2021-12-28 09:53
补全电路原理图,源码了吗
作者:
2393878659
时间:
2023-3-1 15:14
楼主您好,求助电路原理图,给红牛,抠扣,贰叁玖叁,八柒捌六,伍九
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1