|
我在用cvavr编译器编写 m16与qt6024通信时使用m16的twi能成功,而使用系统自带的库函数不行,不知道是为什么?
使用qt6024实现3*4键盘
使用TWI功能程序如下,能成功返回值.
#define QT60240_IIC_ADDRESS 0xe //0x0e //0x22 //0xea
#define FAIL 1
#define SUCCESS 0
#include <mega16.h>
#ifndef __SLEEP_DEFINED__
#define __SLEEP_DEFINED__
.EQU __se_bit=0x40
.EQU __sm_mask=0xB0
.EQU __sm_powerdown=0x20
.EQU __sm_powersave=0x30
.EQU __sm_standby=0xA0
.EQU __sm_ext_standby=0xB0
.EQU __sm_adc_noise_red=0x10
.SET power_ctrl_reg=mcucr
#endif
#include <delay.h>
#define START 0x08
#define MT_SLA_ACK 0x18
#define REPEATED_START 0x10
#define MT_DATA_ACK 0x28
#include <stdio.h>
#define TWPS0 0
#define TWPS1 1
#define TWGCE 0
#define TWINT 7
#define TWEA 6
#define TWSTA 5
#define TWSTO 4
#define TWWC 3
#define TWEN 2
#define TWIE 0
unsigned char receive_data;
void IIC_Init(void)
{
TWSR=0;
TWBR=0X20;
TWAR=0;
TWCR=0X44;
PORTC.0=1;
DDRC=0xff;
PORTC.1=1;
}
unsigned char Writing_IIC_Data(unsigned char mem_addr,unsigned char idata)
{
//发出START 信号
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//等待TWINT 置位, TWINT 置位表示START 信号已发出
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是START 转出错处理
if ((TWSR & 0xF8) != START)
return FAIL;
//装入SLA_W 到TWDR 寄存器,TWINT 位清零,启动发送地址
TWDR = QT60240_IIC_ADDRESS;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待TWINT 置位, TWINT 置位表示总线命令SLA+W 已发出,及收到应答信号ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK 转出错处理
if ((TWSR & 0xF8) != MT_SLA_ACK)
return FAIL;
//装入数据到TWDR 寄存器,TWINT 清零,启动发送数据
TWDR = mem_addr;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待 TWINT 置位, TWINT 置位表示总线数据 DATA 已发送,及收到应答信号 ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频器,如果状态字不是MT_DATA_ACK 转出错处理
if ((TWSR & 0xF8) != MT_DATA_ACK)
return FAIL;
//装入数据到TWDR 寄存器,TWINT 清零,启动发送数据
TWDR = idata;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待 TWINT 置位, TWINT 置位表示总线数据 DATA 已发送,及收到应答信号 ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频器,如果状态字不是MT_DATA_ACK 转出错处理
if ((TWSR & 0xF8) != MT_DATA_ACK)
return FAIL;
//发送STOP 信号
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
return SUCCESS;
}
unsigned char Reading_IIC_Data(unsigned char mem_addr)
{
//发出START 信号
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//等待TWINT 置位, TWINT 置位表示START 信号已发出
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是START 转出错处理
if ((TWSR & 0xF8) != START)
return FAIL;
//装入SLA_W 到TWDR 寄存器,TWINT 位清零,启动发送地址
TWDR = QT60240_IIC_ADDRESS;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待TWINT 置位, TWINT 置位表示总线命令SLA+W 已发出,及收到应答信号ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK 转出错处理
if ((TWSR & 0xF8) != MT_SLA_ACK)
return FAIL;
//装入数据到TWDR 寄存器,TWINT 清零,启动发送数据
TWDR = mem_addr;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待 TWINT 置位, TWINT 置位表示总线数据 DATA 已发送,及收到应答信号 ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频器,如果状态字不是MT_DATA_ACK 转出错处理
if ((TWSR & 0xF8) != MT_DATA_ACK)
return FAIL;
//重复发出START 信号
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//等待TWINT 置位, TWINT 置位表示START 信号已发出
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是START 转出错处理
if ((TWSR & 0xF8) != REPEATED_START)
return FAIL;
//装入SLA_R 到TWDR 寄存器,TWINT 位清零,启动发送地址
TWDR = QT60240_IIC_ADDRESS+1;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待TWINT 置位, TWINT 置位表示总线命令SLA+R 已发出,及收到应答信号ACK/NACK
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK 转出错处理
if ((TWSR & 0xF8) != 0x40)
return FAIL;
TWCR = (1<<TWINT) | (1<<TWEN);
//等待TWINT 置位, TWINT 置位表示数据已接收
while (!(TWCR & (1<<TWINT)));
//检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK 转出错处理
if ((TWSR & 0xF8) != 0x58)
return FAIL;
//接收的数据
receive_data = TWDR;
//发送STOP 信号
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
return SUCCESS;
}
void clear_iic(void)
{
//发送STOP 信号
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
void main(void)
{
unsigned char i,key;
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x80;
DDRD=0x80;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x2F;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
putchar(0x11);
// I2C Bus initialization
IIC_Init();
while (1)
{
for(i=1;i<4;i++)
{
Reading_IIC_Data(i);
if(receive_data!=0)
{
switch (receive_data)
{
case 1:if(i==1) {key=3; break;}
if(i==2) {key=2;break;}
if(i==3) {key=1;break;}
case 2:if(i==1) {key=6; break;}
if(i==2) {key=5;break;}
if(i==3) {key=4;break;}
case 4:if(i==1) {key=9; break;}
if(i==2) {key=8;break;}
if(i==3) {key=7;break;}
case 8:if(i==1) {key='#'; break;}
if(i==2) {key=0;break;}
if(i==3) {key='*';break;}
}
putchar(key);
}
delay_ms(150);
}
};
}
使用自带的库函数程序如下,此时使用的是 PA口,只读地址1里面的数据
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.9 Professional
Automatic Program Generator
?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 2008/5/6
Author : SNOW
Company : SEELO
Comments:
Chip type : ATmega16L
Program type : Application
Clock frequency : 7.372800 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#ifndef __SLEEP_DEFINED__
#define __SLEEP_DEFINED__
.EQU __se_bit=0x40
.EQU __sm_mask=0xB0
.EQU __sm_powerdown=0x20
.EQU __sm_powersave=0x30
.EQU __sm_standby=0xA0
.EQU __sm_ext_standby=0xB0
.EQU __sm_adc_noise_red=0x10
.SET power_ctrl_reg=mcucr
#endif
// I2C Bus functions
#asm
.equ __i2c_port=0x1B ;PORTA
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include <i2c.h>
#include <delay.h>
#include <stdio.h>
#define add 0x0e
unsigned char rd_qt6024(unsigned char meu_add)
{
unsigned char data;
i2c_start();
i2c_write(add);
i2c_write(meu_add);
i2c_start();
i2c_write(add|1);
data=i2c_read(1);
i2c_stop();
return data;
}
void main(void)
{
unsigned char data;
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x2F;
i2c_init();
while (1)
{
data=rd_qt6024(1);
putchar(data);
delay_ms(1000);
};
}
不管有没有键触摸到,返回值为0Xff和oxDF交替出现.有时还可能是其它的值,都非正确值,不知是为什么。
附带传上qt6024的datasheet
请马老师和知道原因的朋友帮忙看看,不慎感谢。
点击此处下载 ourdev_268182.pdf(文件大小:344K) (原文件名:QT60240_X002.pdf) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|