[Atmel开发板经验分享] GPIO控制的簡易機械手臂
- UID
- 1066743
|
[Atmel开发板经验分享] GPIO控制的簡易機械手臂
利用按鈕做觸發改變手臂上各servo的角度來夾起垃圾(衛生紙)
LED toggle由開發板上的SW0按鈕偵測是否被按下的高低電位變化
產生interrupt給MCU在執行LED的亮滅
因此基於這範例我加入了在更新LED狀態時,同時也變更了小機械手臂各servo的狀態,
在static void update_led_state(void)加入:
if(pin_state==true)
{
}
else
{
}
其中delay1是用來決定第一個PWM輸出的duty cycle值給servo
並加入tc driver用以產生PWM訊號
定義PWM1 即EXT1擴充腳位群組上的PWM,而PWM10即PWM(+),PWM11即PWM(-)
#define PWM1_MODULE | EXT1_PWM_MODULE | #define PWM10_OUT_PIN | EXT1_PWM_0_PIN | #define PWM10_OUT_MUX | EXT1_PWM_0_MUX | #define PWM11_OUT_PIN | EXT1_PWM_1_PIN | #define PWM11_OUT_MUX | EXT1_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(); |
|
|
|
|
|