下面利用PWM实现呼吸灯:
#include "SC95F861x_C.H"
#include "intrins.H"
volatile unsigned int TimeTick;
unsigned int Pwm_duty;
unsigned char Pwm_flag;
unsigned int xdata PWMRD_40 _at_ 0x1040;
unsigned int xdata PWMRD_41 _at_ 0x1042;
unsigned int xdata PWMRD_42 _at_ 0x1044;
unsigned int xdata PWMRD_43 _at_ 0x1046;
unsigned int xdata PWMRD_50 _at_ 0x1048;
unsigned int xdata PWMRD_51 _at_ 0x104A;
unsigned int xdata PWMRD_52 _at_ 0x104C;
unsigned int xdata PWMRD_53 _at_ 0x104E;
//==========================================================
//=======================================================
void Uart0_Init(unsigned long baud)
{
//Uart0初始化 P20=RX,P21=TX
SCON = 0X50; //异步10bit通信,允许接收
//Timer1波特率 baud=sysclk(32MHz)/(TH1:TL1)
TMOD = 0X11;
TCON = 0X00;
TMCON = 0X00;
TL1 = 32*1000000/baud; //波特率低位控制
TH1 = (32*1000000/baud)>>8; //波特率高位控制
TR1 = 0;
EUART = 0; //串口中断使能off
}
void Uart0Send(unsigned char ch)
{
SBUF = ch;
while(TI == 0);
TI = 0;
}
void Uart0SendStr(unsigned char *s)
{
while(*s != 0)
{
Uart0Send(*s++);
}
}
void Uart0SendStrlen(unsigned char *s,unsigned int len)
{
while(len != 0)
{
Uart0Send(*s++);
len--;
}
}
//=================================================================
//
//=================================================================
volatile unsigned int Time_1ms;
void Delay_ms(unsigned int ms)
{
Time_1ms = ms;
while(Time_1ms);
}
//=============================================================
void Timer0_Init(void)
{
//Timer0
TMOD = 0X11; //16位定时器
TCON = 0X00;
TMCON = 0X00; //12分频
TL0 = (65536-(32000000)/(12*1000)); //定时1ms
TH0 = (65536-(32000000)/(12*1000))>>8; //
TR0 = 1;
ET0 = 1; //中断
}
//============================================
//周期 (0x63F+1)/32(MHz) = 50us 周期
//占空比 0x320/(0x63F+1) = 50%
void PWM_Init(void)
{
PWMMOD = 0x00; //独立模式,边沿对齐
PWMCFG = 0x86; //7:开关 5-4:时钟源选择 3-0:周期设置高4位
PWMCON = 0x3F; //周期设置低8位,50us
PWMRD_52 = 0x8000 | 0x320; //开启PWM口,设置占空比
PWMRD_53 = 0x8000 | 0x320; //开启PWM口,设置占空比
IE1 |= 0x02; //开启中断标志位
}
//==============================================
int main(void)
{
P0CON = 0x00; //设置P0为输入带上拉模式
P0PH = 0xFF;
P1CON = 0x00; //设置P1为高阻输入模式
P1PH = 0x00;
P2CON = 0xFC; //设置P20,P21为输入带上拉模式,其他推挽输出
P2PH = 0xFF;
P3CON = 0xFF; //设置P3为强推挽模式
P3PH = 0x00;
P4CON = 0xFF; //设置P4为强推挽模式
P4PH = 0x01;
P5CON = 0xFF; //设置P5为强推挽模式
P5PH = 0x00;
TimeTick = 0;
Pwm_duty = 0x320;
Pwm_flag = 0;
Uart0_Init(115200);
Timer0_Init();
PWM_Init();
EA = 1;
Delay_ms(1000);
while(1)
{
Delay_ms(100);
Uart0SendStr("SinOne SC95F8617 Test. By WoodData.\n");
PWMRD_52 = 0x8000 | Pwm_duty; //开启PWM口,设置占空比
PWMRD_53 = 0x8000 | Pwm_duty; //开启PWM口,设置占空比
if(Pwm_flag == 0)
{
Pwm_duty += 0x10;
if(Pwm_duty >= 0x640)
{
Pwm_flag = 1;
}
}else
{
Pwm_duty -= 0x10;
if(Pwm_duty <= 0x320)
{
Pwm_flag = 0;
}
}
}
return 0;
}
//===============================================
//中断
void Timer0_ISR() interrupt 1
{
TL0 = (65536-(32000000)/(12*1000)); //定时1ms
TH0 = (65536-(32000000)/(12*1000))>>8; //
if(Time_1ms) Time_1ms--;
TimeTick++;
}
void PWM_Interrup() interrupt 8
{
if(PWMCFG & 0x40)
{
PWMCFG &= ~0x40; //清除中断标志位
}
}
void Uart0_ISR() interrupt 4
{
if(TI)
{
TI = 0;
}
if(RI)
{
RI = 0;
}
}
|