极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 23718|回复: 9

STCunio学习笔记热身—数字电源(PID控制环路)实验

[复制链接]
发表于 2014-9-2 22:42:15 | 显示全部楼层 |阅读模式
本帖最后由 STCunio 于 2014-9-19 23:59 编辑

快点来排队吧,PID库开源了
http://www.geek-workshop.com/thread-10890-1-1.html



PID库
3.9.1  pidbegin(int a,int b,int c)

概述

pidbegin函数的作用是将a、b、c三个参数进行赋值,这三个参数的定义参考上述内容。一般的kp、ki、kd是浮点数,那么a、b、c也是浮点型,所以要在使用pidbegin函数之前需要将a、b、c三个参数进行Q15格式化,即左移15次转换成int,最后我们只需将结果右移15次即可还原。如果使用浮点数来进行PID运算也是可以的,但是浮点数运算会占用大量的时间和存储空间,无论是MCU还是DSP选择整型运算要比浮点运算优越很多。

语法

pidbegin(int a,int b,int c)

参数

a:Q15(Kp + Ki + Kd),int型

b:Q15(-(Kp + 2*Kd),int型

c:Q15(Kd),int型

返回值


boostpower.c

#define PID_BOOST_KP 0.23
#define PID_BOOST_KI 0.03
#define PID_BOOST_KD 0.00
//Q15格式转换,无需用float型计算PID
#define PID_BOOST_A Q15(PID_BOOST_KP + PID_BOOST_KI + PID_BOOST_KD)
#define PID_BOOST_B Q15(-1 *(PID_BOOST_KP + 2 * PID_BOOST_KD))
#define PID_BOOST_C Q15(PID_BOOST_KD)

#define BOOST_ADC_ERROR        0x00//采样误差
#if VCC_Vol==VCC3V3
#define PID_BOOST_VOLTAGE_REFERENCE 284 - BOOST_ADC_ERROR//电阻比为:10K/(100K+10K),基准电压为10V
#elif VCC_Vol==VCC5V0
#define PID_BOOST_VOLTAGE_REFERENCE 187 - BOOST_ADC_ERROR//电阻比为:10K/(100K+10K),基准电压为10V
#endif
unsigned int BoostMeasuredOutput     = 0;
unsigned int BoostSoftstartIncrement = 0;
extern u16         j;
int referenceInput;


void BoostVoltageLoop(void)
{      
    pidbegin(PID_BOOST_A,PID_BOOST_B,PID_BOOST_C);      //准备PID运算                     
            
}
void BoostSoftStartRoutine(void)
{
        BoostMeasuredOutput =analogRead(0);//保留第一次采样值
        referenceInput=BoostMeasuredOutput;
        ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | 0;//再次启动AD采样,从此将进入AD中断处理,analogRead不再使用
        EADC=1;//打开AD采样中断
        PADC = 1;//AD中断高优先级
  BoostSoftstartIncrement = ((PID_BOOST_VOLTAGE_REFERENCE - BoostMeasuredOutput) / 50 );//软启动
       
        while(referenceInput<=PID_BOOST_VOLTAGE_REFERENCE)
        {
                delay_ms(1);       
                referenceInput+=BoostSoftstartIncrement;//慢慢将电压升起来
  }
        referenceInput=PID_BOOST_VOLTAGE_REFERENCE;
}

主程序
/*外部变量声明*/
extern  long controlOutput;
extern int referenceInput;

/*变量声明*/
int val;


u16 pwm0;
u16 j;
void main()
{
        u8 i;
        u16 m;
        Serialbegin(2400);//打开串口
        SPIbegin();//SPI功能暂时没用上,使用的是shiftOut来驱动液晶
        SPIsetBitOrder(MSBFIRST);
        SPIsetClockDivider(SPI_CLOCK_DIV16);
        SPIsetDataMode(SPI_MODE1);
        SPIend();
       
        backlight_on;
        initial_lcd();       
        clear_screen(); //clear all dots
        display_string_8x16(4,10,"Hello STCunio!");/*在第4 页,第16 列显示字符串*/

        delay_ms(3000);
        clear_screen(); //clear all dots
        display_string_8x16(1,20,"STCunio R1");/*在第4 页,第16 列显示字符串*/
        display_string_8x16(4,10,"ADCvalue:");/*在第3 页,第10 列显示字符串*/
        display_string_8x16(6,10,"voltage:");/*在第5 页,第10 列显示字符串*/
       
        pinMode(5,OutPP);//将PWM输出设为推挽
        digitalWrite(5,0);//启动时先将PWM拉低,关掉MOSFET
        analogWrite(5,0,PCA_Clock_1T);        //设定pwm的频率为主时钟/256,主时钟频率为33.1776MHz时PWM频率为12.96K
        BoostVoltageLoop();
       
  BoostSoftStartRoutine();
       
        loop()
        {                       
                val = j;    // read the input pin
                i=val/1000+'0';//分离千位
               
                display_string_8x16(4,(10+8*9),&i);
                i=val%1000/100+'0';//分离百位
                display_string_8x16(4,(10+8*10),&i);
                i=val%100/10+'0';//分离十位
                display_string_8x16(4,(10+8*11),&i);
                i=val%10+'0';//分离个位
                display_string_8x16(4,(10+8*12),&i);

                m=val;
                m=(m*5*11*5)>>9;
                i=m/100+'0';//分离百位
                display_string_8x16(6,(10+8*9),&i);
                i=m%100/10+'0';//分离十位
                display_string_8x16(6,(10+8*10),&i);
               
                display_string_8x16(6,(10+8*11),".");
               
                i=m%10+'0';//分离个位
                display_string_8x16(6,(10+8*12),&i);
                display_string_8x16(6,(10+8*13),"V");
                //delay_ms(50);//延时50ms
        }
}
//========================================================================
// 函数: void ADC_int(void) interrupt ADC_VECTOR
// 描述: ADC中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2012-10-22
//========================================================================
void ADC_int (void) interrupt ADC_VECTOR
{       
                                //long controlOutput1=0;
                                ADC_CONTR &= ~ADC_FLAG;//清标志位
                                j = (u16)(ADC_RES & 3);//读出AD值
                                j = (j << 8) | ADC_RESL;
                               
                 if((j<200)&&(j>37))
                        {                       
                                         
                                                pid(referenceInput,j);       
                                               
                                          pwm0=controlOutput>>15;//Q15格式还原
                              if (pwm0>150)pwm0=150;                //设定上限值                     
                 }
                else
                 {
                                                controlOutput=0;
                                                pwm0=0;
                 }
               
                if(pwm0==0)
                {
                                               
                                    PWM0_OUT_0();//PWM的值为0
                                    pwm0=1;                                                       
          }
                else
                PWM0_NORMAL();
                UpdatePwm(0,256-pwm0);//更新PWM的值,pwm0为低电平的值,最大255,最小0
                ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | 0;        //每次AD中断完都要启动一次AD转换来进行下一下中断       
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-9-3 07:12:37 | 显示全部楼层
先来个基本介绍吧
回复 支持 反对

使用道具 举报

发表于 2014-9-3 08:40:15 | 显示全部楼层
以后板子会不会开源啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-3 12:21:55 | 显示全部楼层
白菜虫虫 发表于 2014-9-3 08:40
以后板子会不会开源啊

STCunio,即system on chip unusual i/o,采用类似arduino构架设计,即使没有单片机知识的设计师和艺术家们能够很快地通过它学习电子和传感器的基础知识,并应用到他们的设计当中。设计中所要表现的想法和创意才是最主要的,至于单片机如何工作,设计师和艺术家们并不需要考虑。有单片机基础的工程师在使用STCuino的时候就会发现,STCuino已经脱离了单片机的概念,完全是一个具有功能强大的IO口电路,使用起来非常简单。当然不乏有很多工程师会认为学习arduino会有很多局限性,使用范围受限,所以arduino也并没有受到工程师们的青睐。STCunio继承了arduino的特点,函数库是开源的。当大家很想学习单片机本身和硬件电路,可以把它当作是普通的demo板, 我们还提供这类的套件,这些套件与市面上的学习板有所不同,入门简单并且可以学习到设计的精髓,达到真正授人予渔的目的。

本产品采用STC新推出的单片机为核心,为响应众多的开发者和学生的要求,尤其是非电子专业的爱好者,STCunio开发团队设计出一款类似arduino uno的学习板,取名为STCunio R1, STCunio R1引脚排列兼容arduino官方学习板,代码开源,并且供电兼容3.3V和5V。
STCunio R1具有一下特点:
1.        STCunio R1具备自动下载功能
不像其他学习板那样需要用一个带自锁的开关来软启动才能下载程序,软启动即将MCU停电再将其上电。如果我们在调试程序当中若采用这种软启动方式下载程序会觉得有点麻烦了。还有一种市面上采用继电器的方式来控制MCU的VCC来实现软启动,这是当ISP发送下载序列时,串口的DTS发一个跳变的信号,通过捕捉这个信号来控制继电器,这种方法也是有弊端的,假如我们通过串口助手发送一个数据给单片机,那么继电器同样会动作,这样并不是我们所希望的。那么STCunio R1自动下载的原理到时是什么呢?
其实原理非常简单,将串口设置为8位数据、中断模式,当ISP下载程序时会有个下载序列,其实是很多个0x7f,当MCU接收0x7f至少16次以上时,这时MCU认为是下载命令,将寄存器IAP_CONTR赋值0X60,那么系统就会跳到ISP监控程序区,这个区是STC厂家做的固件,MCU软启动之后也会进入这个区检测下载流,之后才会进入用户代码区。当然这是要编写一点简单的代码,代码已经编写好在USART1.c中,这个代码我们称之为bootloader,在每次下载程序的时候都把bootloader加到程序中即可,此外我们要在main()函数中加“Serialbegin(2400);”,操作简单吧。
有两点需要注意的:
○1ISP界面有“最低波特率”,当我们每次打开ISP时最低波特率默认是2400,如果要选择更高的波特率,比如115200,那么我们只需要在Serialbegin ()函数中修改的参数改成115200。
○2系统时钟的设置,当我们使用不同的系统时钟只需在config.h中设置MAIN_Fosc,这个是由宏来定义的。
以上两点如果没有设置对,那么就实现不了自动下载。学习板上既然没有自锁开关,那MCU怎么来软启动呢?这里我们也有考虑到,做了一个电子开关来控制MCU的VCC,电子开关由一个轻触按键来控制,这种实现软启动的方法也比用自锁开关开发方便,只需轻轻一按就可以实现软启动。
2.        C语言程序开发,没有C语言基础的学者也不用担心,只要稍微学习一下就会用了。
3.        STCunio是开源的,并且大家可以在库函数里进行修改、升级。
回复 支持 反对

使用道具 举报

发表于 2014-9-3 16:52:52 | 显示全部楼层
拭目以待了
回复 支持 反对

使用道具 举报

发表于 2014-9-4 12:34:27 | 显示全部楼层
其实大家关心的是兼容性如何?
如果只是个新的平台 那么要么兼容性很好,要么性能很好,要么功能丰富
否则还是难搞下去
ARDUINO之类的平台优势在于用的人多 研究的多了 开源的部分多 起步入门相对简单 。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-4 14:47:28 | 显示全部楼层
darkorigin 发表于 2014-9-4 12:34
其实大家关心的是兼容性如何?
如果只是个新的平台 那么要么兼容性很好,要么性能很好,要么功能丰富
否则 ...

STCunio代码开源,IO口兼容arduino UNO,做的库都和ardunio差不多,STCunio的开发环境是keil,支持软件仿真和硬件仿真,这对入门和开发者调试程序非常有用,STCunio第2代产品将会有PWM死区设置,玩智能小车的人不用再担心驱动发烫,程序也可简化。STCunio还加强了自动控制的功能,AD采样速率、PWM的开关频率都可以自己设置,并且可以使用AD中断。
回复 支持 反对

使用道具 举报

发表于 2014-9-4 23:58:29 | 显示全部楼层
STCunio 发表于 2014-9-4 14:47
STCunio代码开源,IO口兼容arduino UNO,做的库都和ardunio差不多,STCunio的开发环境是keil,支持软件仿 ...

恩看起来还不错
你这个教程我仔细看看先先
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-19 18:25:52 | 显示全部楼层
本帖最后由 STCunio 于 2014-9-19 23:58 编辑

原来还可以再编辑
回复 支持 反对

使用道具 举报

发表于 2014-9-21 21:28:26 | 显示全部楼层
代码好复杂。
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-18 22:07 , Processed in 0.045400 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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