CT107D
竞赛板+
IAP15
转接板
资料中提供了相对完整的IIC的库函数,所以,可以不用深入的了解IIC总线的时钟顺序。而以下是选手必须要了解的。
器件地址: 地址的前4
位由器件的型号决定,后3
位由A0
A1
A2
三个引脚决定,在CT107D
中 FCP8591
的地址是0x90
,AT24C02
的地址是0xa0
。
**读/写标志位:**器件地址的后一位为读写标志位,1
为读操作,0
为写操作。
FCP8591
是一个用于数模相互转换的芯片。
位 | 说明 | |
---|---|---|
7 | 0 | 置零 |
6 | x | D/A 标志,1 打开,0 关闭 |
5 | x | 模拟信号的输入方式,与后一位一起使用,一般使用方式0 |
4 | x | |
3 | 0 | 置零 |
2 | x | 自动增量标志,一般情况下置零,如果置位,则在每次A/D 转换后,通道编号自动增加 |
1 | x | 设置通道编号,与后一位一起使用 |
0 | x | 通道0 为A/D 引脚,通道1 为光敏电阻,通道2 为仪表放大器,通道3 为电位器 |
#include
#include
#ifndef u8
#define u8 unsigned char
#endif
u8 code font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code y6=0xc0,y7=0xe0;
u8 dis[8];
unsigned int uval,lval;
void delay100us() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 39;
do
{
while (--j);
} while (--i);
}
//数码管显示
void display(){
u8 i;
dis[0]=0xff; //不显示
dis[1]=font[uval/100%10]&0x7f; //显示电位器的电压
dis[2]=font[uval/10%10];
dis[3]=font[uval%10];
dis[4]=0xff; //不显示
dis[5]=font[lval/100%10]&0x7f; //显示光敏电阻的电压
dis[6]=font[lval/10%10];
dis[7]=font[lval%10];
//数码管显示
for(i=0;i<8;i++){
P2&=0x1f;
P0=1<<i;
P2|=y6;
P2&=0x1f;
P0=dis[i];
P2|=y7;
delay100us();
P0=0xff;//消隐
}
P2&=0x1f;
}
void uread(){//读电位器,随机读操作,
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
uval=IIC_RecByte();
uval=uval*500.0/255;
IIC_Stop();
}
void lread(){//读光敏电阻,随机读操作,
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
lval=IIC_RecByte();
lval=lval*500.0/255;
IIC_Stop();
}
int main(){
while(1){
lread();
uread();
display();
}
}
#include
#include
#ifndef u8
#define u8 unsigned char
#endif
u8 code font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code y6=0xc0,y7=0xe0;
u8 dis[8];
unsigned int out_val=300;//输出电压为3.00伏
void delay100us() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 39;
do
{
while (--j);
} while (--i);
}
//数码管显示
void display(){
u8 i;
dis[0]=0xff; //不显示
dis[1]=0xff;
dis[2]=0xff;
dis[3]=0xff;
dis[4]=0xff;
dis[5]=font[out_val/100%10]&0x7f; //显示输出电压
dis[6]=font[out_val/10%10];
dis[7]=font[out_val%10];
//数码管显示
for(i=0;i<8;i++){
P2&=0x1f;
P0=1<<i;
P2|=y6;
P2&=0x1f;
P0=dis[i];
P2|=y7;
delay100us();
P0=0xff;//消隐
}
P2&=0x1f;
}
void output(){//输出电压,写操作
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(out_val*255.0/500);
IIC_WaitAck();
IIC_Stop();
}
int main(){
while(1){
output();
display();
}
}
如果手边没有电压表的话,可以用短接片把A/D
D/A
引脚连接起来,这样自己测自己。以下是这个方式的代码
#include
#include
#ifndef u8
#define u8 unsigned char
#endif
u8 code font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code y6=0xc0,y7=0xe0;
u8 dis[8];
unsigned int u_val,out_val=472;//输出电压为4.72伏
void delay100us() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 39;
do
{
while (--j);
} while (--i);
}
//数码管显示
void display(){
u8 i;
dis[0]=0xff; //不显示
dis[1]=font[u_val/100%10]&0x7f;
dis[2]=font[u_val/10%10];
dis[3]=font[u_val%10];
dis[4]=0xff;
dis[5]=font[out_val/100%10]&0x7f; //显示输出电压
dis[6]=font[out_val/10%10];
dis[7]=font[out_val%10];
//数码管显示
for(i=0;i<8;i++){
P2&=0x1f;
P0=1<<i;
P2|=y6;
P2&=0x1f;
P0=dis[i];
P2|=y7;
delay100us();
P0=0xff;//消隐
}
P2&=0x1f;
}
void FCP(){//我测我自己,随机读操作
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(out_val*255.0/500);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
u_val=IIC_RecByte();
u_val=u_val*500.0/255;
IIC_Stop();
}
int main(){
while(1){
FCP();
display();
}
}
AT24C02
是一个可擦写的ROM芯片,断电后数据不丢失,它提供了256B
的存储空间。其中,256B
被分为32
页,每页8
个字节。在进行写操作的时候,一次最多只能写一页。
其代码功能如下:
按键表
1 | 2 | 3 | 存储1 |
---|---|---|---|
4 | 5 | 6 | 读取1 |
7 | 8 | 9 | 存储2 |
0 | 撤销 | 清零 | 读取2 |
要求运用按键对数字进行操作,并在数码管上显示出来。能在EEPROM
中存储两个数,并能读取出来。
#include
#include
#ifndef u8
#define u8 unsigned char
#endif
u8 code font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code y6=0xc0,y7=0xe0;
u8 dis[8],num[8]={0,0,0,0,0,0,0,0};
void delay100us() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 39;
do
{
while (--j);
} while (--i);
}
void delay300ms() //@12.000MHz
{
unsigned char i, j, k;
i = 14;
j = 174;
k = 224;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void add_num(u8 val){//在末尾增加一位数
u8 i;
if(num[0]==0){
for(i=0;i<7;i++)
num[i]=num[i+1];
num[7]=val;
}
}
void dec_num(){//去掉末尾的一位数
u8 i;
for(i=7;i>0;i--)
num[i]=num[i-1];
num[0]=0;
}
//数码管显示
void display(){
u8 i;
for(i=0;i<8;i++)
dis[i]=font[num[i]];
for(i=0;dis[i]==font[0]&&i<7;i++)
dis[i]=0xff;
for(i=0;i<8;i++){
P2&=0x1f;
P0=1<<i;
P2|=y6;
P2&=0x1f;
P0=dis[i];
P2|=y7;
delay100us();
P0=0xff;//消隐
}
P2&=0x1f;
}
void rom_read(u8 addr){//读取数据,addr代表地址
u8 i;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
for(i=0;i<8;i++){
num[i]=IIC_RecByte();
IIC_SendAck(i==7);
}
IIC_Stop();
}
void rom_write(u8 addr){//存入数据,addr代表地址
u8 i;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
for(i=0;i<8;i++){
IIC_SendByte(num[i]);
IIC_WaitAck();
}
IIC_Stop();
}
void scankey(){//按键设置
u8 key,i;
P42=0;P44=0;P3=0x0f;
if(P3!=0x0f){
delay100us();
if(P3!=0x0f){
key=P3;
P3=0xf0;P42=1;P44=1;
key|=P3;
if(P42==0) key&=0xbf;
if(P44==0) key&=0x7f;
delay300ms();
switch(key){
//返回按键编号
case 0x77:add_num(0);break; //s4
case 0x7e:add_num(1);break; //s7
case 0xbe:add_num(2);break; //s11
case 0xde:add_num(3);break; //s15
case 0x7d:add_num(4);break; //s6
case 0xbd:add_num(5);break; //s10
case 0xdd:add_num(6);break; //s14
case 0x7b:add_num(7);break; //s5
case 0xbb:add_num(8);break; //s9
case 0xdb:add_num(9);break; //s13
case 0xb7:dec_num();break; //s8“撤销”
case 0xd7:for(i=0;i<8;i++)num[i]=0;break;//s12 “清零”
case 0xee:rom_write(0x00);break; //s19 “存储1”
case 0xed:rom_read(0x00);break; //s18 “读取1”
case 0xeb:rom_write(0x08);break; //s17 “存储2”
case 0xe7:rom_read(0x08);break; //s16 “读取2”
}
}
}
}
int main(){
while(1){
scankey();
display();
}
}