国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee

 找回密碼
 注冊
搜索

關于STC8G單片機的PCA_10PWM輸出注意事項

[復制鏈接]
樓主
關于STC8G單片機的PCA_10PWM輸出注意事項 003818jdf8m856kdd8nk1e.png

以前用過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寄存器:
關于STC8G單片機的PCA_10PWM輸出注意事項 005110b7u6a4m5zn66617c.png 關于STC8G單片機的PCA_10PWM輸出注意事項 005126w0n7re9n0qtm0dxg.png 關于STC8G單片機的PCA_10PWM輸出注意事項 005136rba4yqj8dc1za8c8.png

10位PWM重裝值和比較值的高2位和低8位在兩個寄存器,PCA_PWMn和CCAPnH。
以前寫代碼習慣了根據數據手冊的寄存器從上往下配置,特殊寄存器除外。
以前配置8位PWM初始化代碼如下:
  1. //8位PWM_PCA初始化
  2. void PCA_Init()
  3. {
  4.         CCON=0x00;  //關閉PCA計數器,清除相關標志位
  5.         CMOD=PCA_SYSCLK2;  //PCA時鐘源為系統時鐘2分頻  33.1776/2/1024=0.0162MHZ ==>16.2KHZ
  6.         CL  =0x00;  //計數器清零
  7.         CH  =0x00;
  8. /*------------------------PWM0部分-----------------------------*/
  9.         CCAPM0=0x42; //使能PCA模塊0_PWM輸出
  10.         CCAP0L=0X00;    //捕獲比較寄存器低8位,比較值
  11.         CCAP0H=0X00;    //捕獲比較寄存器高8位,重裝值
  12.         PCA_PWM0=0x00;  //8位PWM輸出        
  13. /*------------------------PWM1部分-----------------------------*/
  14.         CCAPM1=0x42; //使能PCA模塊0_PWM輸出
  15.         CCAP1L=0X00;    //捕獲比較寄存器低8位,比較值
  16.         CCAP1H=0X00;    //捕獲比較寄存器高8位,重裝值
  17.         PCA_PWM1=0x00; //8位PWM輸出

  18.         CCON|=  1<<6;   //啟動計數器
  19. }
復制代碼


這樣,調節自己想要的占空比就OK了,8位PWM正常使用。所以,覺得修改PWM位數就行了。
于是,10位PWM配置如下:
  1. //10位PWM_PCA初始化
  2. //用電位器調節占空比
  3. void PCA_Init()
  4. {
  5.         CCON=0x00;  //關閉PCA計數器,清除相關標志位
  6.         CMOD=PCA_SYSCLK2;  //PCA時鐘源為系統時鐘2分頻  33.1776/2/1024=0.0162MHZ ==>16.2KHZ
  7.         CL  =0x00;  //計數器清零
  8.         CH  =0x00;
  9. /*------------------------PWM0部分-----------------------------*/
  10.         CCAPM0=0x42; //使能PCA模塊0_PWM輸出
  11.         CCAP0L=0X00;    //捕獲比較寄存器低8位,比較值
  12.         CCAP0H=0X00;    //捕獲比較寄存器高8位,重裝值
  13.         PCA_PWM0=0xC0;  //10位PWM輸出        
  14. /*------------------------PWM1部分-----------------------------*/
  15.         CCAPM1=0x42; //使能PCA模塊0_PWM輸出
  16.         CCAP1L=0X00;    //捕獲比較寄存器低8位,比較值
  17.         CCAP1H=0X00;    //捕獲比較寄存器高8位,重裝值
  18.         PCA_PWM1=0xC0; //10位PWM輸出

  19.         CCON|=  1<<6;   //啟動計數器
  20. }
復制代碼

調節占空比的時候用示波器觀察波形,發現波形不對,波形的確是10位的,這點可以肯定。數據手冊看了一遍又一遍,覺得代碼沒問題啊。
實在沒辦法了。后來添加了串口功能,決定把相關寄存器通過串口發出來看看。
通過觀察發現,PWM重裝值高2位永遠是00,低8位沒問題,調節占空比的代碼如下:
  1. //設置脈沖寬度
  2. void PWM0_Set_Duty(u16 Duty)
  3. {
  4.         //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
  5.         PCA_PWM0&= ~(3<<4);        //清零重裝值高2位
  6.         PCA_PWM0|= (Duty>>4)&0x30; //設置新的重裝值高2位
  7.         CCAP0H   = Duty;           //重裝值低8位
  8. }
復制代碼

這樣寫應該沒錯啊,咋回事呢?
于是在main函數里測試下:
  1. void main()
  2. {
  3.         u8 st;
  4.         
  5.         P_SW2|=0x80; //可以訪問擴展的RAM        
  6.         UART1_Init();        
  7.         ADC_Init();
  8.         PCA_Init();
  9.         Timer0_Init();
  10.         SCH_Task_Init();
  11.         
  12.         st=SCH_Task_Add(PWM_Out,30,30,0,ENABLE);        
  13.         Timer0_Cmd(ENABLE);
  14.         
  15.         PCA_PWM0=0xFF;
  16.         UART1_SendByte(PCA_PWM0);
  17.         while(1)
  18.         {
  19.                 SCH_Task_Dispatch();
  20.         }
  21. }
復制代碼

結果發現,串口發出來的是0xCF。明明賦值0xFF,為啥讀出來的卻是0xCF呢?明擺著那兩個位沒寫進去。奇怪了!!!
于是我把//PCA_Init();初始化函數注釋掉.再來測試下,給PCA_PWM0寄存器賦值0xFF,讀出來是0xFF。可以寫進去了。
這就證明問題出在PCA_Init();初始化函數。回頭看看初始化函數.....................省略繁瑣的過程............................!
最后發現是CCAPM0寄存器的問題,這個寄存器我用到了,允許比較功能和使能PWM 輸出。
問題就出在使能PWM輸出這個位上。使能了PWM輸出,Pwm重裝值高2位就寫不進去,也就沒辦法調節占空比。
關于STC8G單片機的PCA_10PWM輸出注意事項 013446ghmz1f2b7sdb7lfa.png

這和資料上的最后一句話是不是沖突了。這算不算一個BUG呢。
在修改重裝值前,先禁止PWM 輸出,修改好后再打開。這能算無干擾嗎???

最后代碼修改如下:
  1. //10位PWMPCA初始化
  2. void PCA_Init()
  3. {
  4.         CCON=0x00;  //關閉PCA計數器,清除相關標志位
  5.         CMOD=PCA_SYSCLK2;  //PCA時鐘源為系統時鐘2分頻  33.1776/2/1024=0.0162MHZ ==>16.2KHZ
  6.         CL  =0x00;  //計數器清零
  7.         CH  =0x00;
  8. /*------------------------PWM0部分-----------------------------*/
  9.         CCAPM0 = 0x40;  //失能PCA模塊0_PWM輸出
  10.         CCAP0L=0X00;    //捕獲比較寄存器低8位,比較值
  11.         CCAP0H=0X00;    //捕獲比較寄存器高8位,重裝值
  12.         PCA_PWM0=0xC0;  //10位PWM輸出
  13.         CCAPM0=0x42; //使能PCA模塊0_PWM輸出
  14.         
  15. /*------------------------PWM1部分-----------------------------*/
  16.         CCAPM1 = 0x40;  //失能PCA模塊1_PWM輸出
  17.         CCAP1L=0X00;    //捕獲比較寄存器低8位,比較值
  18.         CCAP1H=0X00;    //捕獲比較寄存器高8位,重裝值
  19.         PCA_PWM1=0xC0; //10位PWM輸出
  20.         CCAPM1=0x42; //使能PCA模塊0_PWM輸出
  21.         
  22.         CCON|=  1<<6;   //啟動計數器
  23. }


  24. //設置脈沖寬度
  25. void PWM0_Set_Duty(u16 Duty)
  26. {
  27.         //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
  28.         
  29.         CCAPM0   = 0x40;           //失能PCA模塊0_PWM輸出
  30.         PCA_PWM0&= ~(3<<4);        //清零重裝值高2位
  31.         PCA_PWM0|= (Duty>>4)&0x30; //設置新的重裝值高2位
  32.         CCAP0H   = Duty;           //重裝值低8位
  33.         CCAPM0   = 0x42;           //使能PCA模塊0_PWM輸出
  34. }


  35. //設置脈沖寬度
  36. void PWM1_Set_Duty(u16 Duty)
  37. {
  38.         //注意:在更新 10 位 PWM 的重載值時,必須先寫高兩位 XCCAPnH[1:0],再寫低 8 位 CCAPnH[7:0]。
  39.         
  40.         CCAPM1   = 0x40;           //失能PCA模塊1_PWM輸出
  41.         PCA_PWM1&= ~(3<<4);        //清零重裝值高2位
  42.         PCA_PWM1|= (Duty>>4)&0x30; //設置新的重裝值高2位
  43.         CCAP1H   = Duty;           //重裝值低8位
  44.         CCAPM1   = 0x42;           //使能PCA模塊0_PWM輸出
  45. }
復制代碼

您需要登錄后才可以回帖 登錄 | 注冊

本版積分規則

手機版|小黑屋|ELEOK |網站地圖

GMT+8, 2026-5-26 04:09

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回復 返回頂部 返回列表