- 原理图部分
注意不用的触摸引脚不接灯接到地!
iic脚和中断脚(HI)都要接上拉电阻4.7k
- PCB设计
- 程序设计
芯片可以配置再使用的,本程序host是stm32f429ig,没有开机配置,直接用的芯片默认参数调试。
.c文件
#include "CY8CMBR3108.h"
#include "bsp_lcd.h"
#include "gui.h"
#include "myconfig.h"
//图片库调试用
#include "ScheduleOff.c"
#include "ScheduleOn.c"
#define CY8C_3108_ADDR 0x37
static void i2c_Delay(void)
{
uint8_t i,j;
for (i = 0; i <100; i++);
}
void i2c_Start(void)
{
/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
CY8C_I2C_SDA_1();
CY8C_I2C_SCL_1();
i2c_Delay();
CY8C_I2C_SDA_0();
i2c_Delay();
CY8C_I2C_SCL_0();
i2c_Delay();
}
void i2c_Stop(void)
{
/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
CY8C_I2C_SDA_0();
CY8C_I2C_SCL_1();
i2c_Delay();
CY8C_I2C_SDA_1();
}
void i2c_SendByte(uint8_t _ucByte)
{
uint8_t i;
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
CY8C_I2C_SDA_1();
}
else
{
CY8C_I2C_SDA_0();
}
i2c_Delay();
CY8C_I2C_SCL_1();
i2c_Delay();
CY8C_I2C_SCL_0();
if (i == 7)
{
CY8C_I2C_SDA_1(); // 释放总线
}
_ucByte <<= 1; /* 左移一个bit */
i2c_Delay();
}
}
uint8_t i2c_WaitAck(void)
{
uint8_t re;
CY8C_I2C_SDA_1(); /* CPU释放SDA总线 */
i2c_Delay();
CY8C_I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
i2c_Delay();
if (EEPROM_I2C_SDA_READ()) /* CPU读取SDA口线状态 */
{
re = 1;
}
else
{
re = 0;
}
CY8C_I2C_SCL_0();
i2c_Delay();
return re;
}
uint8_t i2c_ReadByte(void)
{
uint8_t i;
uint8_t value;
/* 读到第1个bit为数据的bit7 */
value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1;
CY8C_I2C_SCL_1();
i2c_Delay();
if (EEPROM_I2C_SDA_READ())
{
value++;
}
CY8C_I2C_SCL_0();
i2c_Delay();
}
return value;
}
void i2c_Ack(void)
{
CY8C_I2C_SDA_0(); /* CPU驱动SDA = 0 */
i2c_Delay();
CY8C_I2C_SCL_1(); /* CPU产生1个时钟 */
i2c_Delay();
CY8C_I2C_SCL_0();
i2c_Delay();
CY8C_I2C_SDA_1(); /* CPU释放SDA总线 */
}
void i2c_NAck(void)
{
CY8C_I2C_SDA_1(); /* CPU驱动SDA = 1 */
i2c_Delay();
CY8C_I2C_SCL_1(); /* CPU产生1个时钟 */
i2c_Delay();
CY8C_I2C_SCL_0();
i2c_Delay();
}
//中断口PC11中断优先级设置
void CY8CMBR3106S_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC为优先级组1 */
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*Int*/
/* 配置中断源:按键1 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
/* 配置抢占优先级:1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
/* 配置子优先级:1 */
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_CY8CMBR3106S_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
/*开启按键GPIO口的时钟*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC ,ENABLE);
/* 使能 SYSCFG 时钟 ,使用GPIO外部中断时必须使能SYSCFG时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 配置 NVIC */
CY8CMBR3106S_NVIC_Configuration();
/* 选择按键1的引脚 */
// GPIO_InitStructure.GPIO_Pin = FT6236_INT_PIN;
// /* 设置引脚为输入模式 */
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
// /* 设置引脚不上拉也不下拉 */
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// /* 使用上面的结构体初始化按键 */
// GPIO_Init(FT6236_INT_GPIO_PORT, &GPIO_InitStructure);
/* 连接 EXTI 中断源 到key1引脚 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource11);
/* 选择 EXTI 中断源 */
EXTI_InitStructure.EXTI_Line = EXTI_Line11;
/* 中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 下降沿触发 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中断/事件线 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
static void i2c_CfgGpio(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC,ENABLE);
//pa15--scl pc10--sda
/*SCL*/
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; /* 开漏输出 */
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*SDA*/
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; /* 开漏输出 */
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
EXTI_CY8CMBR3106S_Config();
i2c_Stop();
}
void CY8C_3108_CheckDevice(unsigned char _ADDR)
{
unsigned char u8;
u8=0;
i2c_Start(); /* 发送启动信号 */
i2c_SendByte(_ADDR<<1);
while( i2c_WaitAck()) /* 检测设备的ACK应答 */
{
i2c_Start(); /* 发送启动信号 */
i2c_SendByte(_ADDR<<1);
// printf("\r\ncheck没有应答\r\n");
RS485_EN(1);
USART_SendData(RS485_USART,0x44);
while (USART_GetFlagStatus(RS485_USART, USART_FLAG_TXE) == RESET);
}
i2c_Stop(); /* 发送停止信号 */
}
//读取键值
uint16_t CY8CMBR3106S_ReadOneByte(void)
{
uint8_t high=0,low=0;
uint16_t key_value=0;
// delay_us(100);
// for(int i=0;i<255;i++)
// {
// for(int j=0;j<255;j++)
// {
// for(int x=0;x<255;x++)
// {
// ;
// }
// }
// }
//设置器件数据指针
i2c_Start();
i2c_SendByte(CY8C_3108_ADDR<<1);
while( i2c_WaitAck()) /* 检测设备的ACK应答 */
{
i2c_Start(); /* 发送启动信号 */
i2c_SendByte(CY8C_3108_ADDR<<1);
printf("\r\n等待设置器件数据指针回复应答信号1\r\n");
}
// i2c_SendByte(0x90);
i2c_SendByte(0xaa);
while( i2c_WaitAck()) /* 检测设备的ACK应答 */
{
//没有输出log说明收到应答
printf("\r\n等待设置器件数据指针回复应答信号2\r\n");
}
i2c_Stop();
//读取键值操作start
i2c_Start();
i2c_SendByte((CY8C_3108_ADDR<<1)|0x01);
while( i2c_WaitAck()) /* 检测设备的ACK应答 */
{
i2c_SendByte((CY8C_3108_ADDR<<1)|0x01);
//没有输出log说明收到应答
printf("\r\n读取键值操作回复应答信号1\r\n");
}
for(int x=0;x<255;x++)
{
;
}
low = i2c_ReadByte();
i2c_Ack();
high = i2c_ReadByte();
i2c_NAck();
i2c_Stop();
key_value =( high<<8)| low;
//读取键值操作end
return key_value;
}
void Yijiu98Test(void *pvParameters)
{
unsigned char keyvalue;
vTaskDelay( 50);
i2c_CfgGpio(); /* 配置IIC-GPIO */
CY8C_3108_CheckDevice(CY8C_3108_ADDR);
//CY8C_3108_ReadSet();
//CY8C_3108_ReadKeyvalue();
while(1)
{
keyvalue=CY8CMBR3106S_ReadOneByte();
printf("\r\n keyvalud=%x\r\n",keyvalue);
GUI_PNG_Draw(&_acScheduleOn,sizeof(_acScheduleOn),45,110);//排成按钮,调试用
vTaskDelay( 500);
}
}
.h文件
#ifndef __CY8CMBR3108_H_
#define __CY8CMBR3108_H_
#define CY8C_I2C_SCL_1() GPIO_SetBits(GPIOA, GPIO_Pin_15) /* SCL = 1 */
#define CY8C_I2C_SCL_0() GPIO_ResetBits(GPIOA, GPIO_Pin_15) /* SCL = 0 */
#define CY8C_I2C_SDA_1() GPIO_SetBits(GPIOC, GPIO_Pin_10) /* SDA = 1 */
#define CY8C_I2C_SDA_0() GPIO_ResetBits(GPIOC, GPIO_Pin_10) /* SDA = 0 */
#define EEPROM_I2C_SDA_READ() GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_10) /* 读SDA口线状态 */
extern void Yijiu98Test(void *pvParameters);
#endif