休克的本质是什么| 高压偏低是什么原因造成的| 可逆是什么意思| 做梦梦到蛇是什么征兆| 扁桃体有什么用| 金线莲有什么功效| 胆固醇高有什么危害| 腹泻可以吃什么食物| 熬夜伤什么| 头疼喝什么药| 洗头膏什么牌子好| 什么是蝴蝶宝宝| 老年人心跳过快是什么原因| 喜欢蓝色的女人是什么性格| 最小的动物是什么| 梦见亲人哭是什么征兆| 中标是什么意思| 梦见老虎狮子是什么预兆| 足跟疼挂什么科室| 翡翠属于什么玉| 落地签是什么意思| 起什么转什么成语| 阴唇内侧长疙瘩是什么原因| 九月一日什么节日| 什么床品牌最好| 知否知否应是绿肥红瘦什么意思| 曹字五行属什么| 土耳其浴是什么意思| it是什么行业| 感冒头疼是什么原因| 什么是姑息治疗| 今天什么日子| 炖什么汤对肺部最好| 喝酒对身体有什么好处和坏处| 葡萄像什么| 吃烧烤后吃什么水果可以帮助排毒| 走投无路是什么意思| 吃什么清理脑血管堵塞| 狼烟是什么意思| 蜱虫的天敌是什么| 珠联璧合是什么意思| 尿道灼热感吃什么药| 混血是什么意思| 什么盛名| 张国荣什么时候去世的| 红酒为什么要醒酒| 肉桂粉是什么做的| 溶血是什么意思| 验光是什么意思| ck是什么牌子的包包| 蛇酒不是三十九开什么| 莼菜是什么菜| 64岁属什么生肖| 申的五行属什么| 牛鬼蛇神是什么意思| 姗字五行属什么| 什么的垂下| 水土不服吃什么药| 父母都是b型血孩子是什么血型| 什么是华盖| 体检前三天不能吃什么| 火车和高铁有什么区别| 异丙醇是什么| 梦见别人杀人是什么预兆| 血液病有什么症状| 肺活量5000什么水平| 曼陀罗是什么意思| 虎皮鹦鹉吃什么| 75年属什么的生肖| 魂穿是什么意思| 立秋什么意思| b型和o型生的孩子是什么血型| hf是什么| 不羁放纵是什么意思| 闲云野鹤指什么生肖| 什么东西止血最快最好| 黄猫来家里有什么预兆| 炖牛肉放什么调料最好| 绒毛膜促性腺激素是什么意思| 双眸是什么意思| 爱是什么词| 雪纳瑞什么颜色最贵| 热伤风感冒吃什么药好| 恨天高是什么意思| 什么叫丹凤眼| 十一朵玫瑰花代表什么意思| 怀孕了尿液是什么颜色| 手上起小水泡是什么原因| 舌根白苔厚是什么原因| 晰字五行属什么| 回家心切什么意思| 桑拓木命是什么意思| 渣滓是什么意思| 轮回什么意思| o型血的人是什么性格| 腋毛有什么作用| 两头尖是什么中药| 载脂蛋白a1偏高是什么原因| 子宫脱垂是什么症状| 去脚气用什么药最好| 高血压用什么药| 青葱岁月是什么意思| 石家庄古代叫什么名字| 被什么虫子咬了会刺痛| 酷暑难当是什么意思| 伪君子是什么意思| poscer是什么牌子| 指什么门| 水银中毒会出现什么状况| 冰箱保鲜室不制冷是什么原因| 发扬什么词语搭配| 男生叫你姑娘什么意思| 意志是什么意思| 肝内胆管结石有什么症状表现| 6.5号是什么星座| 口臭吃什么药| 知我者莫若你什么意思| 突兀什么| 手臂长斑是什么原因| 梦到掉牙齿是什么意思| 杏仁有什么营养| 野生型是什么意思| 佳木斯二院全名叫什么| 路政属于什么单位| 胸口隐隐作痛挂什么科| 灌溉是什么意思| 12月21日是什么星座| 人工流产和无痛人流有什么区别| 10月25是什么星座| 憨厚老实是什么意思| ih医学上是什么意思| 细佬什么意思| 乳腺囊肿有什么症状| 祛是什么意思| 舌头上有红点点是什么原因| 冷艳是什么意思| 蛆长什么样| 扎西德勒是什么意思| 今天过生日是什么星座| 多吃黄瓜有什么好处| 耳朵背后有痣代表什么| 指数是什么| 肝脏低密度影是什么意思| 疏肝解郁喝什么茶| 优雅从容的意思是什么| 谶语是什么意思| 八月十七是什么星座| 儿童乳房发育挂什么科| 紫癜是一种什么病| me是什么基团| 犹太人为什么叫犹太人| 发冷发热是什么原因| kj是什么意思| hds是什么意思| 阳亢是什么意思| 英雄联盟msi是什么| 马赫是什么意思| 餐标是什么意思| 吃维e有什么好处和副作用| 第一次查怀孕挂什么科| 娃娃鱼属于什么类动物| 1970属什么| 梅州有什么大学| 例假可以吃什么水果| 唠嗑是什么意思| 查脂肪肝做什么检查| 莳字五行属什么| 泄是什么意思| 路政属于什么单位| c肽高说明什么| 雌二醇凝胶有什么作用| 田七是什么| 与世无争是什么意思| 苦瓜煮水喝有什么功效| 身体多病戴什么首饰| 什么是直女| 马跟什么生肖最配| 勃起困难是什么原因造成的| 旅行是什么意思| 10月份是什么星座| ich是什么意思| 胆囊是什么| 省公安厅厅长什么级别| 吃山楂有什么好处| 桂花代表什么生肖| 药流前需要做什么检查| 猫咪弓背是什么原因| 大骨头炖什么好吃| 四川代表什么生肖| 霉菌性阴道炎是什么症状| 梦见自己吃面条是什么意思| 口腔溃疡吃什么药| 多梦是什么原因造成的| 漏尿是什么原因| 欣字属于五行属什么| 86年属什么的生肖| 16岁能做什么工作| 成人发烧38度吃什么药| 葡萄糖偏高有什么问题| 亚型是什么意思| 编者按是什么| 为什么牙龈老是出血| 相声海清是什么意思| 为什么尿频| 西洋参和人参有什么区别| 驼背是什么原因造成的| 铁锚是什么意思| 枸杞与菊花一起泡水喝有什么功效| 高考明天考什么| 疡是什么意思| 鸡块炖什么好吃| 月经有黑色血块是什么原因| 手淫是什么意思| 什么动物不喝水| 什么时候绝经| 小脑延髓池是什么意思| 舒坦是什么意思| 梦见捡硬币是什么预兆| 子宫肌瘤有什么危害| 腋下有异味用什么药| 鲜卑族现在是什么族| 红血丝用什么护肤品修复比较好| 脾肾亏虚的症状是什么| 臭屁多是什么原因| 消化不良反酸吃什么药| 活动性胃炎是什么意思| 低钾会出现什么症状| 天上的星星是什么| 宫外孕是什么原因造成的| 抻是什么意思| eeg是什么意思| 六月一日是什么星座| 较重闭合性跌打损伤是什么意思| 突然头晕是什么原因| 北海特产有什么值得带| 什么化妆品好用| 小孩肚子疼拉肚子吃什么药| sf什么意思| 什么是易孕体质| 什么水果助消化| 伏羲姓什么| 读什么| 肌肤甲错是什么意思| 糖化血糖是什么意思| 夏天适合用什么护肤品| 颅内缺血灶是什么病症| 什么情况需要做肠镜| 男性硬下疳是什么样子| 脊椎挂什么科| 家家酒是什么意思| 乙肝病毒表面抗体阳性是什么意思| 流汗有什么好处| 肝是起什么作用的| 把妹什么意思| 考生号是什么| 空气栓塞取什么卧位| 军长什么级别| 又什么又什么式的词语| 女生爱出汗是什么原因| 透明的剑是什么剑| giordano是什么牌子| 什么是中耳炎| 尿钙是什么意思| 高原反应吃什么药| 百度
这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 ? 论坛首页 ? 嵌入式开发 ? STM32 ? 利用STM32F103C8T6的PWM输出制作四路降压模块

共2条 1/1 1 跳转至

利用STM32F103C8T6的PWM输出制作四路降压模块

高工
2025-08-05 15:02:45     打赏
百度 要坚持把政治建设摆在首位,确保中央路线方针政策和重大决策部署在气象部门不折不扣地贯彻落实,严肃党内政治生活,营造良好政治生态。

我在工作中会用到5V12V等常见的电压输出,由于使用开关电源做输出比较麻烦,所以设置一个四路的降压模块,现在将其分享出来给大家参考一下。

降压电路部分采用XL4015左右电压芯片,选用该芯片的考虑点是宽电压输入 8V-36V范围,这个范围基本上在工作中比较容易找到,效率也比较高,具体参数如下图:

图片1.png

设计的电路图如下:

图片2.png

由于单片机采用3.3V工作电压,所以固定一路输出为5V输出,该输出电压也可以为其他负载提供电压输出,在PCB布局时,将5V3.3V输出引出外部提供电压输出。

二:屏幕显示使用的IIC接口的OLED屏幕:资料如下:

采用i2C接口的1.3寸的12864 OLED模块显示,采用该屏幕主要是接线方便,对屏幕的刷新速度要求不高,只是用作显示电压使用;缺点是单色的,看起来并不是很友好。

图片3.png


软件控制部分:硬件设计资料:采用STM32的定时器4PWM输出功能,为了使输出的电压恒定,输出电压经过了两次RC电路,然后 进入运放LM358,这个运放工作时,不需要负电压就可以,而且价格便宜,图纸如下

图片4.png

电压采集部分:将XL4015输出端的电压经过电阻分压进入单片机的ADC采样口,设置分压电路时,需要注意下,输出电压最大时,不能超过单片IO口最高的承受电压的能力。这里需要将输出电压进入单片机内部进行采集,用于检测PWM输出是否正常。

图片5.png

实物测试图片如下:

实物测试图片如下:

主要软件代码如下:

利用ADC检测电压输出是否正常:

//单通道 DMA adc数据
volatile u16 adc_values;
volatile u16 adc_buf[400];

//-------------单通道 ADC读取----------------
void Adc_Init(void) {
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72/6 = 12MHz
    //ADC1通道11的转换时间为T=(239.5+12.5) x 1/12=21us。
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure); 
    ADC_DeInit(ADC1);//复位ADC1
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC 独立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;//单次扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式
    ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC1 和ADC2 工作在同步规则模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1 ;//进行规则转换的ADC通道数量
    ADC_Init(ADC1, &ADC_InitStructure);//初始化ADC1
    ADC_Cmd(ADC1, ENABLE);
    ADC_ResetCalibration(ADC1);//开启复位校准
    while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准成功
    ADC_StartCalibration(ADC1);//开始校验ADC1
    while(ADC_GetCalibrationStatus(ADC1));//等待校验成功
}
u16 get_ADC_Values(u8 ch, u8 rank) {
 
    //设置指定ADC规则通道,设置转换时间
    ADC_RegularChannelConfig(ADC1, ch, rank, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE); //开启软件转换
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); //等待转换结束
    return 	ADC_GetConversionValue(ADC1);
}
//返回ADC平均值
u16 get_ADC_Average(u8 ch, u8 rank, u8 count) {
    u32 temp_val = 0;
    u8 i;
 
    for(i = 0; i < count; i++) {
        temp_val += get_ADC_Values(ch, rank);
        delay_ms(5);
    }
    return temp_val / count; 
}
//-------------单通道 ADC DMA读取----------------
void ADC_DMA_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
	
    //使能DMA1时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);      
  
		//初始化IO 
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;        
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;  
    GPIO_Init(GPIOA,&GPIO_InitStructure);  
 
    //复位DMA1 通道1 ADC
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//ADC内存基地址
    DMA_InitStructure.DMA_MemoryBaseAddr  = (u32)&adc_values;//变量基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到内存
    DMA_InitStructure.DMA_BufferSize = 1;//数据宽度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设内存地址不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//变量内存地址不变
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//16字节 12位ADC
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//16字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);//初始化DMA1 通道1
    DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA 通道1
 
    ADC_DeInit(ADC1);//复位ADC1
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE; //关闭扫描
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换 触发一次 持续转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;//转换一个通道
    ADC_Init(ADC1, &ADC_InitStructure);//初始化ADC
		//ADC时钟 不能大于14MHz
		RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72/6 = 12MHz 
		//设置指定ADC规则通道,设置转换时间
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
    //使能ADC DMA
		ADC_DMACmd(ADC1, ENABLE);
		//使能ADC
    ADC_Cmd(ADC1, ENABLE);
		
		ADC_ResetCalibration(ADC1);//复位校准寄存器  
    while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成  
  
    ADC_StartCalibration(ADC1);//ADC校准  
    while(ADC_GetCalibrationStatus(ADC1));//等待校准完成  
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换 
		
}
//返回ADC平均值
u16 get_ADC_DMA_Average(u8 count) {
    u32 temp_val = 0;
    u8 i;
 
    for(i = 0; i < count; i++) {
        temp_val += adc_values;
        delay_ms(5);
    }
    return temp_val / count;
 
}
//-------------多通道 ADC DMA读取----------------
void ADC_DMA_Multichannel_Init(uint16_t *ADC_Buff) {
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
	
    //使能DMA1时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);      
  
		//初始化IO 
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;        
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;  
    GPIO_Init(GPIOA,&GPIO_InitStructure);  
 
    //复位DMA1 通道1 ADC
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//ADC内存基地址
    DMA_InitStructure.DMA_MemoryBaseAddr  = (u32)ADC_Buff;//变量基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到内存
    DMA_InitStructure.DMA_BufferSize = 400;//数据宽度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设内存地址不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//变量内存地址增长
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//16字节 12位ADC
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//16字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);//初始化DMA1 通道1
    DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA 通道1
 
    ADC_DeInit(ADC1);//复位ADC1
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE; //开启扫描 多通道读取 
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换 触发一次 持续转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 4;//转换3个通道
    ADC_Init(ADC1, &ADC_InitStructure);//初始化ADC
		
  //ADC时钟 不能大于14MHz
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72/6 = 12MHz 
  //设置指定ADC规则通道,设置转换时间
   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);
   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_13Cycles5);
   ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_13Cycles5);
   ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_13Cycles5);
    //使能ADC DMA
		ADC_DMACmd(ADC1, ENABLE);
	//使能ADC
    ADC_Cmd(ADC1, ENABLE);
		
		ADC_ResetCalibration(ADC1);//复位校准寄存器  
    while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成  
  
    ADC_StartCalibration(ADC1);//ADC校准  
    while(ADC_GetCalibrationStatus(ADC1));//等待校准完成  
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换 
		
}

PWM输出控制:

//TIM4 CH1 PWM 输出设置
//PWM 输出初始化
//arr:自动重装值
//psc:时钟预分频数
void Tim4_PWM_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能 TIMx 外设
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能 PB 时钟
	TIM_DeInit(TIM4);
 
  //设置该引脚为复用输出功能,输出 TIM4 CH1 的 PWM 脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; //TIM4_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 GPIO
 
	TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载周期值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化 TIMx
	
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2 模式
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
	
	
	TIM_OCInitStructure.TIM_Pulse = 1800; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //OC1 高电平有效
	TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据指定的参数初始化外设 TIMx
	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH1 预装载使能
	
	
	TIM_OCInitStructure.TIM_Pulse = 1800; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //OC2 高电平有效
	TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据指定的参数初始化外设 TIMx
	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH2 预装载使能
	
	
	TIM_OCInitStructure.TIM_Pulse = 1800; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //OC3 高电平有效
	TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据指定的参数初始化外设 TIMx
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH3 预装载使能
	
	
	TIM_OCInitStructure.TIM_Pulse = 1800; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //OC4 高电平有效
	TIM_OC4Init(TIM4, &TIM_OCInitStructure); //根据指定的参数初始化外设 TIMx
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH4 预装载使能
	
	
	TIM_ARRPreloadConfig(TIM4, ENABLE); //使能 TIMx 在 ARR 上的预装载寄存器
//	TIM_CtrlPWMOutputs(TIM4,ENABLE);  //MOE 主输出使能,高级定时器必须开启
	TIM_Cmd(TIM4, ENABLE); //使能 TIMx
}
void Set_Duty(uint8_t ch,uint16_t value)
{
	switch(ch)
	{
		case 1:
			TIM_SetCompare1(TIM4, value);
			break;
		case 2:
			TIM_SetCompare2(TIM4, value);
			break;
		case 3:
			TIM_SetCompare3(TIM4, value);
			break;
		case 4:
			TIM_SetCompare4(TIM4, value);
			break;
	}	
}   
void Auot_Vol(void)
{
	Set_Duty(3,(float)(Meun.CH2_Vol)*2.321+2207.35+7);
	Set_Duty(2,(float)(Meun.CH3_Vol)*2.321+2207.35+10);
	Set_Duty(1,(float)(Meun.CH4_Vol)*2.321+2207.35+7);
}

界面显示部分:

void MeunDisplay(void)
{
	char buffer[5];
	static char i=50;
	float adv[4]={0};
	int x;
	if(Meun.SecondM == 0 && Meun.FirstM == 0)
	{
		if(Meun.Refresh == 1)
		{
			OLED_Fill(0);//全屏填充
			Meun.Refresh = 0;
			Display_Refresh(0);
			for(x =0;x<100;x++)
			{
				adv[0] += adc_buf[0+x*4];
				adv[1] += adc_buf[1+x*4];
				adv[2] += adc_buf[2+x*4];
				adv[3] += adc_buf[3+x*4];
			}
			adv[0] = adv[0]/100;
			adv[1] = adv[1]/100;
			adv[2] = adv[2]/100;
			adv[3] = adv[3]/100;
			sprintf(buffer,"%4.1fV",(float)adv[3]/4096*3.3*2);
			OLED_ShowStr(24, 3, (uint8_t *)buffer, 1);
			sprintf(buffer,"%4.1fV",(float)adv[2]/4096*3.3*8.5);
			OLED_ShowStr(88, 3, (uint8_t *)buffer, 1);
			sprintf(buffer,"%4.1fV",(float)adv[1]/4096*3.3*8.5);
			OLED_ShowStr(24, 4, (uint8_t *)buffer, 1);
			sprintf(buffer,"%4.1fV",(float)adv[0]/4096*3.3*8.5);
			OLED_ShowStr(88, 4, (uint8_t *)buffer, 1);
			HoldReg[4] = Meun.CH2_Vol;
			HoldReg[5] = Meun.CH3_Vol;
			HoldReg[6] = Meun.CH4_Vol;
			USER_Save();//保存用户数据
		}
		
		if(i % 50 == 0)
		{
			for(x =0;x<100;x++)
			{
				adv[0] += adc_buf[0+x*4];
				adv[1] += adc_buf[1+x*4];
				adv[2] += adc_buf[2+x*4];
				adv[3] += adc_buf[3+x*4];
			}
			adv[0] = adv[0]/100;
			adv[1] = adv[1]/100;
			adv[2] = adv[2]/100;
			adv[3] = adv[3]/100;
			sprintf(buffer,"%4.1fV",(float)adv[3]/4096*3.3*2);
			OLED_ShowStr(24, 3, (uint8_t *)buffer, 1);
			HoldReg[0] = (float)adv[3]/4096*3.3*2*100;
			sprintf(buffer,"%4.1fV",(float)adv[2]/4096*3.3*8.5);
			OLED_ShowStr(88, 3, (uint8_t *)buffer, 1);
			HoldReg[1] = (float)adv[2]/4096*3.3*8.5*100;
			sprintf(buffer,"%4.1fV",(float)adv[1]/4096*3.3*8.5);
			OLED_ShowStr(24, 4, (uint8_t *)buffer, 1);
			HoldReg[2] = (float)adv[1]/4096*3.3*8.5*100;
			sprintf(buffer,"%4.1fV",(float)adv[0]/4096*3.3*8.5);
			OLED_ShowStr(88, 4, (uint8_t *)buffer, 1);
			HoldReg[3] = (float)adv[0]/4096*3.3*8.5*100;
			
			
			if(i == 100)
			{
				OLED_ShowStr(96, 6, (uint8_t *)"*", 2);
				i = 0;
			}
			else if(i == 50)
			{
				OLED_ShowStr(96, 6, (uint8_t *)"  ", 2);
			}
				
		}
		i ++;
	}
	else if(Meun.SecondM == 0)
	{
		if(Meun.Refresh == 1)
		{
			OLED_Fill(0);//全屏填充
			switch(Meun.FirstM)
			{
				case 1:
					Display_Refresh(1);
					break;
				case 2:
					Display_Refresh(2);
					break;
				case 3:
					Display_Refresh(3);
					break;
			}
			Meun.Refresh = 0;
		}
	}
	else
	{
		if(Meun.Refresh == 1)
		{
			OLED_Fill(0);//全屏填充
			Display_Refresh(4);
			Meun.Refresh = 0;
			EDIT_Flag = 1;
		}
		switch(Meun.FirstM)
		{
			case 1:
				sprintf(buffer,"%4.1fV",(float)Meun.CH2_Vol/10);
				OLED_ShowStr(40, 3, (uint8_t *)buffer, 2);
				break;
			case 2:
				sprintf(buffer,"%4.1fV",(float)Meun.CH3_Vol/10);
				OLED_ShowStr(40, 3, (uint8_t *)buffer, 2);
				break;
			case 3:
				sprintf(buffer,"%4.1fV",(float)Meun.CH4_Vol/10);
				OLED_ShowStr(40, 3, (uint8_t *)buffer, 2);
				break;
		}
	}
}

为了节约点成本,数据存储在单片机内部的flash,没有使用存储芯片。

在实际使用过程中发现电压输出并不恒定,用万用表测试可以明显的看出输出电压在0.2V上下跳动,但是这样并不影响使用,其中OUT1固定为5V输出,其他三路为可调电压输出。现在STM32价格貌似是处于下降的趋势,感兴趣的芯查查的小伙伴们可以在下方留下联系方式,方便自己焊接使用。






关键词: STM32F103C8T6     降压     PWM输出     AD    

专家
2025-08-05 19:44:10     打赏
2楼

高手出马,就是不一样!感觉挺实用的设计。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]
鱼油对身体有什么好处 咽后壁淋巴滤泡增生吃什么药 苯醚甲环唑防治什么病 什么的身体 什么天空填动词
gem是什么意思 免疫球蛋白是什么东西 7月12是什么星座 孕妇梦见洪水是什么意思 忌诸事不宜是什么意思
洋葱吃了有什么好处 叶子为什么是绿色的 结肠炎适合吃什么食物 盆腔少量积液是什么问题 女人总犯困是什么原因
起大运是什么意思 哺乳期吃辣椒对宝宝有什么影响 尿多尿频是什么原因造成的 腺肌瘤是什么意思 大力是什么药
轶字五行属什么qingzhougame.com 饱和脂肪是什么hcv9jop7ns4r.cn 女生肾疼是什么原因hcv8jop0ns0r.cn 鸡血藤手镯有什么功效hcv8jop5ns0r.cn 小县城适合做什么生意hcv7jop5ns2r.cn
韩愈是什么朝代的ff14chat.com 妨父母痣是什么意思0735v.com 心肾不交吃什么药hcv9jop1ns4r.cn 什么牌子的空调最好hcv8jop8ns0r.cn 今天什么日hcv8jop5ns7r.cn
五花肉炒什么配菜好吃hcv8jop8ns5r.cn 津液是什么意思hcv8jop5ns6r.cn 梦见死人是什么hcv8jop3ns9r.cn 小孩反复发烧是什么原因引起的hcv9jop7ns9r.cn 骨碎补有什么功效hcv9jop4ns6r.cn
牙龈肿痛吃什么消炎药hcv8jop5ns6r.cn 牙齿发黄是什么原因hcv8jop2ns1r.cn 脸很黄是什么原因hcv7jop6ns2r.cn 得令是什么意思hcv9jop6ns1r.cn 肚子疼拉稀吃什么药imcecn.com
百度