TI MSPM0G3507 简易PID项目显示和按键控制

发布于:2025-06-02 ⋅ 阅读:(25) ⋅ 点赞:(0)

注释掉了一些测试代码,具体UI状态机未实现,已实现按键控制和UI选择切换。 




#include <stdio.h>      // 标准输入输出(最基础,无依赖)
#include <string.h>     // 字符串处理函数(标准库,早于自定义头文件)
#include "ti_msp_dl_config.h"  // TI 驱动库配置(需先于驱动库头文件)
#include "mid_button.h"   // 自定义模块头文件(底层外设/组件)
#include "oled.h"         // 自定义模块头文件(可能依赖 mid_button 等)
#include "lcd.h"          // 自定义模块头文件(注意:需确保其依赖的驱动库头文件已包含)
#include "key_task.h"     // 任务层头文件(依赖底层组件)
#include "mid_uart.h"     // 自定义模块头文件(若与其他模块无强依赖,可后置)
#include "encoder.h"
#include "timer.h"
#include "key.h"
#include "motor.h"
#include "app.h"
#include "app_sys_mode.h"

#include "stdlib.h"


#define SPEED_WAVEFORM_REDUCTION_FACTOR 10

#define SPEED_ENCODER_VALUE_MAX ( -(SPEED_ENCODER_VALUE_MIN) )
#define SPEED_ENCODER_VALUE_MID 0
#define SPEED_ENCODER_VALUE_MIN (-100)

#define DISTANCE_ENCODER_VALUE_MAX ( -(DISTANCE_ENCODER_VALUE_MIN) )
#define DISTANCE_ENCODER_VALUE_MID 0
#define DISTANCE_ENCODER_VALUE_MIN (-360)


//重定义printf
int fputc(int ch, FILE *stream)
{
        while( DL_UART_isBusy(UART_0_INST) == true );

        DL_UART_Main_transmitData(UART_0_INST, ch);

        return ch;
}

volatile unsigned int delay_time=0;

volatile unsigned char uart_data = 0;
volatile unsigned int i=0;

void uart0_send_char(char ch);
void uart0_send_string(char* str);


void ui_home_page(void);	//首页初始化
void ui_encoder_value_update(void);//编码器数据显示


//搭配滴答定时器实现的精确ms延时
void delay_ms(unsigned int ms){
	delay_time=ms;
	while(delay_time != 0);
}
// 生成范围在 0 到 88 之间的随机整数
int generate_random(void)
{
	return (rand() % 89);
}

bool motor_status = false;//电机状态
int curve_x = 0;

int main(void)
{
    SYSCFG_DL_init();
    //NVIC_EnableIRQ(KEY_INT_IRQN);//开启按键引脚的GPIOB端口中断
    //DL_GPIO_setPins(LED1_PORT,LED1_PIN_22_PIN);
    
    //清除串口中断标志
    //NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
    //使能串口中断
    //NVIC_EnableIRQ(UART_0_INST_INT_IRQN);

    //清除定时器中断标志
    //NVIC_ClearPendingIRQ(TIMER_0_INST_INT_IRQN);
    //使能定时器中断
    //NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
	
	//系统参数初始化
	sys_event_init();
	
	//屏幕初始化
	lcd_init();
	ui_home_page();
	
	//编码器初始化
	encoder_init();
	
	//定时器初始化
	timer_init();
	
    //按键初始化
    user_button_init();
	
	
	
//	delay_cycles(8000000*2);
//	//显示定速界面
//	ui_speed_page();
//	//显示定速界面的PID参数
//	ui_speed_page_value_set(12.1, 2.2, 3.12, 50, 30, 1);
//	//I值位置显示选择框
//	ui_speed_page_select_box(1);
//	//D值位置显示选中框
//	ui_parameter_select_box_bold(2);
	
	int sys_time=0;
	
	DL_TimerG_setCaptureCompareValue(PWM_0_INST,0,GPIO_PWM_0_C1_IDX);
    while (1) {
        //__asm__("nop");
		sys_time++;
		/*
        DL_GPIO_clearPins(LED1_PORT,LED1_PIN_22_PIN);//输出低电平
        delay_ms(1000);//延时大概1S
        DL_GPIO_setPins(LED1_PORT,LED1_PIN_22_PIN);  //输出高电平
        delay_ms(1000);//延时大概1S
        */
        /*
        if( DL_GPIO_readPins(KEY_PORT, KEY_PIN_21_PIN) == 0){
            DL_GPIO_setPins(LED1_PORT, LED1_PIN_22_PIN);//高电平
        }else{
            DL_GPIO_clearPins(LED1_PORT, LED1_PIN_22_PIN);//低电平
        }
        */
        // 呼吸灯渐亮过程
//        for (i = 0; i <= 998; i++)
//        {
//            // 设置 LED 亮度
//            DL_TimerG_setCaptureCompareValue(PWM_0_INST,i,GPIO_PWM_0_C1_IDX);
//            delay_ms(1);  // 延迟以控制亮度变化速度
//        }
        // 呼吸灯渐暗过程
//        for (i = 998; i > 0; i--)
//        {
//            // 设置 LED 亮度
//            DL_TimerG_setCaptureCompareValue(PWM_0_INST,i,GPIO_PWM_0_C1_IDX);
//            delay_ms(1);  // 延迟以控制亮度变化速度
//        }

        //按键扫描
//		if(sys_time%20==0){
//			flex_button_scan();
//			
//		}
		if(sys_time%10==0){
			//使用随机数刷新波形
			//draw_speed_curve(0, 0, 319, 88, GREEN, BLACK, generate_random() );
		}
		
		if(sys_time%20==0){
			//ui_home_page_select(get_app_key_current_mode());
			//ui_encoder_value_update();
		}

		//电机扫描
		if(sys_time%20==0){
			if(motor_status==true){
				DL_TimerG_setCaptureCompareValue(PWM_0_INST,999,GPIO_PWM_0_C1_IDX);
				set_motor(9999,0);
			}else{
				DL_TimerG_setCaptureCompareValue(PWM_0_INST,0,GPIO_PWM_0_C1_IDX);
				stop_motor();
			}
		}
		
		delay_cycles(CPUCLK_FREQ/1000*2);
		if(sys_time>=99999) sys_time=0;
		//flex_button_scan();
        //delay_ms(20);
		

		}

}




//定时器的中断服务函数 已配置为1秒的周期
void TIMER_0_INST_IRQHandler(void)
{
    //如果产生了定时器中断
    switch( DL_TimerG_getPendingInterrupt(TIMER_0_INST) )
    {
        case DL_TIMER_IIDX_ZERO://如果是0溢出中断
            //将LED灯的状态翻转
            //DL_GPIO_togglePins(LED1_PORT, LED1_PIN_22_PIN);
            break;

        default://其他的定时器中断
            break;
    }
}



//滴答定时器中断服务函数
void SysTick_Handler(void)
{
    if( delay_time != 0 )
    {
        delay_time--;
    }
}
/*
void GROUP1_IRQHandler(void)//Group1的中断服务函数
{
    
    //读取Group1的中断寄存器并清除中断标志位
    switch( DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1) )
    {
        //检查是否是KEY的GPIOB端口中断,注意是INT_IIDX,不是PIN_22_IIDX
        case KEY_INT_IIDX:
            //如果按键按下变为高电平
            if( DL_GPIO_readPins(KEY_PORT, KEY_PIN_21_PIN) > 0 )
            {
                //设置LED引脚状态翻转
                //DL_GPIO_togglePins(LED1_PORT, LED1_PIN_22_PIN);
            }
        break;
    }

    
}
*/

//串口发送单个字符
void uart0_send_char(char ch)
{
    //当串口0忙的时候等待,不忙的时候再发送传进来的字符
    while( DL_UART_isBusy(UART_0_INST) == true );
    //发送单个字符
    DL_UART_Main_transmitData(UART_0_INST, ch);
}
//串口发送字符串
void uart0_send_string(char* str)
{
    //当前字符串地址不在结尾 并且 字符串首地址不为空
    while(*str!=0&&str!=0)
    {
        //发送字符串首地址中的字符,并且在发送完成之后首地址自增
        uart0_send_char(*str++);
    }
}

//串口的中断服务函数
void UART_0_INST_IRQHandler(void)
{
    //如果产生了串口中断
    switch( DL_UART_getPendingInterrupt(UART_0_INST) )
    {
        case DL_UART_IIDX_RX://如果是接收中断
            //接发送过来的数据保存在变量中
            uart_data = DL_UART_Main_receiveData(UART_0_INST);
            //将保存的数据再发送出去
            uart0_send_char(uart_data);
            break;

        default://其他的串口中断
            break;
    }
}