⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blinky.c

📁 LPC2138单片机做控制器
💻 C
字号:
			    #include  "lpc21xx.h"
#include <stdio.h>	   //包括sprintf这个函数的头文件
#define Fpclk 11059200
#define UART_BPS 57600
#define Q_da 	100/66/*da转换系数 */
#define uint32 unsigned int
#define uint16 unsigned short
#define uint8 unsigned char
 	/*全局变量声明*/

float  Kp,Ti,Td,T,Geiding,de,de1,de2,uf,uo,ad_celiang,q0,q1,q2,shchshx,shchxx ;
	/*Kp--比例度, Ti--积分时间, Td--微分时间,T--采样时间,Geiding--给定值*/
	/*cel--用clshx,clxx,jzhshx,jzhxx校准后的测量值,用来计算偏差*/
	/*de,de1,de2,uf本次偏差(测量值-给定值)和上次偏差,上上次偏差,增量输出*/	
	/*函数声明*/
void  	DelayNS(uint32  dly);
void  	UART0_Init(void);
void  	UART0_SendByte(uint8 data);
void  	UART0_SendStr(char *str)	;
void 	ADC_Init(void);
int 	ADC_Funtion(void) ;
void 	DAC_Init(void);
void 	DAC_Funtion(uint16	V_Aout);
void	Time0Init(void);
void	PID_Init1(void);
int		PID1(void);

/****************************************************************************
* 名    称:main()
* 功    能:主函数
****************************************************************************/
int  main(void)
{
    PINSEL0 = 0x00000005;		    // 设置I/O连接到UART0
    UART0_Init();					//串口初始化
	ADC_Init();						//AD转化初始化
	DAC_Init();						//DA转化初始化
	Time0Init();					// 初始化定时器0
	PID_Init1();						//PID参数初始化
	//DAC_Funtion (Geiding);									 
    while(1)	
    {  
		while( T0IR&0x01== 0 );			    // 等待定时时间到
        T0IR = 0x01;							// 清除中断标志 
		{
		ADC_Funtion();
		PID1();
		DAC_Funtion (uo);
		}
    }
}
/****************************************************************************
* 名    称:DelayNS()
* 功    能:长软件延时
****************************************************************************/
void  DelayNS(uint32  dly)
{   uint32  i;
    for(; dly>0; dly--) 
    {
        for(i=0; i<5000; i++);
    }
}
/****************************************************************************
* 名    称:UART0_Ini()
* 功    能:初始化串口0。设置为8位数据位,1位停止位,无奇偶校验,波特率为115200
****************************************************************************/
void  UART0_Init(void)
{   uint16 Fdiv;
    U0LCR = 0x83;						// DLAB = 1,可设置波特率
    Fdiv = (Fpclk / 16) / UART_BPS;		// 设置波特率
    U0DLM = Fdiv / 256;							
    U0DLL = Fdiv % 256;						
    U0LCR = 0x03;
}				
/****************************************************************************
* 名    称:UART0_SendByte()
* 功    能:向串口发送字节数据,并等待发送完毕。
****************************************************************************/
void  UART0_SendByte(uint8 data)
{  
    U0THR = data;				    	// 发送数据
    while( (U0LSR&0x40)==0 );	    	// 等待数据发送完毕
}
/****************************************************************************
* 名    称:UART0_SendStr()
* 功    能:向串口发送一字符串
****************************************************************************/
void  UART0_SendStr(char *str)
{  
    while(1)
    {  
        if( *str == '\0' ) break;
        UART0_SendByte(*str++);	    	// 发送数据
    }
}
/*********************************AD转化初始化*******************************
* 名    称:ADC_Init()
* 功    能:AD转换初始化设置
****************************************************************************/
void  ADC_Init(void)
{
	PINSEL1 = 	PINSEL1|0x00400000;						// 设置P0.27连接到AIN0
    /*进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延) */
    ADCR = (1 << 0)                     |		// SEL = 1 ,选择通道0
           ((Fpclk / 1000000 - 1) << 8) | 		// CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
           (0 << 16)                    |		// BURST = 0 ,软件控制转换操作
           (0 << 17)                    | 		// CLKS = 0 ,使用11clock转换
           (1 << 21)                    | 		// PDN = 1 , 正常工作模式(非掉电转换模式)
           (0 << 22)                    | 		// TEST1:0 = 00 ,正常工作模式(非测试模式)
           (1 << 24)                    | 		// START = 1 ,直接启动ADC转换
           (0 << 27);							// EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
}
/*********************************AD转化函数********************************
* 名    称:ADC_Funtion()
* 功    能:
****************************************************************************/
int ADC_Funtion(void)
{  	char    str_1[20];
	uint32  ADC_Data;	
	ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24);	// 设置通道1,并进行第一次转换
    while( (ADDR&0x80000000)==0 );	            // 等待转换结束
    ADCR = ADCR | (1 << 24);					// 再次启运转换
    while( (ADDR&0x80000000)==0 );              // 等待转换结束
    ADC_Data = ADDR;							// 读取ADC结果					
    ADC_Data = (ADC_Data>>6) & 0x3FF;           // 提取AD转换值
	ad_celiang=ADC_Data;							//计算偏差的时候要用
    ADC_Data = ADC_Data * 3300*Q_da/1024;           // 数值转换	
    sprintf(str_1, "%d \r", ADC_Data);           
    UART0_SendStr(str_1); 
	return	ad_celiang;
}
/*********************************DA转化初始化*******************************
* 名    称:DAC_Init()
* 功    能:
****************************************************************************/
void  DAC_Init(void)
{
	PINSEL1 = 	PINSEL1|0x00080000;			// 设置P0.25连接到Aout,其它不变
}
/*********************************DA转化函数********************************
* 名    称:DAC_Funtion()
* 功    能:
****************************************************************************/
void  DAC_Funtion  (uint16	V_Aout)
{	uint32  DACV_Data;
	DACV_Data=V_Aout;
	DACV_Data=DACV_Data*1024/3300;
 	DACR =((DACV_Data<<6)&0x0000FFC0);	
}
/*********************************定时器初始化********************************
* 名    称:Time0Init()
* 功    能:
****************************************************************************/
void Time0Init(void)
{
	T0TC=0;							//定时器0开始计数时为0
	T0PR = 99;			    		// 设置定时器0分频为100分频,得110592Hz
	T0MCR = 0x03;		   			// 匹配通道0匹配中断并复位T0TC
	T0MR0 = 110592;	    			// 比较值(0.1S定时值)
	T0TCR = 0x03;		   			// 使能并复位T0TC
	T0TCR = 0x01; 					//使能T0TC
}
/*********************************PID初始化函数********************************
* 名    称:PID_Init()
* 功    能:PID参数初始化  增量型控制器
****************************************************************************/
void	PID_Init1(void)						
{
 	
 	Kp=0.007;
	Ti=8000;
 	Td=20;
	T=1;
	
 	Geiding=1800;
	uo=Geiding;
	q0=Kp*(1+T/Ti+Td/T);
	q1=0-Kp*(1+2*Td/T);
	q2=Kp*Td/T;

	shchshx=3000;
	shchxx=0;
	
	de1=0;
   	de2=0;
	}
 /*********************************PID化函数********************************
* 名    称:PID()
* 功    能:PID控制器实现	位置型控制器算法
****************************************************************************/

int	PID1(void)
{	
	
    de=Geiding-ad_celiang;//本次偏差为校准后的的测量值-给定量	
	uf=q0*de+q1*de1+q2*de2;//得到增量
	uo=uo+uf;
 if(ad_celiang>5/3.3*shchshx)//u0判断后按要求赋新值
			{uo=shchshx;}	 
 else if  (ad_celiang<shchxx)	
 			{uo=shchxx;}	 	
	de2=de1;//上上次偏差赋给de2
   	de1=de;//上次偏差赋给本次偏差de1
	return  uo;
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -