首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[Atmel开发板经验分享] GPIO控制的簡易機械手臂

[Atmel开发板经验分享] GPIO控制的簡易機械手臂

利用按鈕做觸發改變手臂上各servo的角度來夾起垃圾(衛生紙)
LED toggle由開發板上的SW0按鈕偵測是否被按下的高低電位變化
產生interrupt給MCU在執行LED的亮滅
因此基於這範例我加入了在更新LED狀態時,同時也變更了小機械手臂各servo的狀態,
在static void update_led_state(void)加入:


if(pin_state==true)
{

delay1=3500;

}
else
{  

delay1=10000;

}
其中delay1是用來決定第一個PWM輸出的duty cycle值給servo
並加入tc driver用以產生PWM訊號
定義PWM1 即EXT1擴充腳位群組上的PWM,而PWM10即PWM(+),PWM11即PWM(-)
#define PWM1_MODULEEXT1_PWM_MODULE
#define PWM10_OUT_PINEXT1_PWM_0_PIN
#define PWM10_OUT_MUXEXT1_PWM_0_MUX
#define PWM11_OUT_PINEXT1_PWM_1_PIN
#define PWM11_OUT_MUXEXT1_PWM_1_MUX

tc初始化所需要的參數設定,其中tc1給第一個跟第二個servo,tc2給第三個跟第四個servo,每個instance各有channel0跟channel1兩個PWM頻道,並觸發callback時產生duty cycle的變化給servo改變機械手臂的狀態
void configure_tc(void)
{
    struct tc_config config_tc1, config_tc2;
    tc_get_config_defaults(&config_tc1);
    tc_get_config_defaults(&config_tc2);
    config_tc1.counter_size    = TC_COUNTER_SIZE_16BIT;
    config_tc1.wave_generation = TC_WAVE_GENERATION_NORMAL_PWM;
    config_tc1.counter_16_bit.compare_capture_channel[0] = 0xFFFF;
    config_tc1.pwm_channel[0].enabled =true;
    config_tc1.pwm_channel[0].pin_out = PWM10_OUT_PIN;
    config_tc1.pwm_channel[0].pin_mux = PWM10_OUT_MUX;
    config_tc1.counter_16_bit.compare_capture_channel[1] = 0xFFFF;

    config_tc1.pwm_channel[1].enabled =true;
    config_tc1.pwm_channel[1].pin_out = PWM11_OUT_PIN;
    config_tc1.pwm_channel[1].pin_mux = PWM11_OUT_MUX;
    config_tc2.counter_size    = TC_COUNTER_SIZE_16BIT;
    config_tc2.wave_generation = TC_WAVE_GENERATION_NORMAL_PWM;
    config_tc2.counter_16_bit.compare_capture_channel[0] = 0xFFFF;
    config_tc2.pwm_channel[0].enabled =true;
    config_tc2.pwm_channel[0].pin_out = PWM20_OUT_PIN;
    config_tc2.pwm_channel[0].pin_mux = PWM20_OUT_MUX;
    config_tc2.counter_16_bit.compare_capture_channel[1] = 0xFFFF;
    config_tc2.pwm_channel[1].enabled =true;
    config_tc2.pwm_channel[1].pin_out = PWM21_OUT_PIN;
    config_tc2.pwm_channel[1].pin_mux = PWM21_OUT_MUX;
    tc_init(&tc_instance1, PWM1_MODULE, &config_tc1);
    tc_init(&tc_instance2, PWM2_MODULE, &config_tc2);
    tc_enable(&tc_instance1);
    tc_enable(&tc_instance2);
}
void configure_tc_callbacks(void)
{
    tc_register_callback(
    &tc_instance1,
    tc_callback_to_change_duty_cycle_1,
    TC_CALLBACK_CC_CHANNEL0);
    tc_register_callback(
    &tc_instance1,
    tc_callback_to_change_duty_cycle_2,
    TC_CALLBACK_CC_CHANNEL1);
    tc_register_callback(
    &tc_instance2,
    tc_callback_to_change_duty_cycle_3,
    TC_CALLBACK_CC_CHANNEL0);
    tc_register_callback(
    &tc_instance2,
    tc_callback_to_change_duty_cycle_4,
    TC_CALLBACK_CC_CHANNEL1);

    tc_enable_callback(&tc_instance1, TC_CALLBACK_CC_CHANNEL0);
    tc_enable_callback(&tc_instance1, TC_CALLBACK_CC_CHANNEL1);
    tc_enable_callback(&tc_instance2, TC_CALLBACK_CC_CHANNEL0);
    tc_enable_callback(&tc_instance2, TC_CALLBACK_CC_CHANNEL1);
}
void tc_callback_to_change_duty_cycle_1(struct tc_module *const module_inst)
{
    tc_set_compare_value(module_inst, TC_COMPARE_CAPTURE_CHANNEL_0, delay1 + 1);
}
void tc_callback_to_change_duty_cycle_2(struct tc_module *const module_inst)
{
    tc_set_compare_value(module_inst, TC_COMPARE_CAPTURE_CHANNEL_1, delay2 + 1);
}
void tc_callback_to_change_duty_cycle_3(struct tc_module *const module_inst)
{
    tc_set_compare_value(module_inst, TC_COMPARE_CAPTURE_CHANNEL_0, delay3 + 1);
}
void tc_callback_to_change_duty_cycle_4(struct tc_module *const module_inst)
{
    tc_set_compare_value(module_inst, TC_COMPARE_CAPTURE_CHANNEL_1, delay4 + 1);
}

最後在main()裡面呼叫兩個副程式即可:
configure_tc();
configure_tc_callbacks();
返回列表