一、原理分析
PCF8591电压信号探测器:http://t.csdnimg.cn/R38tC
IIC原理:http://t.csdnimg.cn/v4dSv
IIC指令:http://t.csdnimg.cn/RY6yi
HC573/HC138:http://t.csdnimg.cn/W0a0U
独立键盘:http://t.csdnimg.cn/YPInc
二、思维导通
三、示例例程
1、题目要求:
在新建的工程中,采用I/O模式编写代码,针对CT107D单片机综合训练平台,实现以下功能:
- 移植IIC总线的底层驱动代码文件至工程中。
- 配置J5为BTN模式,将S4设置为独立按键,并选择DAC的输出模式。
- 数码管显示格式如下:最左侧3位显示当前的DAC输出模式,最右侧3位显示当前DAC的输出电压,电压单位为V,保留2位小数。
- DAC的输出模式包括三种:
- 模式1:显示"- -",DAC输出固定电压为2.00V。
- 模式2:显示"-2-",DAC输出固定电压为4.00V。
- 模式3:显示"-3-",右侧显示PCF8591芯片AIN3通道的实时输入电压,并将该电压作为DAC的输出参数,实现DAC输出电压与PCF8591芯片AIN3通道输入电压同步变化。通过调节Rb2可调电阻,可改变DAC的输出电压。
- 系统上电后,默认工作在模式1。在模式1中按下S4按键,切换至模式2;在模式2中按下S4按键,切换至模式3;在模式3中按下S4按键,重新回到模式1,如此循环。
- 使用万用表测量J3的19和20引脚,即DAC输出电压,确保万用表显示的数值与数码管右侧显示的电压基本一致。
2.示例代码
#include "stc15.h"
#include "iic.h"
#define TSMG 500
#define TKEY 200
sbit s4 = P3^3;
unsigned char stat = 1; //模式
unsigned int smg_v = 200; //数码管显示电压
unsigned int ain3 = 0; //通道3数值
void delay_smg(unsigned int t)
{
while(t--);
}
void delay_key(unsigned int t)
{
while(t--);
}
code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};
code unsigned char Seg_DotTable[] =
{
0x40, //0
0x79, //1
0x24, //2
0x30, //3
0x19, //4
0x12, //5
0x02, //6
0x78, //7
0x00, //8
0x10 //9
};
//控制所有数码管
void smg_all(unsigned dat)
{
hc573(6,0xff);
hc573(7,dat);
}
//单个数码管设置
void smg_bit(unsigned char channel, unsigned dat)
{
hc573(6,0x01 << channel);
hc573(7,dat);
delay_smg(TSMG);
hc573(6,0x01 << channel);
hc573(7,0xff);
}
//数码管显示函数
void smg_dispay()
{
smg_bit(0, 0xbf);
smg_bit(1, Seg_Table[stat]);
smg_bit(2, 0xbf);
smg_bit(5, Seg_DotTable[smg_v / 100]);
smg_bit(6, Seg_Table[(smg_v / 10) % 10]);
smg_bit(7, Seg_Table[smg_v % 10]);
}
//读取AIN3实时输入电压
void read_pcf8591_ain3()
{
unsigned int temp = 0;
float v = 0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43); //输出DAC,转换AIN3
I2CWaitAck();
I2CStop();
smg_dispay();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
v = temp * (5.0 / 255);
ain3 = v * 100;
}
//输出电压函数
void out_pcf8591(unsigned int dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43); //输出DAC,转换AIN3
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
//系统初始化函数
void init_sys()
{
hc573(5, 0x00); //关闭蜂鸣器继电器
hc573(4, 0xff); //熄灭LED
smg_all(0xff); //熄灭所有数码管
out_pcf8591(102); //输出2.00V
}
//键盘扫描函数
void scan_key()
{
if(s4 == 0)
{
delay_key(TKEY);
if(s4 == 0)
{
switch(stat)
{
case 1:
//当处于模式2时
stat++;
out_pcf8591(204); //输出4V电压
smg_v = 400;
break;
case 2:
stat++;
break;
case 3:
//当处于模式3时
stat = 1;
out_pcf8591(102); //输出2V电压
smg_v = 200;
break;
}
while(s4 == 0)
{
smg_dispay();
}
}
}
}
void main()
{
init_sys();
while(1)
{
if(stat == 3) //当处于模式3时
{
read_pcf8591_ain3();
smg_v = ain3;
out_pcf8591(ain3);
}
scan_key();
smg_dispay();
}
}