#include<reg51.h>
unsigned char pwhh,pwhl,pwlh,pwll
bit flag
sbit pwm=P1^0
void t0isr() interrupt 1
{
if(flag)
{
TH0=pwhh
TL0=pwhl
}
else
{
TH0=pwlh
TL0=pwll
}
pwm=~pwm
}
main()
{
TMOD=0x01
pwhh=(65536-1000)/256
pwhl=(65536-1000)%256
pwlh=(65536-500)/256
pwll=(65536-500)%256
TH0=pwhh
L0=pwhl
TR0=1
ET0=1
EA=1
while(1)
}
怎么可能搞不了三路独立的呢?楼下那位是被STC12C5A60S2的硬件蒙蔽了视线,他认为,STC12C只有两路PWM,无法实现3路,你却忘记了最原始的办法,不要说STC12有PWM功能,即使是传统的AT89S52这类没有PWM功能的单片机也一样能够实现楼主的要求.下面我简单的分析一下我的思路,楼主尝试编程,如果不懂,再追问:
你是用三路独立的PWM调光用的,PWM调光,为了保证不让人眼产生闪烁,理论上PWM的频率要大于20Hz,而在实际的测试用,一般PWM要大于25Hz才能保证不闪烁.为了保险起见,我们将PWM的频率设定在30Hz左右,那么,周期就是33.333333ms,假设,我们实现10级调光,那个 每级的时间是3.33333ms
然后设置三个变量和一个计数器,我描述不太清楚,你看一下程序:
sbit P1_0 = P1^0//---P1.0,P1.1,P1.2是三路PWM输出
unsigned char Set_PWM0 = 0//--Set_PWM0 Set_PWM1 Set_PWM2
//--分别是低电平占整个脉冲的百分比
//--他们最小取0,最大取9
unsigned char counter = 0//--用于计数的
void ISR_Timer0(void) interrupt 1 //---我们就用定时器0来做,不用PWM硬件
{ //----3.3333ms中断一次
counter++
if(counter >= 10) counter = 0
if(counter >= Set_PWM0) P1_0 = 0else P1_0 = 1
if(counter >= Set_PWM1) P1_1 = 0else P1_1 = 1
if(counter >= Set_PWM2) P1_2 = 0else P1_2 = 1
}
这样,定时器0用于决定PWM的反占空比,你只要设置 Set_PWM0等三个参数就可以了.
怎么会实现不了呢?
#include <intrins.h>#include <stdio.h>
#include <math.h>
#include "UPSD3200.H"
#include "upsd_pwm.h"
#define uint unsigned int
#define uchar unsigned char
PSD_REGS PSD8xx_reg _at_ csiop
#define KEYIO (~(PSD8xx_reg.DATAIN_A)) &0x07
sbit CP=P4^7
sbit U_D=P1^1
void init_system()// 系统初始化
uchar keyboard()
void uPSD_PWM4_Variable(unsigned char PWM_Period, unsigned char PWM_PulseWidth)
uchar Adjust_station=NO
unsigned char data x,flag
unsigned char keyboard() //键盘输入
{
unsigned char a=0xff,b=0x01,c=0xf8,d//有按键的位置
uint i
do{
a=KEYIO|c
}while(a==0xff)
if (a == 0xfe){d = '1'}
else if (a == 0xfd){d = '2'}
else if (a == 0xfb){d = '3'}
else {d = '0'}
return(d)
}
void uPSD_PWM4_Init(void)
unsigned int PWM_prescaler
P4SFS |= 0x80
PWM_prescaler = (unsigned int)((FREQ_OSC/2)/PWM4_INPUT_freq)//PWM4输入脉冲频率 K
PSCL1L = PWM_prescaler &0x00ff
PSCL1H = (PWM_prescaler >>8)
}
void StepMotor_GO(bit direction,uint speed) {
unsigned char PWM_Period, PWM_PulseWidth
uint temp_uint
U_D = direction//方向
temp_uint = (PWM4_INPUT_freq*1000)/speed
PWM_Period = (unsigned char)temp_uint
PWM_PulseWidth = PWM_Period/2
uPSD_PWM4_Variable(PWM_Period,PWM_PulseWidth)
}
void StepMotor_STOP(void)
{
P4SFS &= 0x7f
}
void uPSD_PWM4_Variable(unsigned char PWM_Period, unsigned char PWM_PulseWidth)
{
P4SFS |= 0x80
PWMVP = PWM_Period
PWMVPW = PWM_PulseWidth
PWMCON |= 0x20
}
void initkey(void){
PSD8xx_reg.DATAOUT_A=0xFF
PSD8xx_reg.CONTROL_A=0x00
PSD8xx_reg.DIRECTION_A=0x00
}
void init_system() // 系统初始化
{
WDKEY=0x55
P4SFS = (unsigned char) (0x08 <<3)
uPSD_PWM_Channel_8bit(3,243)
问题补充:(接着上面的序)
void uPSD_PWM_Init_8bit(unsigned char PWM_channel_no, unsigned int PWM_freq8, unsigned char PWMCON_value)
{
unsigned int PWM_prescaler
unsigned char output_polarity_mode
output_polarity_mode = PWMCON_value &0x8F
PWMCON = (PWMCON &0x70) | output_polarity_mode
P4SFS = (unsigned char) (0x08 <<PWM_channel_no)
PWM_prescaler = (unsigned int) ( (((unsigned int) FREQ_OSC) / 2) / PWM_freq8)
PSCL0L = PWM_prescaler &0x00ff
PSCL0H = (PWM_prescaler >>8)
PSCL1L = PWM_prescaler &0x00ff
PSCL1H = (PWM_prescaler >>8)
}
void uPSD_PWM_Disable(void)
{
PWMCON &= 0xDF
}
void main(void){
x=0
init_system()
flag=1
while(flag==1){
x=keyboard()
if(x=='1') {StepMotor_GO(0,100)}
else if(x=='2') {StepMotor_GO(1,500)}
else if(x=='3') { StepMotor_STOP()uPSD_PWM_Disable()}
else if(x=='0') {uPSD_PWM_Disable()}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)