TI MSPM0G3507 简易PID项目显示和按键控制
注释掉了一些测试代码,具体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);//延时大概1SDL_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_IIDXcase 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;}
}