📄 4通道adc_t0定时中断4位数码管扫描显示.c
字号:
// 多通道ADC_定时中断4位数码管扫描显示.c T0 定时中断; P1口段笔画, 0=亮; P2口低4位作位选, 0=选中
#include <STC12C5410AD.H> // 单片机内部专用寄存器定义
// 假定4个通道 P1.0 ~ P1.3
unsigned int adc[4]={0,0,0,0}; // 保存4个通道10位AD转换结果
unsigned char adc_p=0; // 当前ADC采样通道号 0..3
unsigned char shrow_p=0; // 当前4位LED显示第几通道(0..3)的ADC结果
sbit K1= P3^0; // 键K1输入引脚定义
bit K1_b; // 前次键K1输入状态
/* T0_int 定时 时间常数 5ms=5000=1388H->EC78H f=12MH */
/* 5ms=4608=1200H->EE00H f=11.0592MH */
#define time_5ms_H 0xEE /* t=5ms for T0_INT_timer */
#define time_5ms_L 0x00
code unsigned char seg_tab[16]={ /* 显示段笔划 hgfedcba; 0=亮 */
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, /* 0,1,2,3,4,5,6,7,8,9 */
0x88,0x83,0xC6,0xA1,0x86,0x8E}; // A b C d E F
unsigned char led_buff[4]; /* 存放4位数码管的段笔画 */
unsigned char led_p=0; /* 待显示的位 */
void delay(unsigned int i) { for(;i!=0;i--); }
// 将一整形量的值以4位10进制数显示的段笔划送显示缓冲区
void led_fill_d(unsigned int n)
{ led_buff[3]=seg_tab[(unsigned char)(n%10)]; // 个位
n=n/10;
led_buff[2]=seg_tab[(unsigned char)(n%10)]; // 十位
n=n/10;
led_buff[1]=seg_tab[(unsigned char)(n%10)]; // 百位
n=n/10;
led_buff[0]=seg_tab[(unsigned char)(n%10)]; // 千位
}
//显示一位。b=0,1,2,3 第几位显示指定
void shrow_1LED(unsigned char b)
{ P2 = P2 | 0x0F; // P2 口 LED 全灭. 0=亮
P1 = led_buff[b]; // 送段信号
P2 = P2 & (~(0x01<<b)); // 位选中, 该位亮
}
main()
{
TMOD= 0x11; /* 0001$0001 T1 & T0 are 16bit timers */
TH0 = time_5ms_H; /* T0 timer 5ms */
TL0 = time_5ms_L;
/* TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 */
TCON= 0x10; /* 0 0 0 1 0 0 0 0 */
/* start T0 xint1 xint0 */
IE= 0x82; /* 1000 0010, EA=ET0=1, */
P1M0 |= 0x0F; // P1.0 ~ P1.3设为高阻输入. 用于AD输入
ADC_CONTR= 0x80; // A/D 转换控制寄存器 ADC_POWER SPEED1_SPEED0 ADC_FLAG ADC_START CHS2_CHS1_CHS0
// 启动ADC转换, adc_p 通道
ADC_CONTR= 0x80 + adc_p; // *ADC_POWER SPEED1_SPEED0 ADC_FLAG *ADC_START CHS2_CHS1_CHS0
while (1) // 死循环
{
delay(10000); // 软延时
led_fill_d(adc[shrow_p]); // 数 填入显示缓冲区
P2 = P2 | 0xF0; // P2 口 高4位的4个 LED 全灭. 0=亮
P2 = P2 & (~(0x01<<(shrow_p+4))); // 该位亮. 指示当前显示的ADC值属于那个通道
}
}
//==========================================
/*===================================*/
/* T0 中断服务程序[5MS定时中断一次] */
/*===================================*/
void T0_ISR() interrupt 1 /* T0 Interrupt 1 */
{
unsigned int t;
TL0= time_5ms_L; // 重置5MS时间常数
TH0= time_5ms_H;
// 1. 扫描输出一位LED
shrow_1LED(led_p); // 第led_p位亮
led_p=(led_p+1)%4; // 指向下一位, 为下一次中断显示用
// 2. 读ADC转换结果
// while ((ADC_CONTR & 0x10)==0); // 等待ADC转换结束
t = ADC_DATA; // ADC 高8位
t = (t<<2) + (ADC_LOW2 &0x3); // 10位ADC结果
adc[adc_p]=t; // 保存ADC结果
adc_p=(adc_p+1)%4; // 指向下一通道
// 2.1 启动下一次ADC转换, adc_p 通道
ADC_CONTR= 0x80 + adc_p; // *ADC_POWER SPEED1_SPEED0 ADC_FLAG *ADC_START CHS2_CHS1_CHS0
// 3. 按键识别,防抖动处理
if (led_p==0) K1_b=K1; // 采样按键K1
else if (led_p==3) // 采样按键K1后,过了20MS
{
if ((K1==0) && (K1_b==1)) shrow_p=(shrow_p+1)%4; // 按键新按下, 切换显示通道
K1_b=K1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -