——來(lái)自迪文開(kāi)發(fā)者論壇
本期為大家推送迪文開(kāi)發(fā)者論壇獲獎(jiǎng)開(kāi)源案例——?基于T5L的零食機(jī)?。該方案基于T5L芯片,通過(guò)PWM接口實(shí)現(xiàn)實(shí)時(shí)調(diào)控爪子抓取力度、速度,并支持后臺(tái)按鍵長(zhǎng)按時(shí)間 讀取,各模塊自檢,報(bào)錯(cuò)提醒,同步顯示用戶投幣次數(shù)、游戲倒計(jì)時(shí)等功能,支持投幣比例、游戲模式、多語(yǔ)言界面、抓力閾值等參數(shù)設(shè)置。
【演示視頻】
視頻由論壇工程師實(shí)拍提供
完整開(kāi)發(fā)資料含迪文屏DGUS工程資料與C51代碼,獲取方式:
1. 前往迪文開(kāi)發(fā)者論壇獲取:http://inforum.dwin.com.cn:20080/forum.php? mod=viewthread&tid=12062&extra=page%3D1&_dsign=80f3adcc
2 . 微信公眾號(hào)中回復(fù)“零食機(jī)”獲取。
【GUI工程設(shè)計(jì)】
【C51工程設(shè)計(jì)】
(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)電機(jī)的驅(qū)動(dòng)代碼
void motor_move(MOTOR motor, MOTOR_DIR dir)
{
if (motor == MOTOR_Z) // Z軸上的爪子電機(jī)
{
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軸移動(dòng)電機(jī)
{
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軸移動(dòng)電機(jī)
{
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)通過(guò)PWM調(diào)節(jié)爪子力度,速度的代碼
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)廠家后臺(tái)按鍵長(zhǎng)按檢測(cè)
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;//成功
}
}
}