使用PADAUK 应广PMS132单片机制作的简易电压表,测量范围在0-5V。使用ADC做外电压检测并且将ADC数值显示在8位数码管的高4位,在8位数码管的低4位显示电压值。下面是仿真器仿真和代码,详细请参考附件。
制作出来的实物图如下:
单片机源程序如下:
- #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;
- }
复制代码
代码下载:
PMS132电压表.rar
(18.42 KB, 下载次数: 104)
|