新手入门
- 积分
- 10
- 金钱
- 10
- 注册时间
- 2016-5-7
- 在线时间
- 2 小时
|
发表于 2016-5-7 11:06:18
|
显示全部楼层
本帖最后由 wangrlo 于 2016-5-7 14:33 编辑
初始化时SDA是低电平应答信号,但为什么初始化后INT是低电平?多谢。附件是工程,下面是其中的FT6236.c:
//#include "delay.h"
#include "FT6236.h"
//#include "vmlog.h"
#include <string.h>
#include "vmtype.h"
#include "vmsystem.h"
#include "vmcmd.h"
#include "vmlog.h"
#include "vmboard.h"
#include "vmdcl.h"
#include "vmdcl_eint.h"
#include "vmdcl_gpio.h"
#include "stdio.h"
//VM_DCL_HANDLE gpio_handle; // device handle
VM_DCL_HANDLE lcd_reset_handle;
VM_DCL_HANDLE lcd_cs_handle;
VM_DCL_HANDLE lcd_dc_handle;
VM_DCL_HANDLE lcd_wr_handle;
VM_DCL_HANDLE lcd_sda_handle;
static VM_DCL_HANDLE g_eint_handle = VM_DCL_HANDLE_INVALID;
VMCHAR g_buff[256];
#define RST_L vm_dcl_control(lcd_reset_handle, VM_DCL_GPIO_COMMAND_WRITE_LOW, NULL)
#define RST_H vm_dcl_control(lcd_reset_handle, VM_DCL_GPIO_COMMAND_WRITE_HIGH, NULL)
#define DC_Low vm_dcl_control(lcd_dc_handle, VM_DCL_GPIO_COMMAND_WRITE_LOW, NULL)
#define DC_High vm_dcl_control(lcd_dc_handle, VM_DCL_GPIO_COMMAND_WRITE_HIGH, NULL)
#define SCLK_Low vm_dcl_control(lcd_wr_handle, VM_DCL_GPIO_COMMAND_WRITE_LOW, NULL)
#define SCLK_High vm_dcl_control(lcd_wr_handle, VM_DCL_GPIO_COMMAND_WRITE_HIGH, NULL)
#define SDIN_Low vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_WRITE_LOW, NULL)
#define SDIN_High vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_WRITE_HIGH, NULL)
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Delay Time
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void delay_us(VMUINT32 millisecs){
VMUINT32 timeStop;
VMUINT32 timeStart;
VMUINT32 Freq = 0;
volatile VMUINT32 i;
///millisecs = millisecs*1000;
timeStart = vm_time_ust_get_count();
sprintf(g_buff,"delay_us = %d", timeStart);log_info(10, g_buff);
while( Freq < millisecs)
{
//for(i=0;i<5000;i++){}
timeStop = vm_time_ust_get_count();
Freq = timeStop - timeStart + 1;
}
}
void Delay(unsigned char n)
{
unsigned char i,j,k;
for(k=0;k<n;k++)
{
for(i=0;i<131;i++)
{
for(j=0;j<15;j++)
{
delay_us(203);
}
}
}
}
vm_dcl_gpio_control_level_status_t FT6236_SDA_Read(){
vm_dcl_gpio_control_level_status_t gpio_input_data; // parameter for VM_DCL_GPIO_COMMAND_READ.
vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_READ, (void *)&gpio_input_data); // We call vm_dcl_control to read gpio55.
return gpio_input_data;
}
vm_dcl_gpio_control_level_status_t FT6236_INT_Read(){
vm_dcl_gpio_control_level_status_t gpio_input_data; // parameter for VM_DCL_GPIO_COMMAND_READ.
vm_dcl_control(g_eint_handle, VM_DCL_GPIO_COMMAND_READ, (void *)&gpio_input_data); // We call vm_dcl_control to read gpio55.
return gpio_input_data;
}
/****************************************************
* 函数名称 :
* 功 能 :单片机发送起始信号
* 入口参数 :无
* 返回参数 :无
* 注意事项 :
*****************************************************/
void FT6236_Start(void)
{
SDA_OUT(); //sda线输出
delay_us(3);
SDIN_High;
SCLK_High; //SCL最小高电平脉宽:0.6us
delay_us(4); //起始信号的最小建立时间:0.6us
SDIN_Low; //SCL高电平期间,SDA的一个下降沿表示起始信号
delay_us(4); //起始信号的最小保持时间:0.6us
SCLK_Low; //箝住总线,为发送器件地址做准备;
delay_us(2); //SCL最小低电平脉宽:1.2us,由RET实现
}
/****************************************************
* 函数名称 :
* 功 能 :单片机发送停止信号
* 入口参数 :无
* 返回参数 :无
* 注意事项 :
*****************************************************/
void FT6236_Stop(void)
{
SDA_OUT(); //sda线输出
delay_us(3);
SCLK_High; //SCL最小高电平脉宽:0.6us
delay_us(4); //停止信号的最小建立时间:0.6us
SDIN_Low;
delay_us(4);
SDIN_High; //SCL高电平期间,SDA的一个上升沿表示停止信号
delay_us(2);
}
/****************************************************
* 函数名称 :
* 功 能 :单片机发送应答信号
* 入口参数 :无
* 返回参数 :无
* 注意事项 :单片机读1B数据后发送一个应答信号
*****************************************************/
void FT6236_McuACK(void)
{
SCLK_Low;
SDA_OUT(); //sda线输出
delay_us(3);
SDIN_Low;
delay_us(2);
SCLK_High; //SCL最小高电平脉宽:0.6us
delay_us(2);
SCLK_Low; //SCL最小低电平脉宽:1.2us
}
/****************************************************
* 函数名称 :
* 功 能 :单片机发送非应答信号
* 入口参数 :无
* 返回参数 :无
* 注意事项 :单片机读数据停止前发送一个非应答信号
*****************************************************/
void FT6236_McuNACK(void)
{
SCLK_Low;
SDA_OUT(); //sda线输出
delay_us(3);
SDIN_High;
delay_us(2);
SCLK_High; //SCL最小高电平脉宽:0.6us
delay_us(2);
SCLK_Low; //SCL最小低电平脉宽:1.2us
}
/****************************************************
* 函数名称 :
* 功 能 :单片机检查FT6236送来的应答信号
* 入口参数 :无
* 返回参数 :1,接收应答失败
0,接收应答成功
* 注意事项 :单片机写1个地址/数据后检查
全局变量RevAckF:收到FT6236应答信号的标志位,为0表示收到
*****************************************************/
u8 FT6236_CheckAck(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
SDIN_High;
SCLK_High; //使SDA上数据有效;SCL最小高电平脉宽:0.6us
delay_us(3);
while(FT6236_SDA_Read().level_status)
{
ucErrTime++;
if(ucErrTime>250) //无应答
{
FT6236_Stop();
return 1;
}
delay_us(2);
}
SCLK_Low;
return 0;
}
/****************************************************
* 函数名称 :
* 功 能 :单片机向IIC总线发送1B的地址/数据
* 入口参数 :待发送的1B地址/数据
* 返回参数 :无
* 注意事项 :不是一个完整的数据发送过程;送数的顺序是从高到低
*****************************************************/
void FT6236_WrOneByte(u8 dat)
{
u8 i;
SDA_OUT(); //sda线输出
SCLK_Low; //拉低时钟开始数据传输
delay_us(3);
for(i = 8; i > 0; i--) //8位1B地址/数据的长度
{
if(dat & 0x80)
SDIN_High; //发送"1"
else
SDIN_Low; //发送"0"
delay_us(2);
SCLK_High; //使SDA上的数据有效
delay_us(2); //SCL最小高电平脉宽:0.6us
SCLK_Low; //SCL最小低电平脉宽:1.2us
delay_us(2);
dat <<= 1; //发送数据左移1位,为下位发送准备
}
}
/****************************************************
* 函数名称 :
* 功 能 :单片机从IIC总线接收1B的数据
* 入口参数 :无
* 返回参数 :收到的1B数据
* 注意事项 :不是一个完整的数据接收过程;从高到低的顺序接收数据
*****************************************************/
u8 FT6236_RdOneByte(void)
{
u8 i,dat = 0; //接收数据位数和内容暂存单元
SDA_IN(); //SDA设置为输入
delay_us(2);
//SDIN_High; //使能上拉,准备读取数据
vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_ENABLE_PULL, NULL);
vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_SET_PULL_HIGH, NULL);
delay_us(2);
for(i = 8;i > 0;i--)
{
SCLK_Low;
delay_us(2);
SCLK_High;
dat <<= 1;
if(FT6236_SDA_Read().level_status)
dat++;
delay_us(2); //SCL最小低电平脉宽:1.2us
}
SDIN_High;
return(dat); //返回1B的数据
}
//向FT6236写入一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:写数据长度
//返回值:0,成功;1,失败.
u8 FT6236_WR_Reg(u16 reg,u8 *buf,u8 len)
{
u8 i;
u8 ret=0;
FT6236_Start();
FT6236_WrOneByte(FT_CMD_WR); //发送写命令
//FT6236_CheckAck();
ret=FT6236_CheckAck();
sprintf(g_buff,"FT_CMD_WR = %d", ret);log_info(3, g_buff);
FT6236_WrOneByte(reg&0XFF); //发送低8位地址
FT6236_CheckAck();
for(i=0;i<len;i++)
{
FT6236_WrOneByte(buf); //发数据
ret=FT6236_CheckAck();
if(ret)break;
}
FT6236_Stop(); //产生一个停止条件
sprintf(g_buff,"buf = %d", ret);log_info(11, g_buff);
return ret;
}
//从FT6236读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度
void FT6236_RD_Reg(u16 reg,u8 *buf,u8 len)
{
u8 i;
FT6236_Start();
FT6236_WrOneByte(FT_CMD_WR); //发送写命令
FT6236_CheckAck();
FT6236_WrOneByte(reg&0XFF); //发送低8位地址
FT6236_CheckAck();
FT6236_Start();
FT6236_WrOneByte(FT_CMD_RD); //发送读命令
FT6236_CheckAck();
for(i=0;i<len;i++)
{
*buf++ = FT6236_RdOneByte(); //读入1B数据到接收数据缓冲区中
FT6236_McuACK(); //发送应答位
}
FT6236_McuNACK(); //n个字节读完,发送非应答位
FT6236_Stop(); //产生一个停止条件
}
/*
**函数名:FT6236_Init
**传入参数:无
**返回值:无
**功能:初始化FT6236引脚
*/
void FT6236_Init(void)
{
sprintf(g_buff,"FT6236_Init = %d", 5);log_info(3, g_buff);
lcd_reset_handle = vm_dcl_open(VM_DCL_GPIO, 33); // First, we call vm_dcl_open to get a handle. 55 means gpio55
//lcd_dc_handle = vm_dcl_open(VM_DCL_GPIO, 47); // First, we call vm_dcl_open to get a handle. 55 means gpio55
lcd_wr_handle = vm_dcl_open(VM_DCL_GPIO, 35); // First, we call vm_dcl_open to get a handle. 55 means gpio55
lcd_sda_handle = vm_dcl_open(VM_DCL_GPIO, 36); // First, we call vm_dcl_open to get a handle. 55 means gpio55
vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_ENABLE_PULL, NULL);
vm_dcl_control(lcd_wr_handle, VM_DCL_GPIO_COMMAND_ENABLE_PULL, NULL);
vm_dcl_control(lcd_sda_handle, VM_DCL_GPIO_COMMAND_SET_PULL_HIGH, NULL);
vm_dcl_control(lcd_wr_handle, VM_DCL_GPIO_COMMAND_SET_PULL_HIGH, NULL);
/* Sets the pin direction to OUTPUT */
vm_dcl_control(lcd_reset_handle, VM_DCL_GPIO_COMMAND_SET_DIRECTION_OUT, NULL);
/* Sets the pin direction to OUTPUT */
vm_dcl_control(lcd_wr_handle, VM_DCL_GPIO_COMMAND_SET_DIRECTION_OUT, NULL);
SDA_OUT();
u8 temp;
SDIN_High;
SCLK_High;
RST_H;
RST_L;
delay_ms(50);
RST_H;
delay_ms(100);
SDIN_High;
SCLK_High;
delay_ms(10);
temp=0;
FT6236_WR_Reg(FT_DEVIDE_MODE,&temp,1); //进入正常操作模式
temp=22; //触摸有效值,22,越小越灵敏
FT6236_WR_Reg(FT_ID_G_THGROUP,&temp,1); //设置触摸有效值
temp=12; //激活周期,不能小于12,最大14
FT6236_WR_Reg(FT_ID_G_PERIODACTIVE,&temp,1);
sprintf(g_buff,"INT = %d", FT6236_INT_Read().level_status);log_info(10, g_buff);
/******************************************************/
}
const u16 FT6236_TPX_TBL[5]=
{
FT_TP1_REG,
FT_TP2_REG,
FT_TP3_REG,
FT_TP4_REG,
FT_TP5_REG
};
TouchPointRefTypeDef TPR_Structure;
void FT6236_Scan(void)
{
u8 i=0;
u8 sta = 0;
u8 buf[4] = {0};
FT6236_RD_Reg(0x02,&sta,1);//读取触摸点的状态
if(sta & 0x0f) //判断是否有触摸点按下,0x02寄存器的低4位表示有效触点个数
{
TPR_Structure.TouchSta = ~(0xFF << (sta & 0x0F)); //~(0xFF << (sta & 0x0F))将点的个数转换为触摸点按下有效标志
for(i=0;i<5;i++) //分别判断触摸点1-5是否被按下
{
if(TPR_Structure.TouchSta & (1<<i)) //读取触摸点坐标
{ //被按下则读取对应触摸点坐标数据
FT6236_RD_Reg(FT6236_TPX_TBL,buf,4); //读取XY坐标值
TPR_Structure.x=((u16)(buf[0]&0X0F)<<8)+buf[1];
TPR_Structure.y=((u16)(buf[2]&0X0F)<<8)+buf[3];
if((buf[0]&0XC0)!=0X80)
{
TPR_Structure.x=TPR_Structure.y=0;//必须是contact事件,才认为有效
return;
}
}
}
TPR_Structure.TouchSta |= TP_PRES_DOWN; //触摸按下标记
}
else
{
if(TPR_Structure.TouchSta &TP_PRES_DOWN) //之前是被按下的
TPR_Structure.TouchSta &= ~0x80; //触摸松开标记
else
{
TPR_Structure.x[0] = 0;
TPR_Structure.y[0] = 0;
TPR_Structure.TouchSta &=0xe0; //清楚触摸点有效标记
}
}
}
/* EINT callback, to be invoked when EINT triggers. */
static void eint_callback(void* parameter, VM_DCL_EVENT event, VM_DCL_HANDLE device_handle)
{
TPR_Structure.TouchSta |= TP_COORD_UD; //触摸坐标有更新
if(TPR_Structure.TouchSta &TP_COORD_UD) //触摸有按下
{
TPR_Structure.TouchSta &= ~TP_COORD_UD; //清标记
FT6236_Scan(); //读取触摸坐标
sprintf(g_buff,"X:\t%d",TPR_Structure.x[0]);
log_info(2, g_buff); /* output log to LCD if have */
sprintf(g_buff,"Y:\t%d",TPR_Structure.y[0]);
log_info(4, g_buff); /* output log to LCD if have */
//printf("\r\n");//插入换行
}
}
/* Attaches EINT */
//static void eint_attach(void)
void eint_attach(void)
{
vm_dcl_eint_control_config_t eint_config;
vm_dcl_eint_control_sensitivity_t sens_data;
vm_dcl_eint_control_hw_debounce_t deboun_time;
VM_DCL_STATUS status;
/* Resets the data structures */
memset(&eint_config,0, sizeof(vm_dcl_eint_control_config_t));
memset(&sens_data,0, sizeof(vm_dcl_eint_control_sensitivity_t));
memset(&deboun_time,0, sizeof(vm_dcl_eint_control_hw_debounce_t));
/* Opens and attaches VM_PIN_EINT EINT */
g_eint_handle = vm_dcl_open(VM_DCL_EINT, PIN2EINT(VM_PIN_EINT));
if(VM_DCL_HANDLE_INVALID == g_eint_handle)
{
sprintf(g_buff,"open EINT error");log_info(3, g_buff);
return;
}
/* Usually, before configuring the EINT, we mask it firstly. */
status = vm_dcl_control(g_eint_handle, VM_DCL_EINT_COMMAND_MASK, NULL);
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_COMMAND_MASK = %d", status);log_info(3, g_buff);
}
/* Registers the EINT callback */
status = vm_dcl_register_callback(g_eint_handle, VM_DCL_EINT_EVENT_TRIGGER, (vm_dcl_callback)eint_callback, (void*)NULL );
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_EVENT_TRIGGER = %d", status);log_info(3, g_buff);
}
/* Configures a FALLING edge to trigger */
sens_data.sensitivity = 0;
eint_config.act_polarity = 0;
/* Sets the auto unmask for the EINT */
eint_config.auto_unmask = 1;
/* Sets the EINT sensitivity */
status = vm_dcl_control(g_eint_handle, VM_DCL_EINT_COMMAND_SET_SENSITIVITY, (void*)&sens_data);
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_COMMAND_SET_SENSITIVITY = %d", status);log_info(3, g_buff);
}
/* Sets debounce time to 1ms */
deboun_time.debounce_time = 1;
/* Sets debounce time */
status = vm_dcl_control(g_eint_handle, VM_DCL_EINT_COMMAND_SET_HW_DEBOUNCE, (void*)&deboun_time);
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_COMMAND_SET_HW_DEBOUNCE = %d", status);log_info(3, g_buff);
}
/* Usually, before configuring the EINT, we mask it firstly. */
status = vm_dcl_control(g_eint_handle, VM_DCL_EINT_COMMAND_MASK, NULL);
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_COMMAND_MASK = %d", status);log_info(3, g_buff);
}
/* 1 means enabling the HW debounce; 0 means disabling. */
eint_config.debounce_enable = 1;
/* Make sure to call this API at the end as the EINT will be unmasked in this statement. */
status = vm_dcl_control(g_eint_handle, VM_DCL_EINT_COMMAND_CONFIG, (void*)&eint_config);
if(status != VM_DCL_STATUS_OK)
{
sprintf(g_buff,"VM_DCL_EINT_COMMAND_CONFIG = %d", status);log_info(3, g_buff);
}
}
void test(){
log_info(6,"test");
}
补充内容 (2016-5-17 15:00):
thx |
|