/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2004-09-16
** Last Version: 1.0
** Descriptions: The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2004-09-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Chenxibing
** Modified date: 2005-01-20
** Version:
** Descriptions: AD转换实验。
**
********************************************************************************************************/
/********************************************************************************************************
** 功能 :使用ADC模块的通道3进行电压的测量,然后将转换结果从串口送出。
** 上位机使用EasyARM软件全仿真的DOS窗口观察。
** 说明 :由W1调节测量电压值。
** 通讯波特率115200,8位数据位,1位停止位,无奇偶校验。
********************************************************************************************************/
#include "config.h"
#include "12864.h"
#include "18b20.h"
/*
*******************************************************************************************************
** 函数名称 :DelayNS()
** 函数功能 :长软件延时
** 入口参数 :dly 延时参数,值越大,延时越久
** 出口参数 :无
*******************************************************************************************************
*/
void DelayNS (uint32 dly)
{
uint32 i;
for ( ; dly>0; dly--)
for (i=0; i<5000; i++);
}
#define UART_BPS 9600 // 通讯波特率9600
/*
*******************************************************************************************************
** 函数名称 :UART0_Init()
** 函数功能 :初始化串口0:波特率115200,8位数据位,1位停止位,无奇偶校验。
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************************
*/
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()
** 函数功能 :向串口发送字节数据,并等待数据发送完毕。
** 入口参数 :data 要发送的数据
** 出口参数 :无
*******************************************************************************************************
*/
void UART0_SendByte (uint8 data)
{
U0THR = data;
while ((U0LSR & 0x40) == 0); // 等待数据发送完毕
}
/*
*******************************************************************************************************
** 函数名称 :PC_DispChar()
** 函数功能 :向PC机发送显示字符。
** 入口参数 :x 显示字符的横坐标
** y 显示字符的纵坐标
** chr 显示的字符,不能为ff
** color 显示的状态,包括前景色、背景色、闪烁位。
** 与DOS字符显示一样:0~3,前景色,4~6,背景色,7,闪烁位。
** 出口参数 :无
*******************************************************************************************************
*/
void PC_DispChar (uint8 x, uint8 y, uint8 chr, uint8 color)
{
UART0_SendByte(0xff); // 起始字符
UART0_SendByte(x);
UART0_SendByte(y);
UART0_SendByte(chr);
UART0_SendByte(color);
}
/*
*******************************************************************************************************
** 函数名称 :ISendStr()
** 函数功能 :向上位机发送字符串。
** 入口参数 :x 显示字符的横坐标
** y 显示字符的纵坐标
** color 显示的状态,包括前景色、背景色、闪烁位。
** 与DOS字符显示一样:0~3,前景色,4~6,背景色,7,闪烁位。
** str 要发送的字符串,以'\0'结束
** 出口参数 :无
*******************************************************************************************************
*/
void ISendStr (uint8 x, uint8 y, uint8 color, char *str)
{
while (1)
{
if (*str == '\0') break; // 结束字符
PC_DispChar(x++, y, *str++, color);
if (x >= 80)
{
x = 0;
y++;
}
}
}
/*==================================================================================================== PID Function The PID (比例、积分、微分) function is used in mainly control applications. PIDCalc performs one iteration of the PID algorithm. While the PID function works, main is just a dummy program showing a typical usage. =====================================================================================================*/
typedef struct PID
{
int SetPoint; //设定目标 Desired Value
long SumError;//误差累计
double Proportion;//比例常数 Proportional Const
double Integral;//积分常数 Integral Const
double Derivative;//微分常数 Derivative Const
int LastError; //Error[-1]
int PrevError; //Error[-2]
} PID;
static PID sPID;
static PID *sptr = &sPID;
/*==================================================================================================== Initialize PID Structure PID参数初始化=====================================================================================================*/
void IncPIDInit(void)
{
sptr->SumError = 0;
sptr->LastError = 0;//Error[-1]
sptr->PrevError = 0;//Error[-2]
sptr->Proportion = 0.8;//比例常数 Proportional Const
sptr->Integral = 0.5; //积分常数Integral Const
sptr->Derivative = 0;//微分常数 Derivative Const
sptr->SetPoint = 1300;
}
/**====================================================================================================
PID计算部分
=====================================================================================================*/
double PIDCalc( PID *pp, double NextPoint )
{
double dError,
Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = pp->LastError - pp->PrevError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
+ pp->Integral * pp->SumError // 积分项
+ pp->Derivative * dError // 微分项
);
}
/*
*******************************************************************************************************
** 函数名称 :main()
** 函数功能 :进行3通道电压ADC转换,并把结果转换成电压值,发送到串口。
** 调试说明 :在config.h中包含stdio.h
*******************************************************************************************************
*/
int main (void)
{
uint32 ADC_Data;
char str[20];
uint8 m;
double rOut; // PID Response (Output)
double rIn; // PID Feedback (Input)
PINSEL0 = 0x00000005; // 管脚连接串口
PINSEL1 = 1 << 28; // P0.30连接到AD0.3
UART0_Init();
/* 进行ADC模块设置 */
AD0CR = (1 << 3) | // SEL=8,选择通道3
((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); // 直接启动ADC转换时,此位无效
DelayNS(10);
ADC_Data = AD0DR; // 读取ADC结果,并清除DONE标志位
lcd_init();//液晶初始化
clear();//清屏
for(m=0;m<=5;m++)
{
lcd_xianshi();//显示汉字
}
IncPIDInit();
while (1)
{
AD0CR |= 1 << 24; // 进行第一次转换
while ((ADDR & 0x80000000) == 0); // 等待转换结束
AD0CR |= 1 << 24; // 再次启动转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
ADC_Data = AD0DR; // 读取ADC结果
ADC_Data = (AD