欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
基于stc12c5a60s2單片機(jī)的呼吸燈設(shè)計(jì)
[打印本頁(yè)]
作者:
蔬木果
時(shí)間:
2018-6-25 13:31
標(biāo)題:
基于stc12c5a60s2單片機(jī)的呼吸燈設(shè)計(jì)
我在用stc12c5a60s2做呼吸燈設(shè)計(jì)時(shí)遇到的問(wèn)題,我想設(shè)計(jì)出幾路頻率變化不一樣的pwm波形,我第一個(gè)是利用了C51里面的兩個(gè)計(jì)數(shù)器實(shí)現(xiàn)了呼吸燈設(shè)計(jì),可以使三個(gè)燈做相同頻率的呼吸,
代碼如下://實(shí)現(xiàn)三個(gè)燈的呼吸
#include <reg52.h>
sbit PWMOUT0 = P0^0;
sbit PWMOUT1 = P0^1;
sbit PWMOUT2 = P0^2;
unsigned char HighRH = 0; //高電平重載值的高字節(jié)
unsigned char HighRL = 0; //高電平重載值的低字節(jié)
unsigned char LowRH = 0; //低電平重載值的高字節(jié)
unsigned char LowRL = 0; //低電平重載值的低字節(jié)
unsigned char T1RH = 0;
unsigned char T1RL = 0;
unsigned long PeriodCnt = 0;
void ConfigTimer1(unsigned int ms);
void ConfigPWM(unsigned int fr, unsigned char dc);
void main()
{
EA = 1; //開(kāi)定時(shí)器總中斷
ConfigPWM(100, 10); //配置并啟動(dòng)PWM
ConfigTimer1(50); //用T1定時(shí)調(diào)整占空比
while (1);
}
void ConfigTimer1(unsigned int ms)
{
unsigned long tmp; //臨時(shí)變量
tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率
tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值
tmp = tmp + 12; //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
T1RH = (unsigned char)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié)
T1RL = (unsigned char)tmp;
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x10; //配置T1為模式1
TH1 = T1RH; //加載T1重載值
TL1 = T1RL;
ET1 = 1; //使能T1中斷
TR1 = 1; //啟動(dòng)T1
}
void ConfigPWM(unsigned int fr, unsigned char dc)
{
unsigned int high, low;
PeriodCnt = (11059200/12) / fr; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值
high = (PeriodCnt*dc) / 100; //計(jì)算高電平所需的計(jì)數(shù)值
low = PeriodCnt - high; //計(jì)算低電平所需的計(jì)數(shù)值
high = 65536 - high + 12; //計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
low = 65536 - low + 12; //計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
HighRH = (unsigned char)(high>>8); //高電平重載值拆分為高低字節(jié)
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低電平重載值拆分為高低字節(jié)
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0為模式1
TH0 = HighRH; //加載T0重載值
TL0 = HighRL;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
PWMOUT0 = 1; //輸出高電平
PWMOUT1 = 1; //輸出高電平
PWMOUT2 = 1; //輸出高電平
}
void AdjustDutyCycle(unsigned char dc) //調(diào)整占空比
{
unsigned int high, low;
high = (PeriodCnt*dc)/100;
low = PeriodCnt - high;
high = 65536 - high + 12;
low = 65536 - low + 12;
HighRH = (unsigned char)(high >> 8);
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low >> 8);
LowRL = (unsigned char)low;
}
void InterruptTimer0() interrupt 1 //用定時(shí)器0,實(shí)現(xiàn)了燈的亮滅連續(xù)變化,實(shí)現(xiàn)電平的反轉(zhuǎn)
{
if (PWMOUT0 == 1) //當(dāng)前輸出為高電平時(shí),裝載低電平值并輸出低電平
{
TH0 = LowRH;
TL0 = LowRL;
PWMOUT0 = 0;
PWMOUT1 = 0;
PWMOUT2 = 0;
}
else //當(dāng)前輸出為低電平時(shí),裝載高電平值并輸出高電平
{
TH0 = HighRH;
TL0 = HighRL;
PWMOUT0 = 1;
PWMOUT1 = 1;
PWMOUT2 = 1;
}
}
void InterruptTimer1() interrupt 3
{
unsigned char code table[13] = {
5, 18, 30, 41, 51, 60, 68, 75, 81, 86, 90, 93, 95
};
static bit dir = 0;
static unsigned char index = 0;
TH1 = T1RH;
TL1 = T1RL;
AdjustDutyCycle(table[index]);
if(dir == 0)
{
index++;
if(index >= 12)
{
dir = 1;
}
}
else
{
index--;
if(index == 0)
{
dir = 0;
}
}
}
可是,我并不想看到一樣的頻率變化,我希望三個(gè)燈變化的頻率不一樣,可是上述代碼實(shí)現(xiàn)呼吸燈的效果是基于計(jì)數(shù)器的個(gè)數(shù)的,C51的計(jì)數(shù)器已經(jīng)用完了,我只好把目光投向了stc12c5a60s,這里面不僅有四個(gè)計(jì)數(shù)器,而且有兩路PWM輸出,
我通過(guò)設(shè)置PCA,實(shí)現(xiàn)了通過(guò)按鍵可以實(shí)時(shí)改變輸出波形,
代碼如下:
//利用按鍵s1對(duì)led燈的亮度調(diào)節(jié)
#include"STC12C5A60S2.h"
void delay(unsigned int cnt)
{
unsigned char i;
for(;cnt>0;cnt--)
for(i=0;i<250;i++);
}
void main()
{
EA = 1; //開(kāi)定時(shí)器總中斷
CCON=0; //禁止寄存器CCON中CF位的中斷
CL=0; //PCA的16位計(jì)數(shù)器低8位
CH=0; //PCA的16位計(jì)數(shù)器高8位
CMOD=0x00; //選擇系統(tǒng)時(shí)鐘/12為計(jì)數(shù)脈沖,則PWM的頻率f=sysclk/256/12
//PCA模塊0
CCAP0H=0x80; //占空比控制,此時(shí)的占空比為50%,一路輸出
CCAP0L=0x80;
PCA_PWM0=0x00; //控制占空比的第九位為0
CCAPM0=0x42; //允許P13作為PWM輸出
//PCA模塊1
CCAP1H=0xcc; //占空比控制,此時(shí)的占空比為20%,一路輸出
CCAP1L=0xcc;
PCA_PWM1=0x00;
CCAPM1=0x42; //允許P13作為PWM輸出
CR=1; //啟動(dòng)PCA計(jì)數(shù)器
while(1)
{
if(P10==0)
{
delay(200);
while(P10==0);
CCAP0H+=10; //占空比調(diào)節(jié)
CCAP0L+=10;
CCAP1H+=25; //占空比調(diào)節(jié)
CCAP1L+=25;
}
}
}
可是就在我想結(jié)合兩者的特點(diǎn)一起實(shí)現(xiàn)三個(gè)燈做呼吸燈,另外兩個(gè)燈通過(guò)按鍵做使其的波形不斷變化,因?yàn)檫@在設(shè)計(jì)上我覺(jué)得是行得通的,因?yàn)槲易龊粑鼰魰r(shí),只涉及到51的定時(shí)器,而stc12c5a60s2很好的兼容了51的兩個(gè)定時(shí)器,這樣的話,應(yīng)該是可以同時(shí)出現(xiàn)三個(gè)燈是呼吸燈,最后兩個(gè)燈通過(guò)按鍵調(diào)節(jié)亮度,所以我就把兩個(gè)函數(shù)粘貼在一起了,可是卻沒(méi)有出現(xiàn)應(yīng)有的現(xiàn)象。
問(wèn)題如下:只能通過(guò)按鍵對(duì)最后兩個(gè)燈實(shí)現(xiàn)亮度調(diào)節(jié),而呼吸燈的現(xiàn)象出不來(lái)。
有問(wèn)題的程序如下,不知道怎樣修改,還請(qǐng)大神解惑。
//利用按鍵s1對(duì)led燈的亮度調(diào)節(jié)
#include"STC12C5A60S2.h"
sbit PWMOUT0 = P0^0;
sbit PWMOUT1 = P0^1;
sbit PWMOUT2 = P0^2;
unsigned char HighRH = 0; //高電平重載值的高字節(jié)
unsigned char HighRL = 0; //高電平重載值的低字節(jié)
unsigned char LowRH = 0; //低電平重載值的高字節(jié)
unsigned char LowRL = 0; //低電平重載值的低字節(jié)
unsigned char T1RH = 0;
unsigned char T1RL = 0;
unsigned long PeriodCnt = 0;
void ConfigTimer1(unsigned int ms);
void ConfigPWM(unsigned int fr, unsigned char dc);
void delay(unsigned int cnt)
{
unsigned char i;
for(;cnt>0;cnt--)
for(i=0;i<250;i++);
}
void main()
{
EA = 1; //開(kāi)定時(shí)器總中斷
CCON=0; //禁止寄存器CCON中CF位的中斷
CL=0; //PCA的16位計(jì)數(shù)器低8位
CH=0; //PCA的16位計(jì)數(shù)器高8位
CMOD=0x00; //選擇系統(tǒng)時(shí)鐘/12為計(jì)數(shù)脈沖,則PWM的頻率f=sysclk/256/12
//PCA模塊0
CCAP0H=0x80; //占空比控制,此時(shí)的占空比為50%,一路輸出
CCAP0L=0x80;
PCA_PWM0=0x00; //控制占空比的第九位為0
CCAPM0=0x42; //允許P13作為PWM輸出
//PCA模塊1
CCAP1H=0xcc; //占空比控制,此時(shí)的占空比為80%,一路輸出
CCAP1L=0xcc;
PCA_PWM1=0x00;
CCAPM1=0x42; //允許P13作為PWM輸出
CR=1; //啟動(dòng)PCA計(jì)數(shù)器
while(1)
{
ConfigPWM(100, 10); //配置并啟動(dòng)PWM
ConfigTimer1(50); //用T1定時(shí)調(diào)整占空比
if(P10==0)
{
delay(200);
while(P10==0);
CCAP0H+=10; //占空比調(diào)節(jié)
CCAP0L+=10;
CCAP1H+=25; //占空比調(diào)節(jié)
CCAP1L+=25;
}
}
}
void ConfigTimer1(unsigned int ms)
{
unsigned long tmp; //臨時(shí)變量
tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率
tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值
tmp = tmp + 12; //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
T1RH = (unsigned char)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié)
T1RL = (unsigned char)tmp;
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x10; //配置T1為模式1
TH1 = T1RH; //加載T1重載值
TL1 = T1RL;
ET1 = 1; //使能T1中斷
TR1 = 1; //啟動(dòng)T1
}
void ConfigPWM(unsigned int fr, unsigned char dc)
{
unsigned int high, low;
PeriodCnt = (11059200/12) / fr; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值
high = (PeriodCnt*dc) / 100; //計(jì)算高電平所需的計(jì)數(shù)值
low = PeriodCnt - high; //計(jì)算低電平所需的計(jì)數(shù)值
high = 65536 - high + 12; //計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
low = 65536 - low + 12; //計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
HighRH = (unsigned char)(high>>8); //高電平重載值拆分為高低字節(jié)
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低電平重載值拆分為高低字節(jié)
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0為模式1
TH0 = HighRH; //加載T0重載值
TL0 = HighRL;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
PWMOUT0 = 1; //輸出高電平
PWMOUT1 = 1; //輸出高電平
PWMOUT2 = 1; //輸出高電平
}
void AdjustDutyCycle(unsigned char dc) //調(diào)整占空比
{
unsigned int high, low;
high = (PeriodCnt*dc)/100;
low = PeriodCnt - high;
high = 65536 - high + 12;
low = 65536 - low + 12;
HighRH = (unsigned char)(high >> 8);
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low >> 8);
LowRL = (unsigned char)low;
}
void InterruptTimer0() interrupt 1 //用定時(shí)器0,實(shí)現(xiàn)了燈的亮滅連續(xù)變化,實(shí)現(xiàn)電平的反轉(zhuǎn)
{
if (PWMOUT0 == 1) //當(dāng)前輸出為高電平時(shí),裝載低電平值并輸出低電平
{
TH0 = LowRH;
TL0 = LowRL;
PWMOUT0 = 0;
PWMOUT1 = 0;
PWMOUT2 = 0;
}
else //當(dāng)前輸出為低電平時(shí),裝載高電平值并輸出高電平
{
TH0 = HighRH;
TL0 = HighRL;
PWMOUT0 = 1;
PWMOUT1 = 1;
PWMOUT2 = 1;
}
}
void InterruptTimer1() interrupt 3
{
unsigned char code table[13] = {
5, 18, 30, 41, 51, 60, 68, 75, 81, 86, 90, 93, 95
};
static bit dir = 0;
static unsigned char index = 0;
TH1 = T1RH;
TL1 = T1RL;
AdjustDutyCycle(table[index]);
if(dir == 0)
{
index++;
if(index >= 12)
{
dir = 1;
}
}
else
{
index--;
if(index == 0)
{
dir = 0;
}
}
}
復(fù)制代碼
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1