003818jdf8m856kdd8nk1e.png (368.85 KB)
下載附件
2021-5-9 20:16 上傳
以前用過STC15W的8位PWM,配置很簡單。
數據手冊上也有參考代碼。
一直渴望STC能出8個腳帶AD的單片機,終于等到了,去年STC8G系列上市。這款芯片帶10位ADC,6/7/8/10位硬件PWM等待。價格0.8元左右。
這幾天公司接了個電位器調光的項目,這讓我想到了STC8G1K08A單片機,自帶的功能剛才滿足產品要求。
說實在的,真心不敢用。畢竟是新品,也不知道質量咋樣?抱著支持國產芯片的想法,決定試試。
說干就干,于是在某一個寶上買了幾片。這個調光產品主要用到ADC和PWM。
測試ADC,沒問題!
測試8位PWM,沒問題!(以前玩過15系列的,代碼基本相同)
想著有10位的PWM干嘛要用8位的呢?決定用10位的PWM.
結果搞了一天,愣是沒搞出來。有波形輸出,但是不是自己想要的波形。半夜了,睡覺吧!!!!!
這里說明下關于PWM寄存器:
005110b7u6a4m5zn66617c.png (157.22 KB)
下載附件
2021-5-9 20:16 上傳
005126w0n7re9n0qtm0dxg.png (133.77 KB)
下載附件
2021-5-9 20:16 上傳
005136rba4yqj8dc1za8c8.png (198.04 KB)
下載附件
2021-5-9 20:16 上傳
10位PWM重裝值和比較值的高2位和低8位在兩個寄存器,PCA_PWMn和CCAPnH。
以前寫代碼習慣了根據數據手冊的寄存器從上往下配置,特殊寄存器除外。
以前配置8位PWM初始化代碼如下:
- //8位PWM_PCA初始化
- void PCA_Init()
- {
- CCON=0x00; //關閉PCA計數器,清除相關標志位
- CMOD=PCA_SYSCLK2; //PCA時鐘源為系統時鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
- CL =0x00; //計數器清零
- 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; //啟動計數器
- }
復制代碼
這樣,調節自己想要的占空比就OK了,8位PWM正常使用。所以,覺得修改PWM位數就行了。
于是,10位PWM配置如下:
- //10位PWM_PCA初始化
- //用電位器調節占空比
- void PCA_Init()
- {
- CCON=0x00; //關閉PCA計數器,清除相關標志位
- CMOD=PCA_SYSCLK2; //PCA時鐘源為系統時鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
- CL =0x00; //計數器清零
- 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; //啟動計數器
- }
復制代碼
調節占空比的時候用示波器觀察波形,發現波形不對,波形的確是10位的,這點可以肯定。數據手冊看了一遍又一遍,覺得代碼沒問題啊。
實在沒辦法了。后來添加了串口功能,決定把相關寄存器通過串口發出來看看。
通過觀察發現,PWM重裝值高2位永遠是00,低8位沒問題,調節占空比的代碼如下:
- //設置脈沖寬度
- void PWM0_Set_Duty(u16 Duty)
- {
- //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
- PCA_PWM0&= ~(3<<4); //清零重裝值高2位
- PCA_PWM0|= (Duty>>4)&0x30; //設置新的重裝值高2位
- CCAP0H = Duty; //重裝值低8位
- }
復制代碼
這樣寫應該沒錯啊,咋回事呢?
于是在main函數里測試下:
- void main()
- {
- u8 st;
-
- P_SW2|=0x80; //可以訪問擴展的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();
- }
- }
復制代碼
結果發現,串口發出來的是0xCF。明明賦值0xFF,為啥讀出來的卻是0xCF呢?明擺著那兩個位沒寫進去。奇怪了!!!
于是我把//PCA_Init();初始化函數注釋掉.再來測試下,給PCA_PWM0寄存器賦值0xFF,讀出來是0xFF。可以寫進去了。
這就證明問題出在PCA_Init();初始化函數。回頭看看初始化函數.....................省略繁瑣的過程............................!
最后發現是CCAPM0寄存器的問題,這個寄存器我用到了,允許比較功能和使能PWM 輸出。
問題就出在使能PWM輸出這個位上。使能了PWM輸出,Pwm重裝值高2位就寫不進去,也就沒辦法調節占空比。
013446ghmz1f2b7sdb7lfa.png (44.83 KB)
下載附件
2021-5-9 20:16 上傳
這和資料上的最后一句話是不是沖突了。這算不算一個BUG呢。
在修改重裝值前,先禁止PWM 輸出,修改好后再打開。這能算無干擾嗎???
最后代碼修改如下:
- //10位PWMPCA初始化
- void PCA_Init()
- {
- CCON=0x00; //關閉PCA計數器,清除相關標志位
- CMOD=PCA_SYSCLK2; //PCA時鐘源為系統時鐘2分頻 33.1776/2/1024=0.0162MHZ ==>16.2KHZ
- CL =0x00; //計數器清零
- 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; //啟動計數器
- }
- //設置脈沖寬度
- void PWM0_Set_Duty(u16 Duty)
- {
- //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
-
- CCAPM0 = 0x40; //失能PCA模塊0_PWM輸出
- PCA_PWM0&= ~(3<<4); //清零重裝值高2位
- PCA_PWM0|= (Duty>>4)&0x30; //設置新的重裝值高2位
- CCAP0H = Duty; //重裝值低8位
- CCAPM0 = 0x42; //使能PCA模塊0_PWM輸出
- }
- //設置脈沖寬度
- void PWM1_Set_Duty(u16 Duty)
- {
- //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
-
- CCAPM1 = 0x40; //失能PCA模塊1_PWM輸出
- PCA_PWM1&= ~(3<<4); //清零重裝值高2位
- PCA_PWM1|= (Duty>>4)&0x30; //設置新的重裝值高2位
- CCAP1H = Duty; //重裝值低8位
- CCAPM1 = 0x42; //使能PCA模塊0_PWM輸出
- }
復制代碼
【必讀】版權免責聲明
1、本主題所有言論和內容純屬會員個人意見,與本論壇立場無關。2、本站對所發內容真實性、客觀性、可用性不做任何保證也不負任何責任,網友之間僅出于學習目的進行交流。3、對提供的數字內容不擁有任何權利,其版權歸原著者擁有。請勿將該數字內容進行商業交易、轉載等行為,該內容只為學習所提供,使用后發生的一切問題與本站無關。 4、本網站不保證本站提供的下載資源的準確性、安全性和完整性;同時本網站也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的損失或傷害。 5、本網站所有軟件和資料均為網友推薦收集整理而來,僅供學習用途使用,請務必下載后兩小時內刪除,禁止商用。6、如有侵犯你版權的,請及時聯系我們(電子郵箱1370723259@qq.com)指出,本站將立即改正。
|