/********************************************************************************* * Copyright: (C) 2021 Guo Wenxue * All rights reserved. * * Filename: pwm_music.c * Description: This file used to test PWM music * * Version: 1.0.0(10/21/2022~) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "10/21/2022 17:46:18 PM" * ********************************************************************************/ #include #include #include #include #include #include #include #include #define PWM_CHIP 1 /* buzzer on pwmchip1 */ typedef struct pwm_note_s { unsigned int msec; //持续时间,毫秒 unsigned int freq;//频率 unsigned char duty;//相对占空比,百分比 * 100 }pwm_note_t; /* 使用宏确定使用中音还是高、低音 */ #define CX CM /* 低、中、高音频率*/ static const unsigned short CL[8] = {0, 262, 294, 330, 349, 392, 440, 494}; static const unsigned short CM[8] = {0, 523, 587, 659, 698, 784, 880, 988}; static const unsigned short CH[8] = {0, 1046, 1175, 1318, 1397, 1568, 1760, 1976}; /* 小星星曲子*/ static unsigned short melody[] = { CX[1], CX[1], CX[5], CX[5], CX[6], CX[6], CX[5], CX[0], CX[4], CX[4], CX[3], CX[3], CX[2], CX[2], CX[1], CX[0], CX[5], CX[5], CX[4], CX[4], CX[3], CX[3], CX[2], CX[0], CX[5], CX[5], CX[4], CX[4], CX[3], CX[3], CX[2], CX[0], }; static char pwm_path[64]; /* pwm file path buffer */ static int pwm_export(int chip); static int pwm_config(const char *attr, const char *val); static int pwm_ring(pwm_note_t *note); static inline void msleep(unsigned long ms); int main(int argc, char *argv[]) { pwm_note_t note; int i; if( pwm_export(PWM_CHIP) < 0 ) return 1; pwm_config("enable", "1"); for(i=0; iduty > 100 ) { printf("[INFO] %s argument error.\n", __FUNCTION__); return -1; } period = (unsigned long)((1.f / (double)note->freq) * 1e9);//ns单位 duty_cycle = (unsigned long)(((double)note->duty / 100.f) * (double)period);//ns单位 snprintf(period_str, sizeof(period_str), "%lu", period); snprintf(duty_cycle_str, sizeof(duty_cycle_str), "%lu", duty_cycle); //设置pwm频率和周期 if (pwm_config("period", period_str)) { printf("pwm_config period failure.\n"); return -1; } if (pwm_config("duty_cycle", duty_cycle_str)) { printf("pwm_config duty_cycle failure.\n"); return -2; } msleep(note->msec); /* 设置占空比为0 蜂鸣器无声 */ if (pwm_config("duty_cycle", "0")) { printf("pwm_config duty_cycle failure.\n"); return -3; } msleep(20); return 0; } /* ms级休眠函数 */ static inline void msleep(unsigned long ms) { struct timespec cSleep; unsigned long ulTmp; cSleep.tv_sec = ms / 1000; if (cSleep.tv_sec == 0) { ulTmp = ms * 10000; cSleep.tv_nsec = ulTmp * 100; } else { cSleep.tv_nsec = 0; } nanosleep(&cSleep, 0); }