
不是所有芯片都有开发板,官方会比较齐全,但价格也上来了。 虽然打板比较便宜,但前期研究电路不确定。 还是充分利用STM32外围原件简单的优势,自己搭建核心板。 材料:芯片,SSOP20转DIP20转接板 ![]() 焊接好 ![]() 外围电路图,只做了上电复位电路和boot0电路 ![]() 搭好电路后测试,够迷你吧。 ![]() 不想只点个灯,还是玩呼吸灯吧! 在CUBEMX中设置时钟48Mhz,TIM3的Channel1为“PWM Generation CH1”, ![]() 预分频47,重装值为999,这样PWM信号周期约为1毫秒 Pulse值为0,这个是占空比,计算方式: 占空比 = Pulse /(重装值 + 1)* 100% 相关设置网上资料有 开启PWM HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启PWM 修改Pulse值(也就是CCRx) __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值(Pulse),修改占空比 或: TIM3->CCR1 = pwmVal; 方式一:采用延时方法实现 搜到网上采用延时方法实现呼吸灯,程序如下: int main(void) { ...... uint16_t pwmVal=0; //PWM占空比 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启PWM ...... while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* while (pwmVal <1000) { HAL_Delay(1); //延时1ms pwmVal++; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 //TIM3->CCR1 = pwmVal; } while (pwmVal) { HAL_Delay(1); pwmVal--; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 TIM3->CCR1 = pwmVal; } } 方式二:采用中断方法实现 我对延时天生有种反感,效率有点低,改用中断! 在CUBEMX中把TIM3中断打开 全局变量 uint16_t pwmVal=0; //PWM占空比 uint8_t pwmDir = 0; //变化方向 int main(void) { ...... HAL_TIM_Base_Start_IT(&htim3); //开始中断 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启PWM ...... while 循环啥也不写 } //写回调函数,这个是计数器达到重置值时激活 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (pwmDir == 0) { pwmVal++; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 if (pwmVal == 999) pwmDir = 1; } else { pwmVal--; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 if (pwmVal == 0) pwmDir = 0; } } 我突然发现PA6要用于SPI接口,是否能用其他IO口输出,STM32时钟输出基本与SPI重叠,只剩一个PB0,不够用。 思路是当计数器达到预置比较值时产生一个中断,设置IO口,当达到重置值时再产生一个中断,反转IO口输出。 在CUBEMX中设置时钟48Mhz,TIM3的Channel1为“PWM Generation No Output”,把IO口还原出来。 我选择了2个IO口,分别定义为LED和LED2,为了更好效果,程序中两灯状态刚好相反 为了程序简约,我在main.h中宏定义 #define LED_Toggle HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); #define LED_ON HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); #define LED_OFF HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); #define LED2_Toggle HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin); #define LED2_ON HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); #define LED2_OFF HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); int main(void) { ...... HAL_TIM_Base_Start_IT(&htim3); //开启中断 HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); //开启PWM中断 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启PWM ...... while 循环啥也不写 } //写回调函数,这个是计数器达到重置值时激活,由于PWM没输出, void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (pwmDir == 0) { pwmVal++; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 if (pwmVal == 999) pwmDir = 1; } else { pwmVal--; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比 if (pwmVal == 0) pwmDir = 0; } LED_OFF; LED2_ON; } //这个回调函数是计数器达到比较值时激活,由于PWM没输出, void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { LED_ON; LED2_OFF; } 请各路大侠指点 |
的确,搞个数组或算法函数就可以实现了。
主要是中断问题,HAL库很少有介绍,
特别是回调函数的与中断对应关系,我不太懂,也不知哪里能查到。估计和我一样的也有不少,所以把摸索到的写出来而已。
不错
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); //开启PWM中断
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启PWM
时间有点久了,忘了这贴了。
我找时间再试试,当时一直不能没输出,也是摸索了很久,各种组合试了。后面没进一步优化。