2024年寒假练 - 基于Ti-F280049c实现智能温度调节展示系统
该项目使用了LAUNCHXL-F280049C,实现了智能温度调节展示系统的设计,它的主要功能为:温度传感器检测温度变化,彩色LCD显示当前温度和设定阈值。LED根据温度高低展示不同颜色。按键用于设置温度阈值,摇杆调节LED显示的模式和控制参数。。
标签
嵌入式系统
lihuahua
更新2024-03-27
南京理工大学
502

1、项目功能介绍

设计了一个基于温度变化的展示系统。该系统包含等TMS320F280049C开发套件、硬禾学堂定制扩展版(本项目利用到了温度传感器、LCD屏幕、按键、摇杆)、排针和排线若干。

本展示系统主要实现以下功能:通过温度传感器检测温度变化,利用彩色LCD显示当前温度和阈值。通过按键设置温度阈值,摇杆调节LED显示的模式和控制参数。LED根据温度高低展示不同颜色。

 

2、设计思路

F280049通过IIC接口读取温度传感器数据,通过SPI接口驱动LCD屏幕,通过pwm引脚驱动三色led,通过adc引脚读取按键的动作,通过ECAP功能读取摇杆电路输出的pwm波形。

 

3、硬件框图

4、软件流程图

image.png

主函数中首先对280049c的各外设进行配置,然后进入死循环,判断1s、50ms标志位,进行相应操作:若1s定时到,则翻转LED状态、通过IIC读取温度值、LED根据温度高低展示不同颜色;若50ms定时到,则读取按键、摇杆值、更新菜单显示。

定时器中断服务函数中:若1s定时到,则置1s时间标志位;若50ms定时到,则置50ms时间标志位。

ADC中断服务函数中:判断电压值,然后判断当前按键动作,写入按键循环队列中。

ECAP中断服务函数中:计算方波周期、占空比,然后判断当前摇杆动作,写入摇杆循环队列中。

 


5、简单的硬件介绍:

开发板主控为TMS320F280049C,具有 FPU 和 TMU 的 100MHz C28x CPU、256KB 闪存、支持 InstaSPIN-FOC、3 个 12 位 ADC、CAN、编码器、FSI、UART 等。板载 XDS110 调试探针,用于实时调试和闪存编程。

image.png


扩展板包含如下功能:

按键、旋转编码器输入:当有按键或者旋转编码器动作时,电阻网络会输出不同的电压,通过adc检测模拟信号来判断按键、旋转编码器的动作。

image.png

双电位计控制输入:当摇杆处于中立、上、下、左、右不同位置时,RC震荡电路会输出周期、占空比不同的方波。通过ECAP输入捕获来反向求得摇杆位置。

image.png

RGB三色LED显示:通过GPIO控制灯的颜色。

image.png

1.44寸128*128 LCD:通过SPI总线来驱动st7735。

image.png

电阻加热:当V_HEAT引脚为高电平时,电阻加热;当V_HEAT引脚为低电平时,电阻停止加热。

image.png

数字温度传感器NST112:通过I2C接口配置、读取温度传感器。

image.png

6、实现的功能及图片展示

一级菜单显示“硬禾科技”、“2024寒假在家一起练”logo,点击OK按键进入下一级菜单。

image.png

二级菜单显示当前温度值、温度阈值上限、温度阈值下限,拨动摇杆可以选择设定温度阈值的上限和下限值,点击OK按键进入下一级菜单。

image.png

进入三级菜单后,拨动摇杆可以增加或者减少温度阈值的上限或者下限,点击OK按键返回上一级菜单。

image.png

image.png

7、主要代码片段及说明

7.1 280049c与温度传感器NST112的IIC通信协议:

首先主机280049c向IIC总线写NST112地址1001000,由于先发送高bit位,同时有读写位,所以总线上数据为0x90(10010000b);

然后配置NST112的16位“Configuration register”,地址为0x01;向高字节写入0b01100000,配置连续转换模式,12bit精度;向低字节写入0b11100000,配置温度转换速率为8Hz。

最后结束IIC通信。

image.png

image.png

image.png

主机280049c向IIC总线写NST112地址1001000,然后开始读取NST112的 “Temperature register”,地址为0x00。

image.png

       最后读取温度值,然后拼凑字节。

image.png

float tmepature = 0.0f;
Uint16 tmep_thres_high = 300;//放大10倍
Uint16 tmep_thres_low = 200;//放大10倍

// Function to configure I2CA as Master Transmitter.
void I2CMaster_Init(uint16_t I2C_OwnAddress, uint16_t I2CSlave_Address)
{
//Configure I2C pins
GPIO_SetupPinMux(GPIO_PIN_SDAA, GPIO_MUX_CPU1, 3);
GPIO_SetupPinOptions(GPIO_PIN_SDAA, GPIO_OUTPUT, GPIO_PULLUP);
GPIO_SetupPinMux(GPIO_PIN_SCLA, GPIO_MUX_CPU1, 3);
GPIO_SetupPinOptions(GPIO_PIN_SCLA, GPIO_OUTPUT, GPIO_PULLUP);

//
// Must put I2C into reset before configuring it
//
I2caRegs.I2CMDR.all &= ~(0x20U);
//
// I2C configuration. Use a 400kHz I2CCLK with a 50% duty cycle.
//
//I2C_initMaster(base, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_50);
I2caRegs.I2CPSC.all = 0xB; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 0x7; // NOTE: must be non zero
I2caRegs.I2CCLKH = 0x8; // NOTE: must be non zero
//
// Configure Master as a Transmitter
//
I2caRegs.I2CMDR.bit.MST = 0x1;
I2caRegs.I2CMDR.bit.TRX = 0x1;
//
// Set data count
//
//I2caRegs.I2CCNT = I2C_NUMBYTES;
//
// Set the bit count to 8 bits per data byte
//
I2caRegs.I2CMDR.bit.BC = 0x0U;
//
// Configure slave and own address
//
I2caRegs.I2COAR.all = I2C_OwnAddress; // Own address
I2caRegs.I2CSAR.all = I2CSlave_Address; // Slave address
//
// Set emulation mode to FREE
//
I2caRegs.I2CMDR.bit.FREE = 0x1;
//
//Clear all status
//
I2caRegs.I2CSTR.all = 0xFFFF;
//
// Enable I2C Interrupts- RRDY
//
I2caRegs.I2CIER.all = 0x08;
//
// Take I2C out of reset
//
I2caRegs.I2CMDR.all |= 0x0020;
}

//
// Function to send data over I2C.
//
void I2CWrite(uint16_t slaveAddr, uint16_t *I2C_TXdata,uint16_t byteCount, bool sendStopCondition)
{
//
// Wait for I2C bus to clear
//
while(I2caRegs.I2CMDR.bit.STP !=0x0);
while(I2caRegs.I2CSTR.bit.BB !=0x0);
//
// Locals
//
uint16_t index = 0;
//
// Configure slave address
//
I2caRegs.I2CSAR.all = slaveAddr; // Slave address
//
// Configure I2C as Master Transmitter
//
I2caRegs.I2CMDR.bit.MST = 0x1;
I2caRegs.I2CMDR.bit.TRX = 0x1;
//
//Set Data Count
//
I2caRegs.I2CCNT = byteCount;
//
// send Start condition
//
I2caRegs.I2CMDR.bit.STT = 0x1;

//
//transmit the bytes
//
for(index=0; index < byteCount; index++)
{
I2caRegs.I2CDXR.all= I2C_TXdata[index];
//
//wait till byte is sent
//
while(I2caRegs.I2CSTR.bit.BYTESENT != 0x1);
//
//clear the byte sent
//
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
}
//
// Send STOP condition if specified
//
if(sendStopCondition)
{
I2caRegs.I2CMDR.bit.STP = 0x1;
while(I2caRegs.I2CMDR.bit.STP != 0x0);
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
}
}

//
// Function to read data over I2C. Returns the number of bytes read
//
uint16_t I2CRead(uint16_t slaveAddr,uint16_t *I2C_RXdata, uint16_t byteCount, bool sendStopCondition)
{
//
// Wait for I2C bus to clear
//
while(I2caRegs.I2CMDR.bit.STP !=0x0);
while(I2caRegs.I2CSTR.bit.BB !=0x0);
//
// Configure slave address
//
I2caRegs.I2CSAR.all = slaveAddr;
//
// Configure I2C in Master Receiver mode
//
I2caRegs.I2CMDR.bit.MST = 0x1;
I2caRegs.I2CMDR.bit.TRX = 0x0;
//
//Set Data Count
//
I2caRegs.I2CCNT = byteCount;
//
// send Start condition
//
I2caRegs.I2CMDR.bit.STT = 0x1;
uint16_t count = 0;
//
// Read the received data into RX buffer
//
for(count = 0;count < byteCount;count++)
{
while(I2caRegs.I2CSTR.bit.RRDY ==0);
I2C_RXdata[count++] = I2caRegs.I2CDRR.all;
}
//
// Send STOP condition
//
if(sendStopCondition)
{
I2caRegs.I2CMDR.bit.STP = 0x1;
while(I2caRegs.I2CMDR.bit.STP != 0x0);
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
}
return count;
}

void Writetonst112(void){
uint16_t I2C_TXdata[3];
I2C_TXdata[0]=SET_ADDR; //进入设置寄存器
I2C_TXdata[1]=CFG_CMD_0; //写寄存器1
I2C_TXdata[2]=CFG_CMD_1 ;//写寄存器2
I2CWrite(NST112_ADDRESS, I2C_TXdata,3,true);
}

//读出字符串

float Readfromnst112(void)
{
uint16_t value;
float temp;
uint16_t I2C_TXdata[1];
uint16_t I2C_RXdata[2];
I2C_TXdata[0]=GET_ADDR;
I2CWrite(NST112_ADDRESS,I2C_TXdata, 1,true);//进入温度寄存器,然后结束总线
I2CRead(NST112_ADDRESS,I2C_RXdata,2,true);
value = ((I2C_RXdata[0]<<8)|I2C_RXdata[1]) >>4;
temp = ((float)value)*VAL_BASE;
return temp ;
}

7.2 280049c与ZJY144SN005-st7735 128x128lcd的spi通信协议:

采用gpio模拟spi时序,移植中景圆官方提供的函数,注意lcd_init.c文件中的函数“LCD_Writ_Bus”需要添加延时,否则gpio无法模拟时钟信号。

image.png

image.png

void LCD_GPIO_Init(void)
{
EALLOW;

//res-
GPIO_SetupPinMux(LCD_PIN_RESn, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LCD_PIN_RESn, GPIO_OUTPUT, GPIO_PUSHPULL);

//dc
GPIO_SetupPinMux(LCD_PIN_DCx, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LCD_PIN_DCx, GPIO_OUTPUT, GPIO_PUSHPULL);

//cs
GPIO_SetupPinMux(LCD_PIN_CSn, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LCD_PIN_CSn, GPIO_OUTPUT, GPIO_PUSHPULL);

//clk
GPIO_SetupPinMux(LCD_PIN_SCL, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LCD_PIN_SCL, GPIO_OUTPUT, GPIO_PUSHPULL);

//mosi
GPIO_SetupPinMux(LCD_PIN_SDA, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(LCD_PIN_SDA, GPIO_OUTPUT, GPIO_PUSHPULL);

EDIS;
}
void delay(uint16_t t){
while(t--);
}
/******************************************************************************
函数说明:LCD串行数据写入函数
入口数据:dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{
u8 i;
LCD_CS_Clr();
for(i=0;i<8;i++)
{
LCD_SCLK_Clr();
if(dat&0x80)
{
LCD_MOSI_Set();
}
else
{
LCD_MOSI_Clr();
}
LCD_SCLK_Set();
delay(5);
dat<<=1;
}
LCD_CS_Set();
}


/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{
LCD_Writ_Bus(dat);
}


/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA(u16 dat)
{
LCD_Writ_Bus(dat>>8);
LCD_Writ_Bus(dat);
}


/******************************************************************************
函数说明:LCD写入命令
入口数据:dat 写入的命令
返回值: 无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{
LCD_DC_Clr();//写命令
LCD_Writ_Bus(dat);
LCD_DC_Set();//写数据
}


/******************************************************************************
函数说明:设置起始和结束地址
入口数据:x1,x2 设置列的起始和结束地址
y1,y2 设置行的起始和结束地址
返回值: 无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
if(USE_HORIZONTAL==0)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1+2);
LCD_WR_DATA(x2+2);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1+1);
LCD_WR_DATA(y2+1);
LCD_WR_REG(0x2c);//储存器写
}
else if(USE_HORIZONTAL==1)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1+2);
LCD_WR_DATA(x2+2);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1+3);
LCD_WR_DATA(y2+3);
LCD_WR_REG(0x2c);//储存器写
}
else if(USE_HORIZONTAL==2)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1+1);
LCD_WR_DATA(x2+1);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1+2);
LCD_WR_DATA(y2+2);
LCD_WR_REG(0x2c);//储存器写
}
else
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1+3);
LCD_WR_DATA(x2+3);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1+2);
LCD_WR_DATA(y2+2);
LCD_WR_REG(0x2c);//储存器写
}
}


7.3 280049c通过ECAP外设读取摇杆(电位计)电路输出pwm信号的周期和占空比:

摇杆中立位置:

image.png

摇杆上位置:

image.png

摇杆下位置:

image.png

摇杆位置左:

image.png

摇杆位置右:

image.png

//ECAP初始化配置
void CAP_int(void)
{
/*GPIO配置*/
EALLOW;
InputXbarRegs.INPUT1SELECT = 6; //使用INPUT1--GPIO6引脚
GpioCtrlRegs.GPADIR.bit.GPIO6 = 0; //配置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO6 = 1; //配置为上拉
GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 0; //同步采样,与系统时钟同步
EDIS;

/*初始化配置*/
EALLOW;

ECap1Regs.ECCTL0.bit.INPUTSEL = 0; //ECap1捕获引脚对应到INTPUT1

ECap1Regs.ECCTL1.bit.CAP1POL = 0; //第一次捕获事件发生在上升沿
ECap1Regs.ECCTL1.bit.CAP2POL = 1; //第二次捕获事件发生在下降沿
ECap1Regs.ECCTL1.bit.CAP3POL = 0; //第三次捕获事件发生在上升沿
ECap1Regs.ECCTL1.bit.CAP4POL = 1; //第四次捕获事件发生在下降沿

ECap1Regs.ECCTL1.bit.CTRRST1 = 1; //第一次捕获事件清空计数器
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; //第二次捕获事件不清空计数器
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; //第三次捕获事件不清空计数器
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; //第四次捕获事件清空计数器

ECap1Regs.ECCTL1.bit.CAPLDEN = 1; //使能装载
ECap1Regs.ECCTL1.bit.PRESCALE = 0; //输入信号不分频
ECap1Regs.ECCTL2.bit.CAP_APWM = 0; //配置为捕获模式
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; //连续捕获模式
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; //允许计数器启动

ECap1Regs.ECEINT.bit.CEVT3 = 1; // Enable cevt2 interrupt
// 2 events = interrupt
//当eCAP1连续捕获到2次边沿信号时即进入中断
PieVectTable.ECAP1_INT = &ecap1_isr_rocker;

EDIS;

IER |= M_INT4;
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
}

//频率识别函数
__interrupt void ecap1_isr_rocker(void)
{
uint32_t cap2cnt;//防溢出
uint32_t cap3cnt;

static enum ROCKER_STATE rocker_state = ROCKER_NEUTRAL;
static enum ROCKER_STATE rocker_state_last = ROCKER_NEUTRAL;
static uint16_t cnt = 0;


cap2cnt = ECap1Regs.CAP2;
cap3cnt = ECap1Regs.CAP3;

Rocker_Databuf.Period = (float)(cap2cnt + cap3cnt)/100000.0;//ms
Rocker_Databuf.DutyRatio = ((float)(cap2cnt))/(cap2cnt + cap3cnt);

if((Rocker_Databuf.Period > (3.29-0.1))&&(Rocker_Databuf.Period < (3.29+0.1))&&(Rocker_Databuf.DutyRatio > (0.56-0.05))&&(Rocker_Databuf.DutyRatio < (0.56+0.05)))
{
rocker_state = ROCKER_NEUTRAL;
}
else if((Rocker_Databuf.Period > (4.27-0.1))&&(Rocker_Databuf.Period < (4.27+0.1))&&(Rocker_Databuf.DutyRatio > (0.56-0.05))&&(Rocker_Databuf.DutyRatio < (0.56+0.05)))
{
rocker_state = ROCKER_LEFT;
}
else if((Rocker_Databuf.Period > (2.25-0.1))&&(Rocker_Databuf.Period < (2.25+0.1))&&(Rocker_Databuf.DutyRatio > (0.56-0.05))&&(Rocker_Databuf.DutyRatio < (0.56+0.05)))
{
rocker_state = ROCKER_RIGHT;
}
else if((Rocker_Databuf.Period > (3.28-0.1))&&(Rocker_Databuf.Period < (3.28+0.1))&&(Rocker_Databuf.DutyRatio > (0.34-0.05))&&(Rocker_Databuf.DutyRatio < (0.34+0.05)))
{
rocker_state = ROCKER_UP;
}
else if((Rocker_Databuf.Period > (3.28-0.1))&&(Rocker_Databuf.Period < (3.28+0.1))&&(Rocker_Databuf.DutyRatio > (0.79-0.05))&&(Rocker_Databuf.DutyRatio < (0.79+0.05)))
{
rocker_state = ROCKER_DOWN;
}

if(rocker_state == rocker_state_last){
cnt ++;
if(cnt == 32){
cnt = 0;
if(rocker_state != ROCKER_NEUTRAL){
rocker_state_filter[rocker_state_filter_write_index] = rocker_state;
rocker_state_filter_write_index++;
if(rocker_state_filter_write_index == 8) rocker_state_filter_write_index = 0;
}
}
}else{
cnt = 0;
}
rocker_state_last = rocker_state;



PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;// Acknowledge this interrupt to receive more interrupts from group 4
ECap1Regs.ECCLR.all=0xFFFF;//clare all flag
}

//获取一个按键值
enum ROCKER_STATE GetRockerValue(void){
Uint16 rocker_state_filter_cnt = 0;
enum ROCKER_STATE rocker_state = NO_ACTION;

if(rocker_state_filter_read_index <= rocker_state_filter_write_index){
rocker_state_filter_cnt = rocker_state_filter_write_index - rocker_state_filter_read_index;
}else{
rocker_state_filter_cnt = rocker_state_filter_read_index - rocker_state_filter_write_index + 8;
}

if(rocker_state_filter_cnt > 0){
rocker_state = rocker_state_filter[rocker_state_filter_read_index];

rocker_state_filter_read_index++;
if(rocker_state_filter_read_index == 8) rocker_state_filter_read_index = 0;

}

return rocker_state;
}


7.4 280049c通过ADC外设读取按键电路输出电压值:epwm每5ms触发adc进行一次电压转换

void initADC(void)
{
//
// Setup VREF as internal
//
SetVREF(ADC_ADCA, ADC_INTERNAL, ADC_VREF3P3);

EALLOW;

//
// Set ADCCLK divider to /4
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 6;

//
// Set pulse positions to late
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

//
// Power up the ADC and then delay for 1 ms
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
EDIS;

DELAY_US(1000);
}

//
// initEPWM - Function to configure ePWM1 to generate the SOC.
//
void initEPWM(void)
{
EALLOW;

EPwm1Regs.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC on up-count
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //递增计数
EPwm1Regs.TBCTL.bit.HSPCLKDIV= 2;
EPwm1Regs.TBCTL.bit.CLKDIV= 2;

EPwm1Regs.CMPA.bit.CMPA = 0x0800; // Set compare A value to 2048 counts
EPwm1Regs.TBPRD = 31250; // Set period to 4096 counts

EPwm1Regs.TBCTL.bit.CTRMODE = 3; // Freeze counter

EDIS;
}

//
// initADCSOC - Function to configure ADCA's SOC0 to be triggered by ePWM1.
//
void initADCSOC(void)
{
//
// Select the channels to convert and the end of conversion flag
//
EALLOW;

AdcaRegs.ADCSOC0CTL.bit.CHSEL = 1; // SOC0 will convert pin A1
// 0:A0 1:A1 2:A2 3:A3
// 4:A4 5:A5 6:A6 7:A7
// 8:A8 9:A9 A:A10 B:A11
// C:A12 D:A13 E:A14 F:A15
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 9; // Sample window is 10 SYSCLK cycles
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // Trigger on ePWM1 SOCA

AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // End of SOC0 will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // Enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Make sure INT1 flag is cleared

EDIS;
}

//
// adcA1ISR - ADC A Interrupt 1 ISR
//
__interrupt void adcA1ISR(void)
{
float adcAResults_float = 0.0f;
static bool key2_state = 0;
static bool key2_state_last = 0;

static uint16_t cnt = 0;
//
// Add the latest result to the buffer
// ADCRESULT0 is the result register of SOC0
//adcAResults[index] = AdcaResultRegs.ADCRESULT0;
adcAResults_float=((AdcaResultRegs.ADCRESULT0))*3.3/4095;

if((adcAResults_float <(0.6 + 0.5))&&(adcAResults_float > (0.6 - 0.5)))
key2_state = 1;
else
key2_state = 0;

if(key2_state == key2_state_last){
cnt ++;
if(cnt == 32){
cnt = 0;
if(key2_state != 0){
key_state_filter[key_state_filter_write_index] = key2_state;
key_state_filter_write_index++;
if(key_state_filter_write_index == 8) key_state_filter_write_index = 0;
}
}
}else{
cnt = 0;
}
key2_state_last = key2_state;


//
// Clear the interrupt flag
//
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

//
// Check if overflow has occurred
//
if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT1)
{
AdcaRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
}

//
// Acknowledge the interrupt
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

Uint16 GetKeyValue(void){
Uint16 key_state_filter_cnt = 0;
Uint16 key_state = NULL;
if(key_state_filter_read_index <= key_state_filter_write_index){
key_state_filter_cnt = key_state_filter_write_index - key_state_filter_read_index;
}else{
key_state_filter_cnt = key_state_filter_read_index - key_state_filter_write_index + 8;
}

if(key_state_filter_cnt > 0){
key_state = key_state_filter[key_state_filter_read_index];
key_state_filter_read_index++;
if(key_state_filter_read_index == 8) key_state_filter_read_index = 0;
}

return key_state;
}

7.5 280049c通过GPIO外设控制三色LED:

 //开发板led
void led_init(void){

GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED4, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED4, GPIO_OUTPUT, GPIO_PUSHPULL);

GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED5, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED5, GPIO_OUTPUT, GPIO_PUSHPULL);
}

//扩展版三色led
void color_LED(void){
GPIO_SetupPinMux(DEVICE_GPIO_PIN_RED, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(DEVICE_GPIO_PIN_RED, GPIO_OUTPUT, GPIO_PUSHPULL);

GPIO_SetupPinMux(DEVICE_GPIO_PIN_GREEN, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(DEVICE_GPIO_PIN_GREEN, GPIO_OUTPUT, GPIO_PUSHPULL);

GPIO_SetupPinMux(DEVICE_GPIO_PIN_BLUE, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(DEVICE_GPIO_PIN_BLUE, GPIO_OUTPUT, GPIO_PUSHPULL);
}

8、遇到的主要难题及解决方法

本来想使用280049C的SPI外设驱动LCD屏幕,但耗了很长时间都没有搞好,最后使用妥协办法采用软件GPIO模拟SPI的方法驱动LCD屏幕。

在使用ECAP外设捕获摇杆pwm波形时,在进入ECAP中断服务函数后,发现结算得到的周期、占空比数值与真实值差别很大。最后发现寄存器“ECap1Regs.CAPx”是32位整数值,而程序中自己定义的“cap2cnt”是16位整数值,赋值时发生截断。

uint32_t cap2cnt;//防溢出

uint32_t cap3cnt;

cap2cnt = ECap1Regs.CAP2;

cap3cnt = ECap1Regs.CAP3;

在进行工程环境的搭建时,将基础程序烧进开发板后,发现板子有一股奇怪的糊味,最后发现是电阻加热电路的MOS管的栅极未置低电平,导致MOS一直处于导通状态,电阻持续加热。

 

9、未来的计划或建议

个人未来计划:学习280049C的CLB模块,使用本开发板做一个无刷直流电机的FOC控制器。

对活动主办方建议:首先给大方的主办方赞一个,大学生可以通过这种活动得到很好的提升。但直播效果感觉不太好,干货讲的太少了。

 

附件下载
Platform9_Task2_F28004x.zip
团队介绍
个人参赛
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号