——来自迪文开发者论坛
本期为大家推送迪文开发者论坛获奖开源案例——基于T5L的零食机。该方案基于T5L芯片,通过PWM接口实现实时调控爪子抓取力度、速度,并支持后台按键长按时间 读取,各模块自检,报错提醒,同步显示用户投币次数、游戏倒计时等功能,支持投币比例、游戏模式、多语言界面、抓力阈值等参数设置。
【演示视频】
视频由论坛工程师实拍提供
完整开发资料含迪文屏DGUS工程资料与C51代码,获取方式:
1. 前往迪文开发者论坛获取:/index.html/forum.php? mod=viewthread&tid=12062&extra=page%3D1&_dsign=80f3adcc
2 . 微信公众号中回复“零食机”获取。
【GUI工程设计】
【C51工程设计】
(1)T5L智能屏和主控的通信代码
void uart2_master_isr() interrupt 4
{
u8 res;
if(RI0)
{
RI0 = 0;
res = SBUF0;
uart2_rx_timeout = UART2_RX_TIMEOUT;
if((uart2_rx_sta&UART2_PACKET_OK)==0)
{
if(step==0)
{
recv_len = 0;
if(res==0x15)
step = 1;
}
else if(step==1)
{
date_len = res;
step = 2;
if(date_len>UART2_PACKET_MAX_LEN)
step = 0;
}
else if(step==2)
{
if(recv_len==date_len)
{
step = 0;
if(res==0x16)
{
uart2_rx_sta = date_len;
uart2_rx_sta |= UART2_PACKET_OK;
}
}
else
uart2_buf[recv_len++] = res;
}
}
}
}
(2)电机的驱动代码
void motor_move(MOTOR motor, MOTOR_DIR dir)
{
if (motor == MOTOR_Z) // Z轴上的爪子电机
{
if (dir == MOTOR_DIR_NONE) // 停止
{
MOTOR_Z_DISABLE();
}
else
{
if ((IS_MOTOR_Z_BACKWARD_POS() && (dir == MOTOR_DIR_BACKWARD)) ||
(IS_MOTOR_Z_FORWARD_POS() && (dir == MOTOR_DIR_FORWARD)))
{
MOTOR_Z_DISABLE();
dir = MOTOR_DIR_NONE;
}
else
{
MOTOR_Z_ENABLE();
MOTOR_Z_DIR_PIN = (dir == MOTOR_DIR_BACKWARD);
}
}
}
else if (motor == MOTOR_X) // X轴移动电机
{
if (dir == MOTOR_DIR_NONE) // 停止
{
MOTOR_X_DISABLE();
}
else
{
if (IS_MOTOR_X_BACKWARD_POS() && (dir == MOTOR_DIR_BACKWARD))
{
MOTOR_X_DISABLE();
dir = MOTOR_DIR_NONE;
}
else
{
MOTOR_X_ENABLE();
MOTOR_X_DIR_PIN = (dir == MOTOR_DIR_BACKWARD);
}
}
x_last_dir = dir;
}
else if (motor == MOTOR_Y) // Y轴移动电机
{
if (dir == MOTOR_DIR_NONE) // 停止
{
MOTOR_Y_DISABLE();
}
else
{
if ((IS_MOTOR_Y_BACKWARD_POS() && (dir == MOTOR_DIR_BACKWARD)) ||
(IS_MOTOR_Y_FORWARD_POS() && (dir == MOTOR_DIR_FORWARD)))
{
MOTOR_Y_DISABLE();
dir = MOTOR_DIR_NONE;
}
else
{
MOTOR_Y_ENABLE();
MOTOR_Y_DIR_PIN = (dir == MOTOR_DIR_BACKWARD);
}
}
y_last_dir = dir;
}
else if (motor == MOTOR_CLAW)
{
if (dir == MOTOR_DIR_NONE)
{
MOTOR_CLAW_RELEASE();
}
else
{
MOTOR_CLAW_HOLD();
}
}
}
(3)通过PWM调节爪子力度,速度的代码
const u16 MOTOR_DUTY[MOTOR_TOTAL][MOTOR_SPEED_MAX+1] = {
{45+DUTY_OFFSET,60+DUTY_OFFSET,80+DUTY_OFFSET,110+DUTY_OFFSET,130+DUTY_OFFSET,160+DUTY_OFFSET,200+DUTY_OFFSET,250+DUTY_OFFSET,550+DUTY_OFFSET,TIM_ARR},//X
{45+DUTY_OFFSET,60+DUTY_OFFSET,80+DUTY_OFFSET,110+DUTY_OFFSET,130+DUTY_OFFSET,160+DUTY_OFFSET,200+DUTY_OFFSET,250+DUTY_OFFSET,550+DUTY_OFFSET,TIM_ARR},//Y
{45,60,80,110,130,160,200,250,550,TIM_ARR},//Z
{200,220,240,270,290,320,360,410,550,TIM_ARR}//爪子
};
void motor_set_speed(MOTOR motor,u8 speed)
{
if(speed>MOTOR_SPEED_MAX)
return;
pwm_set_duty((PWM_CH)motor,MOTOR_DUTY[motor][speed]);
}
void motor_set_claw_strength_by_vol(float vol)
{
#define CLAW_DUTY_MIN 200
#define CLAW_DUTY_MAX TIM_ARR
u16 duty;
vol = (float)(vol-QZLDY_MIN)/(QZLDY_MAX-QZLDY_MIN);
if(vol<0)
vol = 0;
else if(vol>1)
vol = 1;
duty = (u16)(vol*(CLAW_DUTY_MAX-CLAW_DUTY_MIN)+0.5f)+CLAW_DUTY_MIN;
pwm_set_duty(PWM_CH_MOTOR_CLAW, duty);
}
(4)厂家后台按键长按检测
u8 key_check_long_press(KEY key,u32 time)
{
while(1)
{
if(!(KEY_Scan(1)&key))
return 1;//失败
if(time)
{
sys_delay_ms(1);
time--;
if(time==0)
return 0;//成功
}
}
}