本帖最后由 wulin 于 2020-8-7 15:58 编辑
不必搞那么复杂,用PWM通过运放滤波放大控制LM317,输出电压通过运算可得,实际电路参数微调一下即可。运放最大输出电压=VCC-1.5V,所以用12V电源不行。LM324/358最大电源电压的32V,放心使用。仿真简图和示例程序如下:
- #include<reg52.h>
- #define key_S 10 //宏定义短按(约10ms)
- #define key_L key_S*35 //宏定义长按(约500ms)
- #define key_I key_S*27 //宏定义长按连+/-间隔(约120ms)
- #define uint unsigned int
- #define uchar unsigned char
- sbit OUT =P2^4;
- sbit key1=P2^5;
- sbit key2=P2^6;
- unsigned char code table[]={//共阳数码管段码"0~f-."
- 0xc0,0xf9,0xa4,0xb0,
- 0x99,0x92,0x82,0xf8,
- 0x80,0x90,0x88,0x83,
- 0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
- uchar data dis_buf[4];
- unsigned char num=0;
- unsigned int count=0,V_IN;
- bit sign=0;
- void delay(unsigned int k)
- {
- unsigned int i,j;
- for(i=k;i>0;i--)
- for(j=110;j>0;j--);
- }
- void keyscan() //按键扫描
- {
- static unsigned int time=0;
- if(!key1||!key2)
- {
- time++;
- if(time>key_L)//长按有效
- time=key_I;//连+/-间隔
- if(time==key_S||time==key_L)//短按消抖+/-或长按连+/-
- {
- if(!key1)//++
- {
- if(count<100)
- count++;//步进电压0.1875
- }
- if(!key2)//--
- {
- if(count>0)
- count--;
- }
- }
- }
- else time=0;
- }
- void Timer0Init() //100微秒@12.000MHz
- {
- TMOD= 0x02; //设置T0自动重装模式
- TL0 = 0x9C; //设置定时初值
- TH0 = 0x9C; //设置定时重载值
- TR0 = 1; //定时器0开始计时
- EA = 1; //开总中断
- ET0 = 1; //开T0中断
- }
- void display(void)
- {
- static uchar i=0;
- dis_buf[0]=table[V_IN/1000];//数据分解
- dis_buf[1]=table[V_IN/100%10];
- dis_buf[2]=table[V_IN/10%10];
- dis_buf[3]=table[V_IN%10];
- P0=0xff; //段码消隐
- P2&=0xf0; //位码清0
- if(i==1)
- P0=dis_buf[i]&0x7f;//送段码加点
- else
- P0=dis_buf[i]; //送段码不加点
- P2|=0x01<<i; //送位码
- i++;
- i%=4;
- }
- void main(void)
- {
- Timer0Init();
- while(1)
- {
- keyscan();
- V_IN=(count*187.5+1250+5)/10;//电压换算(放大1000/10四舍五入)
- display();
- delay(1);
- }
- }
- void Timer0Interrupt(void) interrupt 1
- {
- num++;
- if(num>100)
- num=0;
- if(count>=num)//PWM
- OUT=1;
- else OUT=0;
- }
复制代码
|