You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TMS320F28335的SND3360变量显示及PWM控制技术求助

问题描述

我正在使用TI的TMS320F28335实现永磁同步电机(PMSM)的矢量控制,需要通过连接SND3360的按键实现PWM的启停控制,同时要在SND3360上显示变量数据。目前已能在SND3360上显示固定数值,但不清楚如何实现变量值的显示,现附上相关代码片段,恳请提供代码层面的帮助。

当前代码片段

模式切换逻辑

Mode_cnt += Mode_inc;
if(Mode_cnt > MODE_LIM) { Mode_cnt = 0; }
switch(Mode_cnt)
{
 case 0:    Display[5] = 0x30;    break;
 case 1:    sts_display();   led_display(0x00);    DELAY_US(2L);           break;
 case 2:    diag_display();  led_display(0x00);    DELAY_US(2L);          break;
 case 3:    para1_display(); led_display(0x00);    DELAY_US(2L);         break;
 }
 }

固定值显示示例

void sts_display(void)
{
Sts_cnt += Up_inc;
if(Sts_cnt > Sts_lim) { Sts_cnt = 0; }

switch(Sts_cnt)
{
 case 0:  Display[3] = 0x30; break;
 case 1:  Display[3] = 0x75; break;
 case 2:  Display[3] = 0x36; break;
 default: Display[3] = 0x30; break;
 }
 }

通过这些函数,我可以对特定按键及Display[n](n=1...6)进行设置、清除、递增和递减操作。


解决方案

要实现变量值显示,核心是把变量的数值转换为SND3360数码管对应的段码,再赋值给Display数组。以下是具体实现步骤和代码:

1. 定义数码管段码映射表

先确认SND3360数码管类型(共阴/共阳),以下以共阴七段码为例(共阳则将段码取反):

// 共阴段码:0-9、A-F(覆盖整数和十六进制显示需求)
const unsigned char SEG_CODE[] = {0x30, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};

2. 实现变量转段码的通用函数

整数转段码函数

支持多位数显示,可处理正负数:

// 将整数val拆分到Display的start_pos位置,显示digit_len位
void display_int(int val, unsigned char start_pos, unsigned char digit_len)
{
    unsigned char i;
    unsigned long abs_val;
    
    // 处理负数:先显示负号
    if(val < 0)
    {
        Display[start_pos] = 0x40; // 负号对应的段码
        abs_val = -val;
        start_pos++;
        digit_len--;
    }
    else
    {
        abs_val = val;
    }
    
    // 从高位到低位拆分数字并赋值段码
    for(i = 0; i < digit_len; i++)
    {
        unsigned char digit = (abs_val / pow(10, digit_len - 1 - i)) % 10;
        Display[start_pos + i] = SEG_CODE[digit];
    }
}

浮点数转段码函数

通过放大倍数将小数转为整数显示,支持带小数位的变量(如母线电压、转速):

// 显示浮点数val:int_digit位整数,dec_digit位小数,起始位置start_pos
void display_float(float val, unsigned char start_pos, unsigned char int_digit, unsigned char dec_digit)
{
    int int_part = (int)val;
    int dec_part = (int)((val - int_part) * pow(10, dec_digit));
    
    // 显示整数部分
    display_int(int_part, start_pos, int_digit);
    // 显示小数点(通过点亮数码管的小数点段,此处假设段码加0x80实现)
    if(dec_digit > 0)
    {
        Display[start_pos + int_digit] |= 0x80;
        // 显示小数部分
        display_int(dec_part, start_pos + int_digit + 1, dec_digit);
    }
}

3. 修改显示函数实现变量显示

以para1_display()为例,实现电机转速、相电流等变量的切换显示:

// 假设已定义全局变量:motor_speed(转速)、phase_current_a(A相电流)、bus_voltage(母线电压)
void para1_display(void)
{
    Sts_cnt += Up_inc;
    if(Sts_cnt > Sts_lim) { Sts_cnt = 0; }
    
    switch(Sts_cnt)
    {
        case 0: display_int(motor_speed, 1, 4); break; // 1-4位显示转速(0-9999)
        case 1: display_int(phase_current_a, 1, 4); break; // 显示A相电流
        case 2: display_float(bus_voltage, 1, 3, 1); break; // 显示母线电压(3位整数+1位小数)
        default: display_int(motor_speed, 1, 4); break;
    }
}

4. 按键控制PWM启停

在按键扫描函数中添加PWM启停逻辑:

// 按键扫描函数(需根据SND3360硬件实现,返回按键状态)
unsigned char scan_snd3360_key(void)
{
    // 此处补充SND3360按键扫描代码,返回KEY_OK/KEY_UP/KEY_DOWN等状态
    return KEY_NONE;
}

// 按键处理:控制PWM启停
void key_control_pwm(void)
{
    static unsigned char pwm_running = 0; // 0:停止,1:运行
    unsigned char key = scan_snd3360_key();
    
    if(key == KEY_OK)
    {
        pwm_running = !pwm_running;
        if(pwm_running)
        {
            // 启动PWM:配置F28335的PWM寄存器
            EALLOW;
            EPwm1Regs.TBCTL.bit.CTRMODE = 0; // 增计数模式
            EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 计数器等于CMPA时置高
            EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // 计数器等于CMPA时置低
            EDIS;
        }
        else
        {
            // 停止PWM:禁用输出动作
            EALLOW;
            EPwm1Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;
            EPwm1Regs.AQCTLA.bit.CAD = AQ_NO_ACTION;
            EDIS;
        }
    }
}

5. 主循环整合逻辑

在主循环中定期执行按键处理和显示更新:

void main(void)
{
    // 初始化:系统时钟、GPIO、PWM、SND3360等
    system_init();
    snd3360_init();
    
    while(1)
    {
        key_control_pwm(); // 处理PWM启停按键
        
        // 更新显示模式
        Mode_cnt += Mode_inc;
        if(Mode_cnt > MODE_LIM) { Mode_cnt = 0; }
        switch(Mode_cnt)
        {
            case 0: Display[5] = 0x30; break;
            case 1: sts_display(); led_display(0x00); DELAY_US(2L); break;
            case 2: diag_display(); led_display(0x00); DELAY_US(2L); break;
            case 3: para1_display(); led_display(0x00); DELAY_US(2L); break;
        }
        
        snd3360_refresh(); // 刷新SND3360显示(根据硬件要求添加)
    }
}

内容的提问来源于stack exchange,提问作者Muhammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:45:33