使用PADAUK 應廣PMS132單片機制作的簡易電壓表,測量范圍在0-5V。使用ADC做外電壓檢測并且將ADC數值顯示在8位數碼管的高4位,在8位數碼管的低4位顯示電壓值。下面是仿真器仿真和代碼,詳細請參考附件。
制作出來的實物圖如下:
51hei圖片20220218141805.jpg (1.19 MB, 下載次數: 72)
下載附件
2022-2-18 14:18 上傳
51hei圖片20220218141815.jpg (1.32 MB, 下載次數: 84)
下載附件
2022-2-18 14:18 上傳
51hei圖片20220218142107.png (126.82 KB, 下載次數: 63)
下載附件
2022-2-18 14:21 上傳
單片機源程序如下:
- #include "extern.h"
- #define data_1 pb
- #define duan_B pa.7
- #define wei_A pa.6
- byte wei,duan,b;
- word Reload_T16;
- word Voltage_data;
- word data;
- word time;
- word num;
- dword AD_Val_Sum;
- word AD_average_Val;
- void weiTable(void)
- {
- _Pcadd
- {
- ret 0xfe;//第一位 1111 1110
- ret 0xfd;//第二位 1111 1101
- ret 0xfb;//3 1111 1011
- ret 0xf7;//4 1111 0111
- ret 0xef;//5 1110 1111
- ret 0xdf;//6 1101 1111
- ret 0xbf;//7 1011 1111
- ret 0x7f;//8 0111 1111
- }
- }
- void duanTable(void)//8位共陰極數碼管 段碼
- { A+=1;
- _Pcadd
- {
-
- ret 0x3f;//0 //無小數點
- ret 0x06;//1
- ret 0x5b;//2
- ret 0x4f;//3
- ret 0x66;//4
- ret 0x6d;//5
- ret 0x7d;//6
- ret 0x07;//7
- ret 0x7f;//8
- ret 0x6f;//9
- ret 0xbf;//0 //帶小數點
- ret 0x86;//1
- ret 0xdb;//2
- ret 0xcf;//3
- ret 0xe6;//4
- ret 0xed;//5
- ret 0xfd;//6
- ret 0x87;//7
- ret 0xff;//8
- ret 0xef;//9
- ret 0x40;//-
- }
- }
- void LedDis(void)
- {
- data_1 = 0x00; //去重影
- duan_B = 1;
- duan_B = 0;
- A = wei; //取位碼
- weiTable();
- data_1 = A;
- wei_A = 1;
- wei_A = 0;
- A = duan; //取段碼
- duanTable();
- data_1 = A;
- duan_B = 1;
- duan_B = 0;
- }
- void T16init(void)
- {
- $ T16M IHRC,/16,bit15;
- reload_T16 = 32768 - 1000; //1ms
- stt16 Reload_T16;
- INTEN.T16 = 1;
- INTRQ.T16 = 0;
-
- }
- void TM2_PWM(void)
- {
- tm2ct = 0; //計數寄存器,通過每次進中斷修改該值來獲得精準的時間
- tm2b = 9; //上限寄存器,計數值超出上限寄存器的設定值時會產生中斷;
- $ TM2C SYSCLK,Disable,PWM; //時鐘源選擇,輸出腳選擇,模式選擇PWM模式;
- $ TM2S 8BIT,/4,/25;
- //計算公式為 1/{時鐘源*2/[2*(TM2B+1)*預分頻*分頻]}
- // = 1/(1M*2/(2*TM2B+1)*4*25) = 1/(1000000*2/(2*(49+1)*4*25)) = 0.005s
- INTEN.TM2 = 1;
- INTRQ.TM2 = 0;
- }
- void ADC_init(void)
- {
- //注:選擇的通道需設置為輸入,無上拉電阻,停用數字輸入使能;
- PAC.4 = 0;
- PAPH.4 = 0;
- PADIER = 0b1110_1001;
- $ ADCC Enable,PA4; //啟用ADC
- $ ADCM 12bit,/2;
- $ ADCRGC VDD; //選擇ADC輸入信號的參考電壓為VDD
- .delay 400;
- }
- void ADC_data(void)
- {
- //開始ADC轉換
- AD_START = 1; //開始ADC轉換
- while(!AD_DONE) //等待ADC轉換結果
- NULL;
- //當AD_DONE高電位時讀取ADC結果
- data$0 = ADCRL; //將ADC的值賦給data
- data$1 = ADCRH;
- data = data >> 4;
- }
- DWORD mul_t4;
- WORD mul_x2;
- WORD mul_y2;
- void Word_Mul_Word (void)
- { // mul_t4[D] = mul_x2[W] * mul_y2[W]
- mul_t4$3 = 0;
- mul_t4$2 = 0;
- BYTE cnt;
- cnt = 16;
- do
- {
- mul_x2 >>= 1;
- if (CF)
- {
- mul_t4 += (mul_y2 << 16);
- }
- mul_t4 >>>= 1;
- } while (--cnt);
- }
- DWORD div_src4;
- WORD div_val2, div_res2;
- void DWord_Div_Word (void)
- { // div_src4[D] / div_val2[W] = div_src4[D] * div_val2[W] + div_res2[W]
- BYTE div_cnt, div_tmp;
- div_cnt = 0;
- div_res2 = 0;
- do
- {
- div_src4 <<= 1;
- div_res2 <<<= 1;
- div_tmp <<<= 1;
- div_cnt++;
- A = (div_res2 - div_val2) >> 8;
- if (div_tmp.0 || ! CF)
- {
- div_res2$1 = A;
- div_res2$0 -= div_val2$0;
- div_src4.0 = 1;
- }
- } while (! div_cnt.5);
- }
- WORD div_src2;
- BYTE div_val, div_res;
- void Word_Div_Byte (void)
- { // div_src2[W] / div_val[B] = div_src2[W] * div_val[B] + div_res[B]
- BYTE div_cnt, div_tmp;
- div_cnt = 0;
- div_res = 0;
- do
- {
- div_src2 <<= 1;
- slc div_res;
- slc div_tmp;
- div_cnt++;
- A = div_res - div_val;
- if (div_tmp.0 || !CF)
- {
- div_res = A;
- div_src2.0 = 1;
- }
- } while (! div_cnt.4);
- }
- BYTE div_src3, div_val3, div_res3;
- void Byte_Div_Byte (void)
- { // div_src[B] / div_val[B] = div_src[B] * div_val[B] + div_res[B]
- BYTE div_cnt;
- div_cnt = 0;
- div_res3 = 0;
- A = -div_val3;
- div_src3 <<= 1;
- do
- {
- slc div_res3;
- div_cnt++;
- div_res3 += A;
- if (!CF) div_res3 -= A;
- div_src3 <<<= 1;
- } while (! div_cnt.3);
- }
- WORD div_src_adc1;
- WORD div_val_adc1, div_res_adc1;
- static void Word_adc1_Div_Word_adc1 (void)
- { // div_src2[W] / div_val2[W] = div_src2[W] * div_val2[W] + div_res2[W]
- BYTE div_cnt;
- div_cnt = 0;
- div_res_adc1 = 0;
- do
- {
- div_src_adc1 <<= 1;
- div_res_adc1 <<<= 1;
- div_cnt++;
- A = (div_res_adc1 - div_val_adc1) >> 8;
- if (! CF)
- {
- div_res_adc1$1 = A;
- div_res_adc1$0 -= div_val_adc1$0;
- div_src_adc1.0 = 1;
- }
- } while (! div_cnt.4);
- }
- WORD div_src_adc2;
- WORD div_val_adc2, div_res_adc2;
- static void Word_adc2_Div_Word_adc2 (void)
- { // div_src2[W] / div_val2[W] = div_src2[W] * div_val2[W] + div_res2[W]
- BYTE div_cnt;
- div_cnt = 0;
- div_res_adc2 = 0;
- do
- {
- div_src_adc2 <<= 1;
- div_res_adc2 <<<= 1;
- div_cnt++;
- A = (div_res_adc2 - div_val_adc2) >> 8;
- if (! CF)
- {
- div_res_adc2$1 = A;
- div_res_adc2$0 -= div_val_adc2$0;
- div_src_adc2.0 = 1;
- }
- } while (! div_cnt.4);
- }
- BYTE div_src_adc3, div_val_adc3, div_res_adc3;
- void Byte_adc3_Div_Byte_adc3 (void)
- { // div_src[B] / div_val[B] = div_src[B] * div_val[B] + div_res[B]
- BYTE div_cnt;
- div_cnt = 0;
- div_res_adc3 = 0;
- A = -div_val_adc3;
- div_src_adc3 <<= 1;
- do
- {
- slc div_res_adc3;
- div_cnt++;
- div_res_adc3 += A;
- if (!CF) div_res_adc3 -= A;
- div_src_adc3 <<<= 1;
- } while (! div_cnt.3);
- }
- void data_sum(void)
- {
- num = 128;
- AD_Val_Sum = 0;
- while(num--)
- {
- // Get_AD_Val();
- AD_Val_Sum += data;
- .delay 1000; //1ms
- }
- AD_average_Val = AD_Val_Sum>>7; //除以128
-
- }
- void ADC_calcu(void)//數據計算
- {
- mul_x2 = AD_average_Val;
- mul_y2 = 500;//參考電壓的100倍
- Word_Mul_Word();
- div_src4 = mul_t4;
- div_val2 = 0xFFF;//分辨率12為0xFFF
- DWord_Div_Word();
- Voltage_data = div_src4;//測得的電壓是實際電壓100倍
- nop;
- }
- void FPPA0 (void)
- {
- .ADJUST_IC SYSCLK=IHRC/16, IHRC=16MHz, VDD=5V;
- ADC_init();
- T16init();
- TM2_PWM();
- pa=0b1110_1001;
- pac=0b1110_1001;
- pb=0xff;
- pbc=0xff;
- ENGINT;
- b=0;
- time=0;
- div_res3=0;
- div_src3=0;
- div_src2=0;
- div_res_adc3=0;
- div_src_adc3=0;
- div_src_adc2=0;
- div_src_adc1=0;
- AD_average_Val=0;
- data=0;
- duan=0;
- wei=0;
- while (1)
- {
- data_sum();
- ADC_calcu();
- }
- }
- void Interrupt (void)
- {
- pushaf;
- if (Intrq.T16)
- {
- stt16 Reload_T16;
- b++;
- if(b>8)
- {b=0;}
- LedDis();
- //逐位掃描顯示
- switch(b)
- {
- case 0:
- duan=div_res3; //電壓小數第二位
- wei=8;
- break;
- case 1:
- duan=div_src3; //電壓小數第一位
- wei=7;
- break;
- case 2:
- duan=div_src2+10; //電壓個數位
- wei=6;
- break;
- case 3:
- duan=20; //-
- wei=5;
- break;
- case 4:
- duan=div_res_adc3; //adc個位
- wei=4;
- break;
- case 5:
- duan=div_src_adc3; //adc十位
- wei=3;
- break;
- case 6:
- duan=div_src_adc2; //adc百位
- wei=2;
- break;
- case 7:
- duan=div_src_adc1; //adc千位
- wei=1;
- break;
- default:break;
- }
-
- Intrq.T16 = 0;
- //...
- }
- if(Intrq.TM2)
- {
- tm2ct = 0; //定周期模式,可以省略
- ADC_data();
-
- time++;
- if(time>300)
- {
- time=0;
-
- //取ADC值
- div_src_adc1=AD_average_Val;
- div_val_adc1=1000;
- Word_adc1_Div_Word_adc1 ();
- div_src_adc2=div_res_adc1;
- div_val_adc2=100;
- Word_adc2_Div_Word_adc2 ();
- div_src_adc3=div_res_adc2;
- div_val_adc3=10;
- Byte_adc3_Div_Byte_adc3 ();
- //取電壓值
- div_src2=Voltage_data; //取百位
- div_val=100;
- Word_Div_Byte ();
- div_src3=div_res; //用取百位后的余數取個位,十位
- div_val3=10;
- Byte_Div_Byte ();
- }
-
-
- Intrq.TM2 = 0;
- }
- popaf;
- }
復制代碼
51hei.png (4.83 KB, 下載次數: 64)
下載附件
2022-2-18 15:56 上傳
代碼下載:
PMS132電壓表.rar
(18.42 KB, 下載次數: 104)
2022-2-18 14:13 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|