Skip to content

Instantly share code, notes, and snippets.

@tsl0922
Created August 13, 2024 10:07
Show Gist options
  • Save tsl0922/90e11c3b4b2b202de253e754d1efd5ae to your computer and use it in GitHub Desktop.
Save tsl0922/90e11c3b4b2b202de253e754d1efd5ae to your computer and use it in GitHub Desktop.
stm32 RGB led and buzzer demo (R/G/B: PA0/PA1/PA2, Buzzer: PA6).
#include "stm32f10x.h"
void Delay_us(uint32_t xus) {
SysTick->LOAD = 72 * xus;
SysTick->VAL = 0x00;
SysTick->CTRL = 0x00000005;
while(!(SysTick->CTRL & 0x00010000));
SysTick->CTRL = 0x00000004;
}
void Delay_ms(uint32_t xms) {
while(xms--) Delay_us(1000);
}
void Buzzer_GPIO_Config(void) {
// Enable GPIOA clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // Assuming PA6 for TIM3 Channel 1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Buzzer_PWM_Config(void) {
// Enable TIM3 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Time base configuration
TIM_TimeBaseStructure.TIM_Period = 999; // 1kHz frequency
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 1MHz timer clock
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// PWM1 Mode configuration: Channel 1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; // 50% duty cycle
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
// Enable TIM3 counter
TIM_Cmd(TIM3, ENABLE);
}
void Buzzer_SetFreq(uint16_t freq) {
// Calculate the period value based on the desired frequency
uint16_t period = 1000000 / freq;
// Update the period value of TIM3
TIM3->ARR = period;
}
void Buzzer_SetDuty(uint16_t duty) {
// Calculate the pulse value based on the desired duty cycle
uint16_t pulse = (duty * (TIM3->ARR + 1)) / 100;
// Update the pulse value of TIM3
TIM3->CCR1 = pulse;
}
void RGB_GPIO_Config(void) {
// Enable GPIO clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; // Assuming PA0, PA1, PA2 for RGB
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void RGB_PWM_Config(void) {
// Enable TIM2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Time base configuration
TIM_TimeBaseStructure.TIM_Period = 255; // 8-bit resolution
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// PWM1 Mode configuration: Channel 1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
// PWM1 Mode configuration: Channel 2
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
// PWM1 Mode configuration: Channel 3
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
// Enable TIM2 counter
TIM_Cmd(TIM2, ENABLE);
}
void RGB_Set(uint8_t red, uint8_t green, uint8_t blue) {
TIM_SetCompare1(TIM2, red); // Set duty cycle for Red
TIM_SetCompare2(TIM2, green); // Set duty cycle for Green
TIM_SetCompare3(TIM2, blue); // Set duty cycle for Blue
}
void RGB_Get_Gradient_Color(uint32_t step, uint8_t *red, uint8_t *green, uint8_t *blue) {
uint8_t phase = (step / 256) % 3;
uint8_t value = step % 256;
switch (phase) {
case 0:
*red = 255 - value;
*green = value;
*blue = 0;
break;
case 1:
*red = 0;
*green = 255 - value;
*blue = value;
break;
case 2:
*red = value;
*green = 0;
*blue = 255 - value;
break;
}
}
// cycle the rgb color smoothly
void RGB_Play(uint16_t delay, uint16_t count) {
static uint32_t step = 0;
uint8_t red, green, blue;
for (int i = 0; i < count; i++) {
RGB_Get_Gradient_Color(step, &red, &green, &blue);
RGB_Set(red, green, blue);
step++;
Delay_ms(delay);
}
}
// Twinkle Twinkle Little Star
void Buzzer_Play() {
uint16_t tones[] = {0, 262, 294, 330, 349, 392, 440, 494};
char *melody = "1155665-4433221-5544332-5544332-1155665-4433221";
uint32_t step = 0;
uint8_t red, green, blue;
uint16_t i = 0;
while (melody[i] != '\0') {
if (melody[i] == '0' || melody[i] == '-') {
Buzzer_SetDuty(0);
} else {
Buzzer_SetFreq(tones[melody[i] - '0']);
Buzzer_SetDuty(50);
}
RGB_Play(4, 100);
Buzzer_SetDuty(0);
RGB_Play(4, 25);
i++;
}
}
int main(void) {
RGB_GPIO_Config();
RGB_PWM_Config();
Buzzer_GPIO_Config();
Buzzer_PWM_Config();
while (1) {
Buzzer_Play();
Delay_ms(500);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment