本帖最后由 lulugl 于 2024-7-1 13:09 编辑
【任务目标】
驱动i2c总线,实现数据的发送与读取,本实验驱动i2c的OLED屏,读取sht31的温湿度,并实现显示。
【实验器材】
1、英飞凌CYW20829评估版。
2、OLED显示屏
3、sht31温湿度计。
【实验步骤】
1、新建一个基本i2c的基本示例。在示例中,初始化了i2c总线,SDA为P4.0,SCL为P4.1。在示例中先声明了i2c的结构,并对其进行赋值。
mI2C_cfg.is_slave = false;
mI2C_cfg.address = 0;
mI2C_cfg.frequencyhal_hz = I2C_FREQ;
/* Init I2C master */
result = cyhal_i2c_init(&mI2C, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
/* I2C master init failed. Stop program execution */
handle_error(result);
/* Configure I2C Master */
result = cyhal_i2c_configure(&mI2C, &mI2C_cfg);
/* I2C master configuration failed. Stop program execution */
handle_error(result);
2、创建ssd1306的文件夹,并实现对OLED的写命令函数:
static uint8_t ssd1306_WriteCommand(cyhal_i2c_t *hi2c, uint8_t command)
{
return cyhal_i2c_master_mem_write(hi2c, SSD1306_I2C_ADDR, 0x00, 1, &command, 1, 10);
}
3、其余的代码均为公版的驱动,无需更多的变动。
4、创建sht3x.c/h函数,也实现sht3x的读写驱动,代码如下:
static bool sht3x_send_command(sht3x_handle_t *handle, sht3x_command_t command)
{
uint8_t command_buffer[2] = {(command & 0xff00u) >> 8u, command & 0xffu};
if (cyhal_i2c_master_write(handle->i2c_handle, handle->device_address << 1u, command_buffer, sizeof(command_buffer),
SHT3X_I2C_TIMEOUT, true) != CY_RSLT_SUCCESS) {
return false;
}
return true;
}
bool sht3x_read_temperature_and_humidity(sht3x_handle_t *handle, float *temperature, float *humidity)
{
sht3x_send_command(handle, SHT3X_COMMAND_MEASURE_HIGHREP_STRETCH);
cyhal_system_delay_ms(1);
uint8_t buffer[6];
if (cyhal_i2c_master_read(handle->i2c_handle, handle->device_address << 1u, buffer, sizeof(buffer), SHT3X_I2C_TIMEOUT, true) != CY_RSLT_SUCCESS) {
return false;
}
uint8_t temperature_crc = calculate_crc(buffer, 2);
uint8_t humidity_crc = calculate_crc(buffer + 3, 2);
if (temperature_crc != buffer[2] || humidity_crc != buffer[5]) {
return false;
}
uint16_t temperature_raw = uint8_to_uint16(buffer[0], buffer[1]);
uint16_t humidity_raw = uint8_to_uint16(buffer[3], buffer[4]);
*temperature = -45.0f + 175.0f * (float)temperature_raw / 65535.0f;
*humidity = 100.0f * (float)humidity_raw / 65535.0f;
return true;
}
英飞凌的i2c硬件读写,与stm32的hal库一样,也给了一次性写多个数据的函数封装,使用起来,非常之方便。
整体的代码结构如下:
【主函数代码】
主函数中,主要是初始化ssd1306与sht3x,然后在大循环中读取与显示数据,其代码如下:
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "ssd1306.h"
#include "sht3x.h"
/*******************************************************************************
* Macros
*******************************************************************************/
/* Delay of 1000ms between commands */
#define CMD_TO_CMD_DELAY (1000UL)
/* Packet positions */
#define PACKET_SOP_POS (0UL)
#define PACKET_CMD_POS (1UL)
#define PACKET_EOP_POS (2UL)
/* Start and end of packet markers */
#define PACKET_SOP (0x01UL)
#define PACKET_EOP (0x17UL)
/* I2C slave address to communicate with */
#define I2C_SLAVE_ADDR (0x78UL)
/* I2C bus frequency */
#define I2C_FREQ (400000UL)
/* Command valid status */
#define STATUS_CMD_DONE (0x00UL)
/* Packet size */
#define PACKET_SIZE (3UL)
#ifdef XMC7200D_E272K8384
#define KIT_XMC72
#endif
/*******************************************************************************
* Global Variables
*******************************************************************************/
cyhal_i2c_t mI2C;
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/*******************************************************************************
* Function Definitions
*******************************************************************************/
/*******************************************************************************
* Function Name: handle_error
********************************************************************************
* Summary:
* User defined error handling function
*
* Parameters:
* uint32_t status - status indicates success or failure
*
* Return:
* void
*
*******************************************************************************/
void handle_error(uint32_t status)
{
if (status != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
}
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function.
* 1. I2C Master sends command packet to the slave
* 2. I2C Master reads the response packet to generate the next command
*
* Parameters:
* void
*
* Return:
* int
*
*******************************************************************************/
int main(void)
{
cy_rslt_t result;
cyhal_i2c_cfg_t mI2C_cfg;
uint8_t cmd = CYBSP_LED_STATE_ON;
uint8_t show_buff[64];
/* Initialize the device and board peripherals */
result = cybsp_init();
/* Board init failed. Stop program execution */
handle_error(result);
#if defined(KIT_XMC72)
/*Configure clock settings for KIT_XMC72_EVK */
cyhal_clock_t clock_fll, clock_hf, clock_peri;
result = cyhal_clock_reserve(&clock_hf, &CYHAL_CLOCK_HF[0]);
result = cyhal_clock_reserve(&clock_fll, &CYHAL_CLOCK_FLL);
if(result == CY_RSLT_SUCCESS){
result = cyhal_clock_set_source(&clock_hf, &clock_fll);
}
/* Set divider to 1 for Peripheral Clock */
result = cyhal_clock_reserve(&clock_peri, CYHAL_CLOCK_PERI);
if(result == CY_RSLT_SUCCESS){
result = cyhal_clock_set_divider(&clock_peri,1);
}
#endif
/* Initialize the retarget-io */
result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
CY_RETARGET_IO_BAUDRATE);
/* Retarget-io init failed. Stop program execution */
handle_error(result);
/* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
printf("\x1b[2J\x1b[;H");
printf("****************** "
"HAL: I2C Master "
"****************** \r\n\n");
/* I2C Master configuration settings */
printf(">> Configuring I2C Master..... ");
mI2C_cfg.is_slave = false;
mI2C_cfg.address = 0;
mI2C_cfg.frequencyhal_hz = I2C_FREQ;
/* Init I2C master */
result = cyhal_i2c_init(&mI2C, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
/* I2C master init failed. Stop program execution */
handle_error(result);
/* Configure I2C Master */
result = cyhal_i2c_configure(&mI2C, &mI2C_cfg);
/* I2C master configuration failed. Stop program execution */
handle_error(result);
printf("Done\r\n\n");
if (ssd1306_Init(&mI2C) != 0) {
printf("erro\r\n\n");
handle_error(1);
}
cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
ssd1306_Fill(Black);
ssd1306_UpdateScreen(&mI2C);
// Write data to local screenbuffer
ssd1306_SetCursor(0, 0);
ssd1306_WriteString("ssd1306", Font_11x18, White);
cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
ssd1306_SetCursor(0, 36);
ssd1306_WriteString("4ilo", Font_11x18, White);
ssd1306_UpdateScreen(&mI2C);
// Create the handle for the sensor.
sht3x_handle_t handle = {
.i2c_handle = &mI2C,
.device_address = SHT3X_I2C_DEVICE_ADDRESS_ADDR_PIN_LOW
};
// Initialise sensor (tests connection by reading the status register).
if (!sht3x_init(&handle)) {
printf("SHT3x access failed.\n\r");
}
// Read temperature and humidity.
float temperature, humidity;
/* Enable interrupts */
__enable_irq();
for (;;)
{
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_WriteString("CYW92 sht3x", Font_11x18, White);
sht3x_read_temperature_and_humidity(&handle, &temperature, &humidity);
ssd1306_SetCursor(0, 24);
ssd1306_WriteString("Temp:", Font_11x18, White);
ssd1306_SetCursor(0, 42);
ssd1306_WriteString("HUM:", Font_11x18, White);
ssd1306_SetCursor(52, 24);
sprintf(show_buff,"%.2fC",temperature);
ssd1306_WriteString(show_buff, Font_11x18, White);
sprintf(show_buff,"%.2f%",humidity);
ssd1306_SetCursor(52, 42);
ssd1306_WriteString(show_buff, Font_11x18, White);
ssd1306_UpdateScreen(&mI2C);
cyhal_system_delay_ms(500);
printf("Initial temperature: %.2fC, humidity: %.2f%%RH\n\r", temperature, humidity);
}
}
【实验效果】
|
此文章已获得独家原创/原创奖标签,著作权归21ic所有,未经允许禁止转载。
|