欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: STC12C2052AD單片機芯片中關于AD轉換的相關內容 [打印本頁]

作者: chinayanhui    時間: 2020-3-1 16:55
標題: STC12C2052AD單片機芯片中關于AD轉換的相關內容
使用芯片自帶的AD轉換器,按芯片說明書中提供的典型線路圖連接方案。發現使用查詢方式AD轉換沒有問題,獲取的輸出轉換電壓和實際輸入電壓,大約相差正負0.2V左右。但是使用中斷方式,僅在芯片上電觸發一次,然后就不動了。代碼也檢查了N多遍,真心看不出還有什么問題。請問各位大神遇到過這種問題嗎?該芯片測得的直流電壓會相差這么多嗎?誰用過這款芯片?

單片機代碼如下:
  1. #include <intrins.h>
  2. #include <STC12C2052AD.H>
  3. #include "UART.H"

  4. volatile uint8 COMMAND;

  5. #define ADC_POWER     0x80                // 1000 0000
  6. #define ADC_FLAG      0x10                // 0001        0000
  7. #define ADC_START     0x08                // 0000 1000

  8. #define ADC_SPEEDLL   0x00                // 0000 0000
  9. #define ADC_SPEEDL          0x20                // 0010 0000
  10. #define ADC_SPEEDH    0x40                // 0100 0000
  11. #define ADC_SPEEDHH   0x60                // 0110 0000

  12. // 延時函數
  13. void Delay(uint16 n)
  14. {
  15.         uint16 x;
  16.         while(n--)
  17.         {
  18.                 x = 5000;
  19.                 while(x--);
  20.         }
  21. }

  22. // AD中斷(這里出現問題,上電觸發一次,然后就不再觸發)
  23. void AdcISR() interrupt 5
  24. {
  25.         ADC_CONTR &= ~ADC_FLAG;
  26.         PutChar(ADC_DATA);
  27.         
  28.         // 開始下一次轉換
  29.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
  30.         Delay(10);
  31. }

  32. // 初始化AD
  33. void InitAdc()
  34. {
  35.         P1 = P1M0 = P1M1 = 0xFF;                                // 將所有P1口全部設置為開漏(Open Drain)
  36.         ADC_DATA = 0;
  37.         
  38.         // 清空DA轉換的結果
  39.         //ADC_CONTR = ADC_POWER | ADC_SPEEDHH;        
  40.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
  41.         Delay(10);
  42. }

  43. // 查詢方式獲取AD的值
  44. uint8 GetAdcResult()
  45. {
  46.         ADC_CONTR = ADC_POWER | ADC_SPEEDHH | 6 | ADC_START;
  47.         _nop_();
  48.         _nop_();
  49.         _nop_();
  50.         _nop_();
  51.         while(!(ADC_CONTR & ADC_FLAG));
  52.         
  53.         // 清空位
  54.         ADC_CONTR &= ~ADC_FLAG;
  55.         
  56.         // 返回轉換結果
  57.         return ADC_DATA;
  58. }

  59. // 軟件延時500ms
  60. void Delay500ms()                //@11.0592MHz
  61. {
  62.         unsigned char i, j, k;

  63.         i = 22;
  64.         j = 3;
  65.         k = 227;
  66.         do
  67.         {
  68.                 do
  69.                 {
  70.                         while (--k);
  71.                 } while (--j);
  72.         } while (--i);
  73. }


  74. void main()
  75. {
  76.         InitUART();                // 初始化串口
  77.         InitAdc();                // 初始化ADC
  78.         
  79.         
  80.         // 中斷方式使用AD,使用查詢方式時,注釋下面兩行
  81.         AUXR |= 0x10;
  82.         IE = 0xB0;                // 芯片說明書上給出的是0xA0,會將串口通訊的中斷屏蔽,這里我改為了0xB0
  83.         
  84.         while(1)
  85.         {
  86.                 ;
  87.                
  88.                 // 查詢方式使用AD,中斷方式注釋下面兩行
  89. //                Delay500ms();
  90. //                PutChar(GetAdcResult());
  91.         }
  92. }
復制代碼




作者: wulin    時間: 2020-3-1 17:56
沒有看到開總中斷和開ADC中斷
作者: chinayanhui    時間: 2020-3-1 18:03
剛剛發完帖后,又仔細的檢查了一下代碼。發現這個問題可能是中斷造成的。因為我在中斷響應程序中調用了將數據發送到串口的操作,這種操作會觸發串口發送數據完成的中斷。

我將中斷程序改為如下:

  1. void AdcISR() interrupt 5
  2. {
  3.         ADC_CONTR &= ~ADC_FLAG;
  4.        
  5.         PutChar(0xFF);
  6.         PutChar(0xFE);
  7.         PutChar(ADC_DATA);
  8.        
  9.         // 開始下一次轉換
  10.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
  11. }
復制代碼


在串口調試工具中發現接收窗僅打印了一個FF,然后就不動了。

查詢手冊發現,雖然沒有設置串口優先級寄存器的情況下,同級的串口中斷的優先級比AD優先執行,但是串口中斷并不會打斷AD中斷的執行。所以程序就停止在了putchar中,因為putchar會等待串口中斷執行完成將TI設置為0才往下執行。

所以,在主函數中將串口中斷的優先級提高一級就可以正常工作了。

  1. void main()
  2. {
  3.         // 中斷方式使用AD,使用查詢方式時,注釋下面兩行
  4.         PS = 1;
  5.         AUXR |= 0x10;
  6.         IE = 0xB0;                // 芯片說明書上給出的是0xA0,會將串口通訊的中斷屏蔽,這里我改為了0xB0
  7.         //PADC_SPI = 1;        // 高優先級
  8.        
  9.         InitUART();                // 初始化串口
  10.         InitAdc();                // 初始化ADC
  11.        
  12.         while(1)
  13.         {
  14.                 ;
  15.                
  16.                 // 查詢方式使用AD,中斷方式注釋下面兩行
  17. //                Delay500ms();
  18. //                PutChar(GetAdcResult());
  19.         }
  20. }
復制代碼

作者: chinayanhui    時間: 2020-3-1 18:06
wulin 發表于 2020-3-1 17:56
沒有看到開總中斷和開ADC中斷

謝謝您,我的問題已經解決了。開AD中斷是

AUXR |= 0x10;
IE = 0xB0;

開總中斷在是InitUART中做了。




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1