基于TI F280049C设计智能温度调节展示系统
该项目使用了Code Composer Studio软件,c语言,实现了一个TI F280049C系统板和扩展版的设计,它的主要功能为:基于TI F280049C,硬禾学堂数字系统的输入、输出扩展板作为外设,完成智能温度调节展示。。
标签
嵌入式系统
温度调节
2024寒假在家练
TI F280049C
Yoyoy
更新2024-03-28
南昌大学
261

任务要求

设计一个基于温度变化的展示系统

温度传感器检测温度变化

彩色LCD显示当前温度和设定阈值

LED根据温度高低展示不同颜色

按键用于设置温度阈值

旋转编码器调节LED显示的模式和控制参数。


一、环境配置

1.下载并安装CCS

我们编写TI F280049C的程序,需要用到CCS这个软件。我们进入官网之后,下载CCS并安装即可。


2.导入F280049CWare(例程)

下载C2000ware,下载好后在CCS软件里,上方的project里import project,找到C2000ware,打开drivelib,选择f28004x导入即可。


关于TI F280049C:

LAUNCHXL-F280049C 是一款适用于 TI C2000™ 实时控制器系列 F28004x 器件的低成本开发板。该器件不仅适用于初始评估和原型设计,还提供易于使用的标准化平台,用于开发下一个应用。该扩展版本 LaunchPad 可提供额外引脚用于开发,并支持连接两个 BoosterPack。作为庞大的 TI MCU LaunchPad 生态系统的一部分,该器件还与各种插件交叉兼容,包含 InstaSPIN-FOC 功能。


关于扩展板:



扩展板包含按键、旋转编码器输入、双电位计控制输入、RGB三色LED显示1.44寸128*128 LCD,SPI总线访问、MMA7660三轴姿态传感器、电阻加热、温度传感器、与MSP430 Launch Pad开发板的接口等部分组成。


二、程序实现:

程序均用C语言编写。


思路流程图:


1、模块介绍:

扩展板上的显示屏用的是st7735,将中景园st7735的例程移植到TI F280049C中

//需要添加的头文件
#include "lcd.h"
#include "lcd_init.h"
#include "lcdfont.h"

//在"lcd_init.h"中更改引脚配置
#define GPIO_LCD_PIN_SCL 0
#define GPIO_LCD_PIN_SDA 4
#define GPIO_LCD_PIN_RES 3
#define GPIO_LCD_PIN_DC 1
#define GPIO_LCD_PIN_CS 5


#define LCD_SCLK_Clr() GPIO_writePin(GPIO_LCD_PIN_SCL, 0); //SCL=SCLK
#define LCD_SCLK_Set() GPIO_writePin(GPIO_LCD_PIN_SCL, 1);

#define LCD_MOSI_Clr() GPIO_writePin(GPIO_LCD_PIN_SDA, 0);//SDA=MOSI
#define LCD_MOSI_Set() GPIO_writePin(GPIO_LCD_PIN_SDA, 1);

#define LCD_RES_Clr() GPIO_writePin(GPIO_LCD_PIN_RES, 0);//RES
#define LCD_RES_Set() GPIO_writePin(GPIO_LCD_PIN_RES, 1);

#define LCD_DC_Clr() GPIO_writePin(GPIO_LCD_PIN_DC, 0);//DC
#define LCD_DC_Set() GPIO_writePin(GPIO_LCD_PIN_DC, 1);

#define LCD_CS_Clr() GPIO_writePin(GPIO_LCD_PIN_CS, 0);//CS
#define LCD_CS_Set() GPIO_writePin(GPIO_LCD_PIN_CS, 1);

//最后需要删除一些中文字符,占用过多。

旋转编码器和按键通过读取adc值,观察adc值的变化来判断对应的操作。

控制IO口高低电平来加热电阻,NST112温度传感器读取温度变化。

NST112移植例程


#include "driverlib.h"
#include "device.h"
#include "mygpio.h"
#include "NST112.h"



void I2C_Init(void)
{
SDA_H;
SCL_H;
}

void I2C_delay(char n)
{
uint32_t i;
for ( i = 0; i < n; ++i)
{for(i=0; i<50; ++i);}
}

void I2C_start(void)
{
SDA_OUT;

SCL_H;
SDA_H;
I2C_delay(5);
SDA_L;
I2C_delay(6);
SCL_L;
}

void I2C_stop(void)
{
SCL_L;
SDA_L;
SCL_H;
I2C_delay(6);
SDA_H;
I2C_delay(6);
}

void I2C_ack(void) {
SCL_L;
SDA_OUT;
SDA_L;
I2C_delay(2);
SCL_H;
I2C_delay(5);
SCL_L;
}

void I2C_nack(void) {
SCL_L;
SDA_OUT;
SDA_H;
I2C_delay(2);
SCL_H;
I2C_delay(5);
SCL_L;

}

unsigned char I2C_waitAck(void)
{
unsigned char tempTime;

SDA_IN;

SDA_H;
I2C_delay(1);
SCL_H;
I2C_delay(1);

while(GPIO_readPin(GPIO_PIN_I2C_SDA))
{
tempTime++;
I2C_delay(1);
if(tempTime>250)
{
I2C_stop();
return 1;
}
}

SCL_L;
I2C_delay(1);

return 0;
}

void I2C_SendByte(unsigned char byte)
{
unsigned char i = 0;

SDA_OUT;
SCL_L; //在SCL低电平期间改变数据线高低电平的状态
for(i = 0; i < 8; i++)
{
if(byte & 0x80)
{
SDA_H;
}
else
{
SDA_L;
}
byte <<= 1;
I2C_delay(1);
SCL_H;
I2C_delay(2);
SCL_L;
I2C_delay(2);
}

}

unsigned char I2C_ReadByte(unsigned char ack)
{
unsigned char i = 0, receive = 0;

SDA_IN;

for(i = 0; i < 8; i++)
{
SCL_L;
I2C_delay(2);
SCL_H;
receive <<= 1;
if(GPIO_readPin(GPIO_PIN_I2C_SDA))
{receive++;}

I2C_delay(1);
}
if(ack == 0)

I2C_nack();
else
I2C_ack();
SDA_H;

return receive;

}

float GX112_read_result1(unsigned char addr)
{
short tem,hum;
unsigned char buff[6];
int Temp;
float Temperature = 0;

I2C_start();
I2C_SendByte(addr << 1 | write); //写7位I2C设备地址加0作为写取位,1为读取位
I2C_waitAck();
I2C_SendByte(0x00);
I2C_waitAck();

I2C_delay(20);

I2C_start();
I2C_SendByte(addr << 1 | read); //写7位I2C设备地址加0作为写取位,1为读取位
if(I2C_waitAck() == 0)
{
buff[0] = I2C_ReadByte(1);
buff[1] = I2C_ReadByte(0);

I2C_stop();

}
else
{
buff[0] = 0;
buff[1] = 0;
I2C_stop();
}

if(buff[0] & 0x80)
{
tem = (buff[0] << 8) | buff[1] ;
hum = (((~tem) >> 4) + 1) & 0x0fff;
Temperature = -(float)(hum * 0.0625);
}
else
{
Temp = (buff[0] << 8) | buff[1] ;
Temp >>=4;
Temperature = (float)(Temp * 0.0625);
}

tem = 0;
hum = 0;


return Temperature;
}

2、实现功能:


定义IO口引脚控制电阻加热开关和LED



#define GPIO_PIN_V_HEAT 8
#define GPIO_PIN_LED_BLUE 6
#define GPIO_PIN_LED_GREEN 7
#define GPIO_PIN_LED_RED 2

#define V_HEAT_ON GPIO_writePin(GPIO_PIN_V_HEAT, 1);
#define V_HEAT_OFF GPIO_writePin(GPIO_PIN_V_HEAT, 0);

#define LED_BLUE_ON GPIO_writePin(GPIO_PIN_LED_BLUE, 0);
#define LED_BLUE_OFF GPIO_writePin(GPIO_PIN_LED_BLUE, 1);

#define LED_GREEN_ON GPIO_writePin(GPIO_PIN_LED_GREEN, 0);
#define LED_GREEN_OFF GPIO_writePin(GPIO_PIN_LED_GREEN, 1);

#define LED_RED_ON GPIO_writePin(GPIO_PIN_LED_RED, 0);
#define LED_RED_OFF GPIO_writePin(GPIO_PIN_LED_RED, 1);

void MYGPIO_Init()
{
GPIO_setPadConfig(8, GPIO_PIN_V_HEAT);
GPIO_setDirectionMode(8, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(6, GPIO_PIN_LED_BLUE);
GPIO_setDirectionMode(6, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(7, GPIO_PIN_LED_GREEN);
GPIO_setDirectionMode(7, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(2, GPIO_PIN_LED_RED);
GPIO_setDirectionMode(2, GPIO_DIR_MODE_OUT);

LED_BLUE_OFF;
LED_GREEN_OFF;
LED_RED_OFF;
}


LCD显示功能,显示设定的温度值和NST112实时读取的温度值,以及控制加热到目标温度的开关。



void Show_LCD()
{


LCD_ShowString(0,48,"Switch:",WHITE,BLACK,16,0);
if(key_On_Off==0)
{LCD_ShowString(56,48,"OFF",WHITE,BLACK,16,0);}
else
{LCD_ShowString(56,48,"ON ",WHITE,BLACK,16,0);}

if(key_On_Off==0)
{
switch(site)
{
case 0:LCD_ShowIntNum(32,0,num[0],1,WHITE,RED,16);
LCD_ShowIntNum(40,0,num[1],1,WHITE,BLACK,16);
LCD_ShowIntNum(54,0,num[2],1,WHITE,BLACK,16);
LCD_ShowIntNum(62,0,num[3],1,WHITE,BLACK,16);break;
case 1:LCD_ShowIntNum(32,0,num[0],1,WHITE,BLACK,16);
LCD_ShowIntNum(40,0,num[1],1,WHITE,RED,16);
LCD_ShowIntNum(54,0,num[2],1,WHITE,BLACK,16);
LCD_ShowIntNum(62,0,num[3],1,WHITE,BLACK,16);break;
case 2:LCD_ShowIntNum(32,0,num[0],1,WHITE,BLACK,16);
LCD_ShowIntNum(40,0,num[1],1,WHITE,BLACK,16);
LCD_ShowIntNum(54,0,num[2],1,WHITE,RED,16);
LCD_ShowIntNum(62,0,num[3],1,WHITE,BLACK,16);break;
case 3:LCD_ShowIntNum(32,0,num[0],1,WHITE,BLACK,16);
LCD_ShowIntNum(40,0,num[1],1,WHITE,BLACK,16);
LCD_ShowIntNum(54,0,num[2],1,WHITE,BLACK,16);
LCD_ShowIntNum(62,0,num[3],1,WHITE,RED,16);break;
}
}
else{
LCD_ShowIntNum(32,0,num[0],1,WHITE,BLACK,16);
LCD_ShowIntNum(40,0,num[1],1,WHITE,BLACK,16);
LCD_ShowIntNum(54,0,num[2],1,WHITE,BLACK,16);
LCD_ShowIntNum(62,0,num[3],1,WHITE,BLACK,16);
}

LCD_ShowString(0,24,"Temp:",WHITE,BLACK,16,0);
LCD_ShowIntNum(40,24,Temp_int,2,WHITE,BLACK,16);
LCD_ShowFloatNum1(56,24,Temp_dec,2,WHITE,BLACK,16);

if(pid_result>=0)
{
LCD_ShowString(8,80,"+",WHITE,BLACK,16,0);
LCD_ShowIntNum(24,80,pid_result,2,WHITE,BLACK,16);
}

else
{
LCD_ShowString(8,80,"-",WHITE,BLACK,16,0);
LCD_ShowIntNum(24,80,-pid_result,2,WHITE,BLACK,16);
}

LCD_ShowIntNum(80,80,PWM,2,WHITE,BLACK,16);
LCD_ShowIntNum(80,100,time,2,WHITE,BLACK,16);
}

设置温度,定义数组和位置

char num[4]={4,0,0,0};
char loc[4]={32,40,54,62};

数值逻辑


#include "driverlib.h"
#include "device.h"
#include "ShowTemper.h"



extern unsigned char count,key_move,key_On_Off,site;
extern char num[4];



void Set_Temper()
{

if(key_On_Off==0)
{
if(key_move==1)
{
site++;
if(site>3){site=0;}
key_move=0;
count=0;
}

if(count==1)
{
num[site]--;
count=0;
if(num[site]<0)
{
if(site==1)
{num[site-1]--;
if(num[site-1]<0)
{num[site-1]=9;}
}

if(site==2)
{num[site-1]--;
if(num[site-1]<0)
{num[site-1]=9;
num[site-2]--;
if(num[site-2]<0)
{num[site-2]=9;}}
}

if(site==3)
{num[site-1]--;
if(num[site-1]<0)
{num[site-1]=9;
num[site-2]--;
if(num[site-2]<0)
{num[site-2]=9;
num[site-3]--;
if(num[site-3]<0)
{num[site-3]=9;}}}
}
num[site]=9;
}
}

if(count==2)
{
num[site]++;
count=0;
if(num[site]>9)
{
if(site==1)
{num[site-1]++;
if(num[site-1]>9)
{num[site-1]=0;}
}

if(site==2)
{num[site-1]++;
if(num[site-1]>9)
{num[site-1]=0;
num[site-2]++;
if(num[site-2]>9)
{num[site-2]=0;}}
}

if(site==3)
{num[site-1]++;
if(num[site-1]>9)
{num[site-1]=0;
num[site-2]++;
if(num[site-2]>9)
{num[site-2]=0;
num[site-3]++;
if(num[site-3]>9)
{num[site-3]=0;}}}
}
num[site]=0;
}
}

}
}



adc值和温度的获取,判断旋转编码器左转和右转以及编码器按键按下和普通按键按下时的adc值。


void ADC_Temp_scan()
{
adc_value=0;
ADC_forceSOC(myADC0_BASE, ADC_SOC_NUMBER1);
adc_value=ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
if(adc_value<1500)
{key_move=1;}//按键按下
if(2800<adc_value&&adc_value<2900)
{count=1;}//减
if(2900<adc_value&&adc_value<3000)
{count=2;}//加
if(2000<adc_value&&adc_value<2700)
{key_On_Off^=1;}//按键按下

Temp_int=GX112_read_result1(NST112_ADDRESS); //温度读取
Temp_dec=GX112_read_result1(NST112_ADDRESS);
}

adc配置用的是sysconfig,根据例程的adc中的sysconfig配置即可


计时功能用的是CPU定时器,预分配系数100,重装载值100,系统时钟频率100M,定时器频率100us。


void myCPUTIMER0_init(){

CPUTimer_setEmulationMode(myCPUTIMER0_BASE, CPUTIMER_EMULATIONMODE_RUNFREE);
CPUTimer_setPreScaler(myCPUTIMER0_BASE, 99U);
CPUTimer_setPeriod(myCPUTIMER0_BASE, 99U);
CPUTimer_enableInterrupt(myCPUTIMER0_BASE);
CPUTimer_stopTimer(myCPUTIMER0_BASE);

CPUTimer_reloadTimerCounter(myCPUTIMER0_BASE);
CPUTimer_startTimer(myCPUTIMER0_BASE);

Interrupt_register(INT_myCPUTIMER0, &INT_myCPUTIMER0_ISR);
Interrupt_enable(INT_myCPUTIMER0);
}

__interrupt void INT_myCPUTIMER0_ISR(void)
{
time++;
time_pid++;

PWM_time=PWM;
if(time>1000)
{
time=0;
}


if(time_pid>100)
{
time_pid=0;

}

}


最后用pid来控制加热的时间,以此来接近目标温度



#include "driverlib.h"
#include "device.h"
#include "key.h"
#include "mygpio.h"

float kp=1.2,ki=1.05,kd=1.85;//三个系数
float p,i,d;
float error,lastError;//误差、上次误差


float PID_Count(float reference,float feedback)//目标值,反馈值
{
float pid_result;

lastError=error;
error=reference-feedback;
//计算微分,减去振荡
d=(error-lastError)*kd;
//计算比例,向目标值靠近
p=error*kp;
//计算积分,克服稳定误差
i+=error*ki;

pid_result=p+d;

return pid_result;
}

void PID_Temp_get()
{
float reference,feedback;

reference=num[0]*10+num[1]+num[2]*1.0/10+num[3]*1.0/100;
feedback=GX112_read_result1(NST112_ADDRESS);

pid_result=PID_Count(reference,feedback);

if(pid_result>10)
{
pid_result=10;
}

if(pid_result<-10)
{
pid_result=-10;
}

PWM=18+pid_result*5;
if(PWM<0)PWM=0;

}


三、项目经验总结

第一次用TI的板子和CCS这个软件,有很多不熟悉的地方,需要一步一步去摸索,很多功能不会使用,导致完成这个任务的过程中有许多困难的地方。

通过这次寒假练也学习到了很多东西,对TI板的一些认识和CCS的使用方法,以及之前学习的时候不够清晰认知的地方加深了记忆,比如移植例程的方法和技巧。


附件下载
temp_data_collection.zip
团队介绍
南昌大学
团队成员
吴骁与
南昌大学 2022级 先进制造学院 测控技术与仪器专业
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号