可以將光照值和溫度值顯示在數碼管上(AD轉換)
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- sfr P0M1 = 0x93;
- sfr P0M0 = 0x94;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr CLK_DIV = 0x97;
- //sfr AUXR = 0x8E;
- sfr ADC_CONTR = 0xBC; //ADC控制寄存器
- sfr ADC_RES = 0xBD; //ADC高8位結果
- sfr ADC_LOW2 = 0xBE; //ADC低2位結果
- sfr P1ASF = 0x9D; //P1口模擬功能控制寄存器
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540個時鐘
- #define ADC_SPEEDL 0x20 //360個時鐘
- #define ADC_SPEEDH 0x40 //180個時鐘
- #define ADC_SPEEDHH 0x60 //90個時鐘
- sbit LED_SEL = P2^3;
- sbit BEEP = P3^4;
- unsigned char code LedChar[] = { //數碼管顯示字符轉換表 0-F
- 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
- 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
- };
- unsigned char LedBuff[9] = { //數碼管顯示緩沖區 + 獨立LED緩沖區
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- int code TempData[]={
- 239,197,175,160,150,142,135,129,124,120,116,113,109,107,104,101, //溫度值對應表
- 99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76,
- 75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62,
- 61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52,
- 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44,
- 43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37,
- 36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31,
- 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,
- 24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19,
- 19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14,
- 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7,
- 7, 7, 6, 6,5, 5, 54,4, 3, 3,3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1,
- -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9,
- -10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17,
- -18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
- 30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361
- };
- unsigned char ch = 3; //ADC通道號
- int temp = 0;
- unsigned int light = 0;
- unsigned char T0RH = 0; //T0重載值的高字節
- unsigned char T0RL = 0; //T0重載值的低字節
- bit beep_flag = 0; //蜂鳴器運行控制位
- void InitADC();
- void Delay2ms();
- void ConfigTimer0(unsigned int ms);
- void main()
- {
- P0M0 = 0xFF;
- P0M1 = 0x00;
- P2M0 = 0x08;
- P2M1 = 0x00;
-
- LED_SEL = 0;
-
- InitADC(); //初始化ADC
- IE = 0xA0; //使能ADC中斷
- //開始AD轉換
- ConfigTimer0(1); //配置T0定時1ms
-
- while(1)
- {
- if (temp < 0)
- {
- LedBuff[0] = 0x40;
- LedBuff[1] = LedChar[-temp/10%10];
- LedBuff[2] = LedChar[-temp%10];
- }
- else
- {
- LedBuff[0] = LedChar[temp/100%10];
- LedBuff[1] = LedChar[temp/10%10];
- LedBuff[2] = LedChar[temp%10];
- }
-
- LedBuff[5] = LedChar[light/100%10];
- LedBuff[6] = LedChar[light/10%10];
- LedBuff[7] = LedChar[light%10];
-
- if (temp >= 28)
- {
- beep_flag = 1;
- LedBuff[8] = 0xFF;
- }
- else
- {
- LedBuff[8] = 0x01;
- }
- }
- }
- /* ADC中斷服務程序 */
- void adc_isr() interrupt 5 using 1
- {
- static unsigned int cnt = 0; //記錄ADC中斷次數
- static unsigned long temp_sum = 0; //溫度AD值累加和
- static unsigned long light_sum = 0; //光照AD值累加和
-
- cnt++; //中斷次數+1
- ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標志
-
- if (ch == 3)
- {
- temp_sum += (ADC_RES*256+ADC_LOW2)/4;
- }
- if (ch == 4)
- {
- light_sum += ADC_RES*256+ADC_LOW2;
- }
-
- if (cnt > 2000)
- {
- cnt = 0;
-
- temp = TempData[(temp_sum+1000/2)/1000-1];
- light = (light_sum+1000/2)/1000;
- temp_sum = 0;
- light_sum = 0;
- }
-
- ADC_RES = 0;
- ADC_LOW2 = 0; //清除結果寄存器
-
- if (++ch == 5) ch=3; //切換到下一個通道
- ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
- CLK_DIV = 0x20;
- }
- /* 初始化ADC */
- void InitADC()
- {
- P1ASF = 0xFF; //設置P1口為AD口
- ADC_RES = 0;
- ADC_LOW2 = 0; //清除結果寄存器
- ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
- CLK_DIV = 0x20; //ADC_RES[1:0]存放高2位ADC結果,ADC_RESL[7:0]存放低8位ADC結果
- Delay2ms(); //ADC上電并延時
- }
- void Delay2ms() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 22;
- j = 128;
- do
- {
- while (--j);
- } while (--i);
- }
- /* 配置并啟動T0,ms為T0定時時間 */
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp; //臨時變量
-
- tmp = 11059200 / 12; //定時器計數頻率
- tmp = (tmp * ms) / 1000; //計算所需的計數值
- tmp = 65536 - tmp; //計算定時器重載值
- tmp = tmp + 13; //補償中斷響應延時造成的誤差
- T0RH = (unsigned char)(tmp>>8); //定時器重載值拆分為高低字節
- T0RL = (unsigned char)tmp;
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x01; //配置T0為模式1
- TH0 = T0RH; //加載T0重載值
- TL0 = T0RL;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- }
- /* LED動態掃描函數,需在定時中斷中調用 */
- void LedScan()
- {
- static unsigned char i = 0; //動態掃描索引
-
- P0 = 0x00; //關閉所有段選位,顯示消隱
- P2 = (P2 & 0xF0) | i; //位選索引值賦值到P2口低3位
- P0 = LedBuff[i]; //緩沖區中索引位置的數據送到P0口
- if (i < sizeof(LedBuff)-1) //索引遞增循環,遍歷整個緩沖區
- i++;
- else
- i = 0;
- }
- /* T0中斷服務函數,完成數碼管掃描 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned int cnt = 0;
- TH0 = T0RH; //重新加載重載值
- TL0 = T0RL;
- LedScan(); //LED掃描顯示
-
- if (beep_flag)
- {
- BEEP = ~BEEP; //反轉蜂鳴器控制電平
- cnt++;
- if (cnt > 5000) { //中斷5000次后,即定時5ms
- cnt = 0;
- beep_flag = 0;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
lesson5.zip
(39.54 KB, 下載次數: 11)
2018-11-16 21:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|