4339|5

58

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【雅特力AT32F421评测】女友般的I2C [复制链接]

 

        IIC也是非常常用的一个外设,虽然速度不快,但胜在只需要两个管脚就搞定,还有应答机制。                              细想想IIC像极了女票,你回到家,女友给你声问候(起始信号),提到你的名字(addr地址)等你回应,然后和你倒一段苦水,再等你回应,再接着倒,再等你回应,如果她说完之前不理她了,一会她就不高兴了(应答错误)然后和你说了声不理你了(停止位)然后就dy外放去了,有时候交流不畅,女友生气了哄起来也头痛(总线死锁)。所以还是纸片人好。

        后面需要用到矩阵按键,又不想mcu太累,还是招个专门的ic来负责吧!tb市场转了一圈,最后谈妥了沁恒的CH450,兼容I2C,最高2M,这价格还要啥自行车了。还有个国产的xxx来着uart接口,运费10元,果断推掉。

                下面来看下具体代码USER下新建drv_i2c.c和drv_i2c.h

  • /* Includes ------------------------------------------------------------------*/
  • #include "at32f4xx.h"
  • #include "drv_i2c.h"
  • #include "at32_board.h"
  • #include <rthw.h>
  • #include <rtthread.h>
  • /**
  • * [url=home.php?mod=space&uid=159083]@brief[/url] I2C Timeout definition
  • */
  • #define I2C_TIMEOUT_FLAG ((uint32_t)35) /* Timeout 35 ms */
  • #define I2C_TIMEOUT_ADDR_SLAVE ((uint32_t)10000) /* Timeout 10 s */
  • #define I2C_TIMEOUT_BUSY_FLAG ((uint32_t)10000) /* Timeout 10 s */
  • /**
  • * @brief I2C Event check flag definition
  • */
  • #define I2C_EVT_CHECK_NONE ((uint32_t)0x00000000)
  • #define I2C_EVT_CHECK_ACKFAIL ((uint32_t)0x00000001)
  • #define I2C_EVT_CHECK_STOP ((uint32_t)0x00000002)
  • /**
  • * @brief us delay used by the I2C.
  • * @param us: delay x us.
  • * @retval None
  • */
  • void I2C_Delay(uint32_t us)
  • {
  • us *= 300;
  • while(us!=0){
  • us--;
  • }
  • }
  • /** @brief Clears the I2C ADDR pending flag.
  • * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
  • * @retval None
  • */
  • void I2C_ClearADDRFlag(I2C_Type* I2Cx)
  • {
  • __IO uint32_t tmpreg;
  • tmpreg = I2Cx->STS1;
  • tmpreg = I2Cx->STS2;
  • }
  • /** @brief Clears the I2C STOPF pending flag.
  • * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
  • * @retval None
  • */
  • void I2C_ClearSTOPFlag(I2C_Type* I2Cx)
  • {
  • __IO uint32_t tmpreg;
  • tmpreg = I2Cx->STS1;
  • tmpreg = I2Cx->CTRL1 |= I2C_CTRL1_PEN;
  • }
  • /**
  • * @brief This function handles I2C Communication Timeout.
  • * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
  • * @param Flag: specifies the I2C flag to check.
  • * @param Status: The new Flag status (SET or RESET).
  • * @param Timeout Timeout duration.
  • * @retval I2C status.
  • */
  • static I2C_StatusType I2C_WaitOnFlagUntilTimeout(I2C_Type* I2Cx, uint32_t Flag, FlagStatus Status, uint32_t EventCheck, uint32_t Timeout)
  • {
  • /* delay 10 us = ms * 100 */
  • Timeout *= 100;
  • while(I2C_GetFlagStatus(I2Cx, Flag) == Status)
  • {
  • /* Check ACKFAIL Flag */
  • if(EventCheck & I2C_EVT_CHECK_ACKFAIL)
  • {
  • if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_ACKFAIL) == SET)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • /* Clear AF Flag */
  • I2C_ClearFlag(I2Cx, I2C_FLAG_ACKFAIL);
  • return I2C_ERROR;
  • }
  • }
  • /* Check STOP Flag */
  • if(EventCheck & I2C_EVT_CHECK_STOP)
  • {
  • if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF) == SET)
  • {
  • /* Clear STOP Flag */
  • I2C_ClearSTOPFlag(I2Cx);
  • return I2C_ERROR;
  • }
  • }
  • /* 10 us delay */
  • I2C_Delay(10);
  • /* Check for the Timeout */
  • if((Timeout--) == 0)
  • {
  • return I2C_TIMEOUT;
  • }
  • }
  • return I2C_OK;
  • }
  • /**
  • * @brief I2C初始化
  • * @param None
  • * @retval None
  • */
  • void I2Cx_Init(void)
  • {
  • GPIO_InitType GPIO_InitStructure;
  • I2C_InitType I2C_InitStructure;
  • /* I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */
  • RCC_AHBPeriphClockCmd(I2C_GPIO_CLK , ENABLE);
  • /* 启用I2C时钟 */
  • RCC_APB1PeriphClockCmd(I2C_CLK, ENABLE);
  • /* GPIO configuration */
  • GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  • GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  • GPIO_InitStructure.GPIO_OutType = GPIO_OutType_OD;
  • GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
  • /* Configure I2C pins: SCL */
  • GPIO_InitStructure.GPIO_Pins = I2C_SCL_PIN;
  • GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  • /* Configure I2C pins: SDA */
  • GPIO_InitStructure.GPIO_Pins = I2C_SDA_PIN;
  • GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
  • /*引脚复用到IIC*/
  • GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_GPIO_PinsSource, I2C_SCL_GPIO_GPIO_AF);
  • GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_GPIO_PinsSource, I2C_SDA_GPIO_GPIO_AF);
  • /* I2C configuration */
  • I2C_InitStructure.I2C_Mode = I2C_Mode_I2CDevice;
  • I2C_InitStructure.I2C_FmDutyCycle = I2C_FmDutyCycle_2_1;
  • I2C_InitStructure.I2C_OwnAddr1 = I2C_SLAVE_ADDRESS7;
  • I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  • I2C_InitStructure.I2C_AddrMode = I2C_AddrMode_7bit;
  • I2C_InitStructure.I2C_BitRate = I2C_SPEED;
  • /* IIC初始化 */
  • I2C_Init(I2C_PORT, &I2C_InitStructure);
  • /* 启用I2C */
  • I2C_Cmd(I2C_PORT, ENABLE);
  • }
  • /**
  • * @brief Receives in master mode an amount of data in blocking mode.
  • * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
  • * @param DevAddress Target device address.
  • * @param pData Pointer to data buffer.
  • * @param Size Amount of data to be sent.
  • * @param Timeout Timeout duration.
  • * @retval I2C status.
  • */
  • I2C_StatusType I2C_Receive(I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
  • {
  • /* Step 1: Wait until BUSY flag is reset */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
  • {
  • return I2C_ERROR_STEP_1;
  • }
  • /* Disable Pos */
  • I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
  • /* Enable Acknowledge */
  • I2C_AcknowledgeConfig(I2Cx, ENABLE);
  • /* Send START condition */
  • I2C_GenerateSTART(I2Cx, ENABLE);
  • /* Wait until SB flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_2;
  • }
  • /* Send slave address for write */
  • I2C_Send7bitAddress(I2Cx, DevAddress, I2C_Direction_Receive);
  • /* Wait until ADDR flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_3;
  • }
  • if(Size == 1)
  • {
  • /* Disable Acknowledge */
  • I2C_AcknowledgeConfig(I2Cx, DISABLE);
  • /* Clear ADDR flag */
  • I2C_ClearADDRFlag(I2Cx);
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • }
  • else if(Size == 2)
  • {
  • /* Enable Pos */
  • I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);
  • /* Disable Acknowledge */
  • I2C_AcknowledgeConfig(I2Cx, DISABLE);
  • /* Clear ADDR flag */
  • I2C_ClearADDRFlag(I2Cx);
  • }
  • else
  • {
  • /* Enable Acknowledge */
  • I2C_AcknowledgeConfig(I2Cx, ENABLE);
  • /* Clear ADDR flag */
  • I2C_ClearADDRFlag(I2Cx);
  • }
  • while(Size > 0)
  • {
  • if(Size <= 3)
  • {
  • /* One byte */
  • if(Size == 1)
  • {
  • /* Wait until RXNE flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_4;
  • }
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • }
  • /* Two bytes */
  • else if(Size == 2)
  • {
  • /* Wait until BTF flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_5;
  • }
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • }
  • /* 3 Last bytes */
  • else
  • {
  • /* Wait until BTF flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_6;
  • }
  • /* Disable Acknowledge */
  • I2C_AcknowledgeConfig(I2Cx, DISABLE);
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • /* Wait until BTF flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_7;
  • }
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • }
  • }
  • else
  • {
  • /* Wait until RXNE flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_8;
  • }
  • /* Read data from DR */
  • (*pData++) = I2C_ReceiveData(I2Cx);
  • Size--;
  • }
  • }
  • return I2C_OK;
  • }
  • /**
  • * @brief Transmits in master mode an amount of data in blocking mode.
  • * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
  • * @param DevAddress Target device address.
  • * @param pData Pointer to data buffer.
  • * @param Size Amount of data to be sent.
  • * @param Timeout Timeout duration.
  • * @retval I2C status.
  • */
  • I2C_StatusType I2C_Transmit(I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
  • {
  • /* Wait until BUSY flag is reset */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
  • {
  • return I2C_ERROR_STEP_1;
  • }
  • /* Disable Pos */
  • I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
  • /* Send START condition */
  • I2C_GenerateSTART(I2Cx, ENABLE);
  • /* Wait until SB flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_2;
  • }
  • /* Send address for write */
  • I2C_Send7bitAddress(I2Cx, DevAddress, I2C_Direction_Transmit);
  • /* Wait until ADDR flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_3;
  • }
  • /* Clear ADDR flag */
  • I2C_ClearADDRFlag(I2Cx);
  • while(Size > 0)
  • {
  • /* Wait until TDE flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_4;
  • }
  • /* Write data to DR */
  • I2C_SendData(I2Cx, (*pData++));
  • Size--;
  • }
  • /* Wait until BTF flag is set */
  • if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  • {
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_ERROR_STEP_5;
  • }
  • /* Send STOP Condition */
  • I2C_GenerateSTOP(I2Cx, ENABLE);
  • return I2C_OK;
  • }
  • /**
  • * @}
  • */
  • /**
  • * @}
  • */

        懒得写,直接拷的例程中的代码,封装了发送和接收函数(有点想念HAL库了)

  • /* Define to prevent recursive inclusion -------------------------------------*/
  • #ifndef __AT32F4XX_I2C_EX_H
  • #define __AT32F4XX_I2C_EX_H
  • /* Includes ------------------------------------------------------------------*/
  • #include "at32f4xx.h"
  • /**
  • * @brief I2C Status structures definition
  • */
  • typedef enum
  • {
  • I2C_OK = 0,
  • I2C_ERROR_STEP_1 = 1,
  • I2C_ERROR_STEP_2 = 2,
  • I2C_ERROR_STEP_3 = 3,
  • I2C_ERROR_STEP_4 = 4,
  • I2C_ERROR_STEP_5 = 5,
  • I2C_ERROR_STEP_6 = 6,
  • I2C_ERROR_STEP_7 = 7,
  • I2C_ERROR_STEP_8 = 8,
  • I2C_ERROR_STEP_9 = 9,
  • I2C_ERROR_STEP_10 = 10,
  • I2C_ERROR_STEP_11 = 11,
  • I2C_ERROR_STEP_12 = 12,
  • I2C_BUSY = 100,
  • I2C_TIMEOUT = 101,
  • I2C_ERROR = 102,
  • } I2C_StatusType;
  • /**
  • * @}
  • */
  • /* Exported constants --------------------------------------------------------*/
  • /** @defgroup I2C_Exported_Constants I2C Exported Constants
  • * @{
  • */
  • /**
  • * @brief I2C Parameter definition
  • */
  • #define I2C_SPEED 100000
  • #define I2C_SLAVE_ADDRESS7 0xB0
  • #define I2C_EEAddress 0xB0
  • /**
  • * @brief I2C Interface pins
  • */
  • #define I2C_PORT I2C1
  • #define I2C_CLK RCC_APB1PERIPH_I2C1
  • #define I2C_SCL_PIN GPIO_Pins_8 /* PB.8 */
  • #define I2C_SCL_GPIO_PORT GPIOB /* GPIOB */
  • #define I2C_GPIO_CLK RCC_AHBPERIPH_GPIOB
  • #define I2C_SCL_GPIO_PinsSource GPIO_PinsSource8
  • #define I2C_SCL_GPIO_GPIO_AF GPIO_AF_1
  • #define I2C_SDA_PIN GPIO_Pins_9 /* PB.9*/
  • #define I2C_SDA_GPIO_PORT GPIOB /* GPIOB */
  • #define I2C_SDA_GPIO_PinsSource GPIO_PinsSource9
  • #define I2C_SDA_GPIO_GPIO_AF GPIO_AF_1
  • /**
  • * @}
  • */
  • /* Exported macro ------------------------------------------------------------*/
  • /** @defgroup I2C_Exported_Macros I2C Exported Macros
  • * @{
  • */
  • #define MASTER_BOARD
  • /**
  • * @}
  • */
  • /* Exported variables ------------------------------------------------------- */
  • /* Exported functions ------------------------------------------------------- */
  • /** @addtogroup I2C_Exported_Functions
  • * @{
  • */
  • void I2Cx_Init(void);
  • I2C_StatusType I2C_Receive (I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
  • I2C_StatusType I2C_Transmit(I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
  • /**
  • * @}
  • */
  • #endif /* __I2C_H */

           还要新建CH450.c和。h文件来写ch450的驱动

  • #include "CH450.h"
  • #include "at32f4xx.h"
  • #include "drv_i2c.h"
  • #include <rtthread.h>
  • I2C_StatusType I2C_Status;
  • void CH450_Write(uint8_t cmd) //写参数
  • {
  • I2C_Status = I2C_Transmit(I2C_PORT, CH450_Write_ADDR, &cmd, 1, 1000);
  • rt_kprintf("I2C_Status:%d\r\n",I2C_Status);
  • }
  • unsigned char CH450_Read(void) //读取按键
  • {
  • unsigned char keycode;
  • I2C_Receive(I2C_PORT, CH450_Read_ADDR, &keycode, 1, 1000);
  • return(keycode);
  • }
  • void CH450_Init(void) //初始化
  • {
  • CH450_Write(CH450_SYSON2); //只开启按键
  • }
  • #ifndef __CH450_H
  • #define __CH450_H
  • #include "stdint.h"
  • /*
  • * 命令字节参数设定
  • *
  • * D7 D6 D5 D4 D3 D2 D1 D0
  • * SLEEP INTENS 0 0 0 KEYB DISP
  • *
  • * 设置系统参数命令用于设定 CH450 的系统级参数:显示驱动使能 DISP、键盘扫描使能 KEYB、显示驱动亮度控制 INTENS、低功耗睡眠控制 SLEEP。
  • *
  • * SLEEP 用于使 CH450 进入低功耗睡眠状态,从而可以节约电能。处于低功耗睡眠状态中的 CH450
  • *可以被下述两种事件中的任何一种唤醒,第一种事件是检测到 SEG3~SEG0 上的按键,有效按键代码
  • *是 42H 到 5FH;第二种事件是接收到单片机发出的下一个操作命令。当 CH450 被唤醒后,SLEEP 位会
  • *自动清 0。睡眠和唤醒操作本身不会影响 CH450 的其它工作状态。如果 KEYB 位为 1 则唤醒后产生按
  • *键中断,如果 KEYB 位为 0 则唤醒后不产生按键中断。
  • *
  • * INTENS 用于控制显示驱动的亮度,包含两位数据,有 4 种组合:数据 00、01、10 分别设置
  • *显示驱动占空比为 4/4、1/4、2/4,并且启用内部的段驱动限流;数据 11 设置显示驱动占空比为 4/4,
  • *但是禁止内部的段驱动限流,所以外部需要在段引脚串接限流电阻 R0。
  • *
  • * 当 KEYB 位为 1 时启用键盘扫描,当 KEYB 位为 0 时关闭键盘扫描。
  • *
  • * 当 DISP 位为 1 时允许显示输出,当 DISP 位为 0 时关闭显示驱动.
  • */
  • /* CH450的常用命令码,如果考虑与I2C兼容,那么高8位应该右移1位 */
  • #define CH450_SYSOFF 0x00 // 关闭显示、关闭键盘
  • #define CH450_SYSON1 0x01 // 开启显示
  • #define CH450_SYSON2 0x03 // 开启显示、键盘
  • #define CH450_SYSON3 0x22 // 关闭显示、开启键盘
  • #define CH450_GET_KEY 0x0700 // 获取按键,返回按键代码
  • #define CH450_DIG2 0x1200 // 数码管位2显示,需另加8位数据
  • #define CH450_DIG3 0x1300 // 数码管位3显示,需另加8位数据
  • #define CH450_DIG4 0x1400 // 数码管位4显示,需另加8位数据
  • #define CH450_DIG5 0x1500 // 数码管位5显示,需另加8位数据
  • #define CH450_DIG6 0x1600 // 数码管位6显示,需另加8位数据
  • #define CH450_DIG7 0x1700 // 数码管位7显示,需另加8位数据
  • // CH450地址定义
  • #define CH450_Write_ADDR 0x48 // 设置命令地址
  • #define CH450_Read_ADDR 0x4F // 读取按键地址
  • #define CH450_DIG2_ADDR 0x64 // DIG2字命令
  • #define CH450_DIG3_ADDR 0x66 // DIG3字命令
  • #define CH450_DIG4_ADDR 0x68 // DIG4字命令
  • #define CH450_DIG5_ADDR 0x6A // DIG5字命令
  • #define CH450_DIG6_ADDR 0x6C // DIG6字命令
  • #define CH450_DIG7_ADDR 0x6E // DIG7字命令
  • unsigned char CH450_Read(void); // 从CH450读取按键代码
  • void CH450_Write(uint8_t cmd); // 向CH450发出操作命令
  • void CH450_Init(void); //初始化
  • #endif

main中创建线程之后延时1秒让CH450稳定复位

  • int main(void)
  • {
  • /* 创建ADC线程 */
  • ADC_thread = rt_thread_create("ADC", /* 线程名字 */
  • ADC_thread_entry, /* 线程入口函数 */
  • RT_NULL, /* 线程入口函数参数 */
  • sizeof(ADC_stack), /* 线程栈大小 */
  • 4, /* 线程的优先级 */
  • 10); /* 线程时间片 */
  • /* 启动线程,开启调度 */
  • if (ADC_thread != RT_NULL)
  • rt_thread_startup(ADC_thread);
  • /*CH450复位延时*/
  • rt_thread_mdelay(1000);
  • /*只开启按键扫描*/
  • CH450_Write(0x22);
  • return 0;
  • }

        线程中定期读取按键编码,rt_kprintf貌似也不能输出十六进制,就先输出十进制先验证下功能吧!

  • static void ADC_thread_entry(void *parameter)
  • {
  • while (1)
  • {
  • if(ADC_GetINTStatus(ADC1, ADC_INT_EC) != RESET){
  • ADC_value = ADC_GetConversionValue(ADC1)*3.3f/4095;//ADC值转电压值
  • OLED_Showdecimal(10,10,ADC_value,2,3,16);、、OLED刷屏
  • OLED_Refresh();
  • ADC_SoftwareStartConvCtrl(ADC1, ENABLE);/* 启动ADC转换 */
  • }
  • rt_kprintf("KEY_Val:%d\r\n",CH450_Read());//十进制打印按键值
  • rt_thread_mdelay(300);
  • }
  • }

按下不同的按键可以看到打印值的改变,

最新回复

谢谢分享女友   详情 回复 发表于 2021-5-26 21:27

赞赏

1

查看全部赞赏

点赞(1) 关注
 
 

回复
举报

2万

帖子

71

TA的资源

管理员

沙发
 

赞楼主的比喻,哈哈,看来感触颇深

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 
 

回复

1938

帖子

2

TA的资源

版主

板凳
 

来看看这个女友般的IIC,哈哈!

 
 
 

回复

1089

帖子

0

TA的资源

纯净的硅(高级)

4
 

资源不够再说,限于本人水平,暂时不考虑,有点绕

个人签名چوآن شـين
 
 
 

回复

6991

帖子

0

TA的资源

五彩晶圆(高级)

5
 

不能输出十六进可能是串口,是不是还未初始化就先给rt_kprintf指定了输出的串口,没有指定rt_kprintf的输出串口。

IIC像极了女票,,真逗

 
 
 

回复

7755

帖子

2

TA的资源

五彩晶圆(高级)

6
 

谢谢分享女友

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
报名最后一周!2025 英飞凌消费、计算与通讯创新大会-北京站
会议时间:3月18日(周二)09:30签到
参会奖励:电动螺丝刀套装、户外登山包、京东卡

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表