本帖最后由 qinyunti 于 2023-6-19 23:09 编辑
1
蜂鸣器版本
c9b9260ae309870483fcee59754c76e5
2
喇叭版本-声音很炸裂
d4a5bce6fce4eaf20b0d779a6a6f9911
前言
前面实现了PWM音乐播放和ADC的采集,现在可以结合两者实现”动次打次打碟”的Demo。通过ADC旋转控制播放不同的音调。
参考
https://bbs.eeworld.com.cn/thread-1247074-1-1.html
https://bbs.eeworld.com.cn/thread-1247090-1-1.html
过程
基于https://bbs.eeworld.com.cn/thread-1247090-1-1.html
创建ADC工程,基于此工程进行
使用到的引脚
串口P0.2 P0.3
PWM P11_1
ADC P10_0
代码
获取ADC值
uint16_t adc_single_channel_process(void)
{
/* Variable to store ADC conversion result from channel 0 */
int32_t adc_result_0 = 0;
/* Read input voltage, convert it to millivolts and print input voltage */
adc_result_0 = cyhal_adc_read_uv(&adc_chan_0_obj) / MICRO_TO_MILLI_CONV_RATIO;
if(adc_result_0 >= 4096)
{
adc_result_0 = 0;
}
return adc_result_0;
}
主函数
int main(void)
{
/* Variable to capture return value of functions */
cy_rslt_t result;
uint16_t adc = 0;
uint8_t duty = 0;
uint16_t frq = 1000;
#if defined(CY_DEVICE_SECURE)
cyhal_wdt_t wdt_obj;
/* Clear watchdog timer so that it doesn't trigger a reset */
result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
CY_ASSERT(CY_RSLT_SUCCESS == result);
cyhal_wdt_free(&wdt_obj);
#endif
/* Initialize the device and board peripherals */
result = cybsp_init();
/* Board init failed. Stop program execution */
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Enable global interrupts */
__enable_irq();
/* Initialize retarget-io to use the debug UART port */
result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
CY_RETARGET_IO_BAUDRATE);
/* retarget-io init failed. Stop program execution */
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Print message */
/* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
printf("\x1b[2J\x1b[;H");
printf("-----------------------------------------------------------\r\n");
printf("PSoC 6 MCU: ADC using HAL\r\n");
printf("-----------------------------------------------------------\r\n\n");
pwm_initialize();
pwm_setduty(80, 10000);
beep_play_music(beepfrep, beepduty, beeptime, sizeof(beepfrep)/sizeof(beepfrep[0]));
#if ADC_EXAMPLE_MODE == MULTI_CHANNEL
/* Initialize Channel 0 and Channel 1 */
adc_multi_channel_init();
#else /* ADC_EXAMPLE_MODE == SINGLE_CHANNEL */
/* Initialize Channel 0 */
adc_single_channel_init();
#endif /* ADC_EXAMPLE_MODE == MULTI_CHANNEL */
/* Update ADC configuration */
result = cyhal_adc_configure(&adc_obj, &adc_config);
if(result != CY_RSLT_SUCCESS)
{
printf("ADC configuration update failed. Error: %ld\n", (long unsigned int)result);
CY_ASSERT(0);
}
for (;;)
{
#if ADC_EXAMPLE_MODE == MULTI_CHANNEL
/* Sample input voltage at channel 0 and channel 1*/
adc_multi_channel_process();
#else /* ADC_EXAMPLE_MODE == SINGLE_CHANNEL */
/* Sample input voltage at channel 0 */
#endif /* ADC_EXAMPLE_MODE == MULTI_CHANNEL */
/* 200ms delay between scans */
cyhal_system_delay_ms(100);
adc = adc_single_channel_process();
printf("adc:%d\r\n",adc);
if(adc<ADC_MIN)
{
duty = 1;
frq = 1000;
}
else
{
if(adc>ADC_MAX)
{
adc =ADC_MAX;
}
duty = 20;
frq = (((uint32_t)FRQ_MAX-FRQ_MIN)*((uint32_t)adc-FRQ_MIN))/((uint32_t)ADC_MAX-ADC_MIN) + (uint32_t)FRQ_MIN;
}
pwm_setduty(duty, frq);
}
}
PWM相关
void beep_play_music(const uint16_t* freq,const uint16_t* duty, const uint32_t* time, uint16_t len)
{
uint16_t i = 0;
for(i=0; i< len; i++)
{
pwm_setduty(duty,freq);
cyhal_system_delay_ms(time);
}
}
cy_rslt_t pwm_initialize(void)
{
cy_rslt_t rslt;
rslt = cyhal_pwm_init(&pwm_led, P11_1, NULL);
if (CY_RSLT_SUCCESS == rslt)
{
rslt = cyhal_pwm_set_duty_cycle(&pwm_led,
50,
10000);
if (CY_RSLT_SUCCESS == rslt)
{
rslt = cyhal_pwm_start(&pwm_led);
}
}
return rslt;
}
cy_rslt_t pwm_setduty(uint8_t duty, uint32_t freq)
{
cy_rslt_t rslt;
cyhal_pwm_stop(&pwm_led);
cyhal_pwm_set_duty_cycle(&pwm_led,duty,freq);
rslt = cyhal_pwm_start(&pwm_led);
return rslt;
}
代码见附件
测试
见视频
总结
以上结合ADC和PWM实现了模拟打碟的效果,好的效果需要有音乐元素的经验,需要好的素材以上仅作演示,可以搜集一些比较好玩的音乐,结合旋转变压器输入得到一些有意思的效果。