• 温控的具体实现:二


    好了,既然确认温度应该由Pt_100采集出来的电压平均值来表示,那么为了实现功能且便于PID调试,那么我们就应该想办法由UART口采集出陶瓷加热片的电压(平均值)。

    1:设置输出为占空比为0.4的PWM波,然后验证这些。

    通过翻看User's guide,我们可以发现CCRx和CCR0一样,也可以产生中断。那么尝试着写如下代码(只粘贴重要的部分):

    volatile unsigned Point_1,Point_2;
    double Point_now ;
    double temperature_now;

    #pragma vector=TIMER1_A1_VECTOR
    __interrupt void TIMER1_A1_ISR(void)

    {

    switch(__even_in_range(TA1IV,14))

    {

    case 0: break; // No interrupt
    case 2: break; // CCR1 not used
    case 4: ADC12CTL0 |= ADC12SC; //开启ADC转换  
               break; 
    case 6: break; // reserved
    case 8: break; // reserved
    case 10: break; // reserved
    case 12: break; // reserved
    case 14: break; // overflow
    default: break;

    }
    __bis_SR_register(LPM0_bits + GIE);
    __no_operation();

    }

    #pragma vector=TIMER1_A0_VECTOR
    __interrupt void TIMER1_A0_ISR(void)

    {

    P11OUT ^= 0x01; // Toggle触发 P11.0

    temperature_now = Point_now/11.521; //现在的温度
    while (!(UCA3IFG&UCTXIFG)); //等待BUF区准备好,当IFG=1时就表示准备好了
    UCA3TXBUF = (int)((temperature_now/100)+48); //向串口发送数据 发送温度数据的第一位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%100)/10+48); //向串口发送数据 发送温度数据的第二位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%10)+48); //向串口发送数据 发送温度数据的第三位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = 46; //发送记录分隔符(小数点)
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)((temperature_now-(int)temperature_now)*10+48); //向串口发送数据 发送温度数据小数点后一位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = ' '; //发送回车符


    ADC12CTL0 |= ADC12SC;
    __bis_SR_register(LPM0_bits + GIE);
    __no_operation();

    }

    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)

    {
    switch(__even_in_range(ADC12IV,34))

    {
    case 0: break; // Vector 0: No interrupt
    case 2: break; // Vector 2: ADC overflow
    case 4: break; // Vector 4: ADC timing overflow
    case 6: break; // Vector 6: ADC12IFG0
    case 8: // Vector 8: ADC12IFG1
    Point_2 = Point_1; // Move result, IFG置0
    Point_1 = ADC12MEM1;
    Point_now = 0.6 * Point_1 + 0.4 * Point_2;
    break;
    case 10: break; // Vector 10: ADC12IFG2
    case 12: break; // Vector 12: ADC12IFG3
    case 14: break; // Vector 14: ADC12IFG4
    case 16: break; // Vector 16: ADC12IFG5
    case 18: break; // Vector 18: ADC12IFG6
    case 20: break; // Vector 20: ADC12IFG7
    case 22: break; // Vector 22: ADC12IFG8
    case 24: break; // Vector 24: ADC12IFG9
    case 26: break; // Vector 26: ADC12IFG10
    case 28: break; // Vector 28: ADC12IFG11
    case 30: break; // Vector 30: ADC12IFG12
    case 32: break; // Vector 32: ADC12IFG13
    case 34: break; // Vector 34: ADC12IFG14

    default: break;
    }


    __no_operation();

    }

    这段代码的意思是计数器计算到CCR2时,进入中断,开始AD转换。将转换值送给Point_1;然后计数器计算到CCR0时,进入中断,首先计算平均值Point_now,然后开始AD转换将转换值存为Point_1,将以前的值保存到Point_2。

    所以可以得知,进入CCR0中断时,Point_now = 0.6 * Point_1 + 0.4 * Point_2;(因为占空比设置为0.4)

    将Point_now的值对应的温度通过串口调试助手发射出去。

    得到的温度结果为:

    所以得到的温度约为129.9℃。

    同时,我们可以采集出电压最小值对应的温度值,代码为:

    #pragma vector=TIMER1_A1_VECTOR
    __interrupt void TIMER1_A1_ISR(void)

    {

    P11OUT ^= 0x01; // Toggle触发 P11.0

    temperature_now = Point_now/11.521; //现在的温度
    while (!(UCA3IFG&UCTXIFG)); //等待BUF区准备好,当IFG=1时就表示准备好了
    UCA3TXBUF = (int)((temperature_now/100)+48); //向串口发送数据 发送温度数据的第一位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%100)/10+48); //向串口发送数据 发送温度数据的第二位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%10)+48); //向串口发送数据 发送温度数据的第三位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = 46; //发送记录分隔符(小数点)
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)((temperature_now-(int)temperature_now)*10+48); //向串口发送数据 发送温度数据小数点后一位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = ' '; //发送回车符
    switch(__even_in_range(TA1IV,14))

    {

    case 0: break; // No interrupt
    case 2: break; // CCR1 not used
    case 4: ADC12CTL0 |= ADC12SC; //开启ADC转换
    break; // CCR2 not used
    case 6: break; // reserved
    case 8: break; // reserved
    case 10: break; // reserved
    case 12: break; // reserved
    case 14: break; // overflow
    default: break;

    }
    __bis_SR_register(LPM0_bits + GIE);
    __no_operation();

    }

    得到的温度结果为:

    所以约为120℃。

    采集出电压最大值对应的温度,代码为:

    #pragma vector=TIMER1_A0_VECTOR
    __interrupt void TIMER1_A0_ISR(void)

    {

    P11OUT ^= 0x01; // Toggle触发 P11.0

    temperature_now = Point_now/11.521; //现在的温度
    while (!(UCA3IFG&UCTXIFG)); //等待BUF区准备好,当IFG=1时就表示准备好了
    UCA3TXBUF = (int)((temperature_now/100)+48); //向串口发送数据 发送温度数据的第一位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%100)/10+48); //向串口发送数据 发送温度数据的第二位
    while (!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)(((int)temperature_now%10)+48); //向串口发送数据 发送温度数据的第三位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = 46; //发送记录分隔符(小数点)
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF =(int)((temperature_now-(int)temperature_now)*10+48); //向串口发送数据 发送温度数据小数点后一位
    while(!(UCA3IFG&UCTXIFG));
    UCA3TXBUF = ' '; //发送回车符


    ADC12CTL0 |= ADC12SC;
    __bis_SR_register(LPM0_bits + GIE);
    __no_operation();

    }

    采集到的温度数据为

    约为146.7℃。

    由146.7*0.4+120*0.6=130.76

    而程序采集出的温度为120.9

    所以,排除各个阶段温度不稳定所造成的误差,可以认为此程序得到了平均电压所对应的平均温度。

  • 相关阅读:
    Oracle之表空间
    Oracle 数据库实现数据更新:update、merge
    union和union all用法
    SQL Server 使用游标更新数据库中的数据(使用存储过程)
    MDX函数(官方顺序,带示例)
    开窗函数 --over()
    MySql安装与MySQL添加用户、删除用户与授权
    samba服务
    asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序
    asp.net core系列 57 IS4 使用混合流(OIDC+OAuth2.0)添加API访问
  • 原文地址:https://www.cnblogs.com/qifengle/p/5138145.html
Copyright © 2020-2023  润新知