TLC2543 是一款 12 位精密模数转换器 (ADC)。
1~9、11、12——AIN0~AIN10为模拟输入端;
15——CS 为片选端;
17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式)
16——DOUT为A/D转换结果的三态串行输出端;(A/D转换结果的输出端。)
19——EOC为转换结束端;
18——CLK为I/O时钟;(控制输入输出的时钟,由外部输入。)
14——REF+为正基准电压端;
13——REF-为负基准电压端;
20——VCC为电源;
10——GND为地。
/***********************************************************************
* 说明:摇杆实验。摇动摇杆,查看显示屏上AD值变化。
**********************************************************************/
#include "STC89C5xRC.h" /* 此文件中定义了单片机的一些特殊功能寄存器 */
#include "OLED.h" /* OLED头文件 */
/* #include "Codedat.h" */
#define uint unsigned int /* 对数据类型进行声明定义 */
#define uchar unsigned char
sbit beep = P2 ^ 4; /* 定义蜂鸣器触发脚 */
/**************************************
* 2543控制引脚宏定义
*************************************/
sbit CLOCK = P3 ^ 5; /*2543时钟*/
sbit D_IN = P4 ^ 0; /*2543输入*/ /* 【注意:此处是口袋实验室连接引脚】 */
sbit D_OUT = P0 ^ 2; /*2543输出*/
sbit _CS = P3 ^ 4; /*2543片选*/
sbit DIG1 = P0 ^ 0; /* 数码管位选1 */
sbit DIG2 = P0 ^ 1; /* 数码管位选2 */
sbit key1 = P3 ^ 2; /* 摇杆A按键 */
sbit key2 = P3 ^ 3; /* 摇杆B按键 */
#define led P1 /* 将P1口定义为led 后面就可以使用led代替P0口 */
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,本延时函数延时较短,可以较快刷新屏幕
* 当然也可以使用OLED.h定义的delay_ms()函数
*******************************************************************************/
void delay( int ms )
{
int ii, jj;
if ( ms < 1 )
ms = 1;
for ( ii = 0; ii < ms; ii++ )
for ( jj = 0; jj < 500; jj++ )
;
}
/*******************************************************************************
* 函 数 名 : read2543
* 函数功能 : TLC2543驱动模块
* 输 入 : port 通道号
* 输 出 : ad 转换值
* 说 明 :请结合TLC2543芯片手册和下方注释理解
*******************************************************************************/
uint read2543( uchar port )
{
uint ad = 0, i;
CLOCK = 0;
_CS = 0;
port <<= 4; /*选通道。高四位代表AD通道,低四位自动补0 */
/*这里的for,其实就算_CS变低后,时钟IO_Clock和Data_Input使能,Data_Out脱离高阻状态。
* 12个时钟信号依次输入。随着时钟信号的输入,控制字从Data_Input一位一位地在时钟信号上升沿时
* 送入TLC2543(注意:高位先入),这里的控制字是通道选择(port),从A0-A10共11个通道,
* (分别对应0000至1010,高四位就是存放模拟通道输入选择的数据)
* 同时,上一周期转换的AD数据,即输出数据寄存器中的数据从Data_Out一位一位地移出(下降沿时)
* (第一次_CS=0时输出第一位,其他的跟着for内的下降沿输出)*/
for ( i = 0; i < 12; i++ ) /* 进行12次(12位)的数据推送 */
{
if ( D_OUT )
ad |= 0x01; /* 相当于每次检出输出1时。最低位就给1,否则给0 */
D_IN = (bit) (port & 0x80); /* 相当于只取最高位进行与运算 */
CLOCK = 1; /* 电平抬高 */
delay( 3 ); /* 延时 */
CLOCK = 0; /* 给低电平 */
delay( 3 ); /* 延时。这里是给一个完整周期的脉冲 */
port <<= 1;
ad <<= 1; /* 左移一位,为下一次for循环做准备 */
}
_CS = 1; /* 片选端置高,则IO_Clock和Data_Input禁止,Data_Out高阻,EOC置高 */
ad >>= 1; /*上面最后一次for循环多移了一次现在移回来 */
return(ad); /* 返回转换值 */
}
/*******************************************************************************
* 函 数 名 : ad_number
* 函数功能 : AD值数值拆分函数
* 输 入 : i 通道 y 显示行坐标
* 输 出 : 无
*******************************************************************************/
void ad_number( uchar i, uchar y )
{
uint ad;
ad = read2543( i ); /* 这里得到的是AD值(0~4095) */
OLED_ShowNum( 63, y, ad, 4, 16 );
}
/*******************************************************************************
* 函 数 名 : Int1Init()
* 函数功能 : 设置外部中断1 [P3.3]
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Int0Init()
{
/* 设置INT0 */
IT0 = 1; /* 跳变沿出发方式(下降沿) */
EX0 = 1; /* 打开INT0的中断允许。 */
EA = 1; /* 打开总中断 */
}
/*******************************************************************************
* 函 数 名 : Int1Init()
* 函数功能 : 设置外部中断1 [P3.3]
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Int1Init()
{
/* 设置INT1 */
IT1 = 1; /* 跳变沿出发方式(下降沿) */
EX1 = 1; /* 打开INT1的中断允许。 */
EA = 1; /* 打开总中断 */
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main( void )
{
Int0Init(); /* 外部中断0初始化 */
Int1Init(); /* 外部中断1初始化 */
beep = 0; /* 蜂鸣器不响 */
DIG1 = 0; /* 禁止数码管十位亮 */
DIG2 = 0; /* 禁止数码管个位亮 */
delay( 300 ); /*上电后等待系统稳定 */
OLED_Init(); /* OLED初始化 */
OLED_ShowString( 24, 0, "A-X:", 16 );
OLED_ShowString( 24, 2, "A-Y:", 16 );
OLED_ShowString( 24, 4, "B-X:", 16 );
OLED_ShowString( 24, 6, "B-Y:", 16 );
led = 0xff; /* LED全灭 */
while ( 1 )
{
ad_number( 7, 4 );
ad_number( 8, 2 );
ad_number( 9, 0 );
ad_number( 10, 6 );
}
}
/*******************************************************************************
* 函 数 名 : Int0() interrupt 0
* 函数功能 : 外部中断1的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Int0()
interrupt 0 /* 外部中断1的中断函数 */
{
delay( 40 ); /* 延时消抖 */
if ( key1 == 0 ) /* 如果按键按下 */
{
beep = ~beep; /* 蜂鸣器响/不响 */
}
}
/*******************************************************************************
* 函 数 名 : Int1() interrupt 2
* 函数功能 : 外部中断1的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Int1() interrupt 2 /* 外部中断1的中断函数 */
{
delay( 40 ); /* 延时消抖 */
if ( key2 == 0 ) /* 如果按键按下 */
{
led = ~led; /* LED全亮/灭 */
}
}