|
以前用過(guò)STC15W的8位PWM,配置很簡(jiǎn)單。
數(shù)據(jù)手冊(cè)上也有參考代碼。
一直渴望STC能出8個(gè)腳帶AD的單片機(jī),終于等到了,去年STC8G系列上市。這款芯片帶10位ADC,6/7/8/10位硬件PWM等待。價(jià)格0.8元左右。
這幾天公司接了個(gè)電位器調(diào)光的項(xiàng)目,這讓我想到了STC8G1K08A單片機(jī),自帶的功能剛才滿足產(chǎn)品要求。
說(shuō)實(shí)在的,真心不敢用。畢竟是新品,也不知道質(zhì)量咋樣?抱著支持國(guó)產(chǎn)芯片的想法,決定試試。
說(shuō)干就干,于是在某一個(gè)寶上買了幾片。這個(gè)調(diào)光產(chǎn)品主要用到ADC和PWM。
測(cè)試ADC,沒(méi)問(wèn)題!
測(cè)試8位PWM,沒(méi)問(wèn)題。ㄒ郧巴孢^(guò)15系列的,代碼基本相同)
想著有10位的PWM干嘛要用8位的呢?決定用10位的PWM.
結(jié)果搞了一天,愣是沒(méi)搞出來(lái)。有波形輸出,但是不是自己想要的波形。半夜了,睡覺(jué)吧。。。!
這里說(shuō)明下關(guān)于PWM寄存器:
10位PWM重裝值和比較值的高2位和低8位在兩個(gè)寄存器,PCA_PWMn和CCAPnH。
以前寫代碼習(xí)慣了根據(jù)數(shù)據(jù)手冊(cè)的寄存器從上往下配置,特殊寄存器除外。
以前配置8位PWM初始化代碼如下:
//8位PWM_PCA初始化
void PCA_Init()
{
CCON=0x00; //關(guān)閉PCA計(jì)數(shù)器,清除相關(guān)標(biāo)志位
CMOD=PCA_SYSCLK2; //PCA時(shí)鐘源為系統(tǒng)時(shí)鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
CL =0x00; //計(jì)數(shù)器清零
CH =0x00;
/*------------------------PWM0部分-----------------------------*/
CCAPM0=0x42; //使能PCA模塊0_PWM輸出
CCAP0L=0X00; //捕獲比較寄存器低8位,比較值
CCAP0H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM0=0x00; //8位PWM輸出
/*------------------------PWM1部分-----------------------------*/
CCAPM1=0x42; //使能PCA模塊0_PWM輸出
CCAP1L=0X00; //捕獲比較寄存器低8位,比較值
CCAP1H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM1=0x00; //8位PWM輸出
CCON|= 1<<6; //啟動(dòng)計(jì)數(shù)器
}
這樣,調(diào)節(jié)自己想要的占空比就OK了,8位PWM正常使用。所以,覺(jué)得修改PWM位數(shù)就行了。
于是,10位PWM配置如下:
//10位PWM_PCA初始化
//用電位器調(diào)節(jié)占空比
void PCA_Init()
{
CCON=0x00; //關(guān)閉PCA計(jì)數(shù)器,清除相關(guān)標(biāo)志位
CMOD=PCA_SYSCLK2; //PCA時(shí)鐘源為系統(tǒng)時(shí)鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
CL =0x00; //計(jì)數(shù)器清零
CH =0x00;
/*------------------------PWM0部分-----------------------------*/
CCAPM0=0x42; //使能PCA模塊0_PWM輸出
CCAP0L=0X00; //捕獲比較寄存器低8位,比較值
CCAP0H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM0=0xC0; //10位PWM輸出
/*------------------------PWM1部分-----------------------------*/
CCAPM1=0x42; //使能PCA模塊0_PWM輸出
CCAP1L=0X00; //捕獲比較寄存器低8位,比較值
CCAP1H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM1=0xC0; //10位PWM輸出
CCON|= 1<<6; //啟動(dòng)計(jì)數(shù)器
}
調(diào)節(jié)占空比的時(shí)候用示波器觀察波形,發(fā)現(xiàn)波形不對(duì),波形的確是10位的,這點(diǎn)可以肯定。數(shù)據(jù)手冊(cè)看了一遍又一遍,覺(jué)得代碼沒(méi)問(wèn)題啊。
實(shí)在沒(méi)辦法了。后來(lái)添加了串口功能,決定把相關(guān)寄存器通過(guò)串口發(fā)出來(lái)看看。
通過(guò)觀察發(fā)現(xiàn),PWM重裝值高2位永遠(yuǎn)是00,低8位沒(méi)問(wèn)題,調(diào)節(jié)占空比的代碼如下:
//設(shè)置脈沖寬度
void PWM0_Set_Duty(u16 Duty)
{
//注意:在更新 10 位 PWM 的重載值時(shí),必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
PCA_PWM0&= ~(3<<4); //清零重裝值高2位
PCA_PWM0|= (Duty>>4)&0x30; //設(shè)置新的重裝值高2位
CCAP0H = Duty; //重裝值低8位
}
這樣寫應(yīng)該沒(méi)錯(cuò)啊,咋回事呢?
于是在main函數(shù)里測(cè)試下:
void main()
{
u8 st;
P_SW2|=0x80; //可以訪問(wèn)擴(kuò)展的RAM
UART1_Init();
ADC_Init();
PCA_Init();
Timer0_Init();
SCH_Task_Init();
st=SCH_Task_Add(PWM_Out,30,30,0,ENABLE);
Timer0_Cmd(ENABLE);
PCA_PWM0=0xFF;
UART1_SendByte(PCA_PWM0);
while(1)
{
SCH_Task_Dispatch();
}
}
結(jié)果發(fā)現(xiàn),串口發(fā)出來(lái)的是0xCF。明明賦值0xFF,為啥讀出來(lái)的卻是0xCF呢?明擺著那兩個(gè)位沒(méi)寫進(jìn)去。奇怪了。!
于是我把//PCA_Init();初始化函數(shù)注釋掉.再來(lái)測(cè)試下,給PCA_PWM0寄存器賦值0xFF,讀出來(lái)是0xFF。可以寫進(jìn)去了。
這就證明問(wèn)題出在PCA_Init();初始化函數(shù);仡^看看初始化函數(shù).....................省略繁瑣的過(guò)程............................!
最后發(fā)現(xiàn)是CCAPM0寄存器的問(wèn)題,這個(gè)寄存器我用到了,允許比較功能和使能PWM 輸出。
問(wèn)題就出在使能PWM輸出這個(gè)位上。使能了PWM輸出,Pwm重裝值高2位就寫不進(jìn)去,也就沒(méi)辦法調(diào)節(jié)占空比。
這和資料上的最后一句話是不是沖突了。這算不算一個(gè)BUG呢。
在修改重裝值前,先禁止PWM 輸出,修改好后再打開(kāi)。這能算無(wú)干擾嗎???
最后代碼修改如下:
//10位PWMPCA初始化
void PCA_Init()
{
CCON=0x00; //關(guān)閉PCA計(jì)數(shù)器,清除相關(guān)標(biāo)志位
CMOD=PCA_SYSCLK2; //PCA時(shí)鐘源為系統(tǒng)時(shí)鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
CL =0x00; //計(jì)數(shù)器清零
CH =0x00;
/*------------------------PWM0部分-----------------------------*/
CCAPM0 = 0x40; //失能PCA模塊0_PWM輸出
CCAP0L=0X00; //捕獲比較寄存器低8位,比較值
CCAP0H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM0=0xC0; //10位PWM輸出
CCAPM0=0x42; //使能PCA模塊0_PWM輸出
/*------------------------PWM1部分-----------------------------*/
CCAPM1 = 0x40; //失能PCA模塊1_PWM輸出
CCAP1L=0X00; //捕獲比較寄存器低8位,比較值
CCAP1H=0X00; //捕獲比較寄存器高8位,重裝值
PCA_PWM1=0xC0; //10位PWM輸出
CCAPM1=0x42; //使能PCA模塊0_PWM輸出
CCON|= 1<<6; //啟動(dòng)計(jì)數(shù)器
}
//設(shè)置脈沖寬度
void PWM0_Set_Duty(u16 Duty)
{
//注意:在更新 10 位 PWM 的重載值時(shí),必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
CCAPM0 = 0x40; //失能PCA模塊0_PWM輸出
PCA_PWM0&= ~(3<<4); //清零重裝值高2位
PCA_PWM0|= (Duty>>4)&0x30; //設(shè)置新的重裝值高2位
CCAP0H = Duty; //重裝值低8位
CCAPM0 = 0x42; //使能PCA模塊0_PWM輸出
}
//設(shè)置脈沖寬度
void PWM1_Set_Duty(u16 Duty)
{
//注意:在更新 10 位 PWM 的重載值時(shí),必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
CCAPM1 = 0x40; //失能PCA模塊1_PWM輸出
PCA_PWM1&= ~(3<<4); //清零重裝值高2位
PCA_PWM1|= (Duty>>4)&0x30; //設(shè)置新的重裝值高2位
CCAP1H = Duty; //重裝值低8位
CCAPM1 = 0x42; //使能PCA模塊0_PWM輸出
}
以上是個(gè)人見(jiàn)解,如有說(shuō)錯(cuò)的,請(qǐng)大家指出,我會(huì)虛心求教!!
|
評(píng)分
-
查看全部評(píng)分
|