delay函数.c和.h文件代码
时间: 2024-12-17 16:19:31 浏览: 26
在C语言中,`delay()` 函数通常用于控制程序的执行速度,尤其是在处理硬件操作需要时间间隔的情况下。它并不是标准库的一部分,所以你需要自定义或者查找特定平台提供的库支持。
首先,让我们看一个简单的`delay.h`头文件示例:
```c
#ifndef DELAY_H
#define DELAY_H
#include <stdio.h>
// 如果是在嵌入式系统或有定时器可用,可能使用这样的延迟函数
void delay(unsigned int milliseconds);
#endif // DELAY_H
```
接下来是`delay.c`文件,这里我们提供了一个基于计数的简单实现:
```c
#include "delay.h"
void delay(unsigned int milliseconds) {
unsigned int i;
for (i = 0; i < milliseconds * 1000; i++);
}
```
如果系统没有内置的延时函数或定时器,上述代码可能会效率较低。在实际应用中,你可能需要依赖更专业的库(如`rtos`或`sys/time.h`),或者直接利用硬件的定时器功能来实现准确的延时。
相关问题
lcd1602的stm32f103c6的代码.c和.h,以及对应的delay.c和.h,says.c和.h
以下是一个简单的LCD1602的STM32F103C6代码,包括了lcd1602.c和lcd1602.h文件,以及对应的delay.c和delay.h,以及says.c和says.h文件。
lcd1602.h文件:
```c
#ifndef __LCD1602_H__
#define __LCD1602_H__
#include "stm32f10x.h"
#define LCD1602_GPIO_RCC RCC_APB2Periph_GPIOB //LCD1602所在GPIO的时钟
#define LCD1602_GPIO GPIOB //LCD1602所在GPIO
#define LCD1602_E_PIN GPIO_Pin_0 //LCD1602的E引脚
#define LCD1602_RS_PIN GPIO_Pin_1 //LCD1602的RS引脚
#define LCD1602_RW_PIN GPIO_Pin_2 //LCD1602的RW引脚
#define LCD1602_DATA_PINS GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6 //LCD1602的数据引脚
void LCD1602_Init(void);
void LCD1602_WriteCmd(uint8_t cmd);
void LCD1602_WriteData(uint8_t data);
void LCD1602_SetCursor(uint8_t x, uint8_t y);
void LCD1602_Clear(void);
void LCD1602_DisplayString(char* str);
void LCD1602_DisplayNum(uint16_t num);
#endif
```
lcd1602.c文件:
```c
#include "lcd1602.h"
#include "delay.h"
//LCD1602初始化函数
void LCD1602_Init(void)
{
RCC_APB2PeriphClockCmd(LCD1602_GPIO_RCC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LCD1602_E_PIN | LCD1602_RS_PIN | LCD1602_RW_PIN | LCD1602_DATA_PINS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LCD1602_GPIO, &GPIO_InitStructure);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RS_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RW_PIN, Bit_RESET);
LCD1602_WriteCmd(0x38);
LCD1602_WriteCmd(0x06);
LCD1602_WriteCmd(0x0C);
LCD1602_WriteCmd(0x01);
}
//LCD1602写命令函数
void LCD1602_WriteCmd(uint8_t cmd)
{
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RS_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RW_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_DATA_PINS, (cmd >> 4) & 0x0F);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_SET);
Delay_us(1);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_DATA_PINS, cmd & 0x0F);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_SET);
Delay_us(1);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_RESET);
Delay_us(50);
}
//LCD1602写数据函数
void LCD1602_WriteData(uint8_t data)
{
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RS_PIN, Bit_SET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_RW_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_DATA_PINS, (data >> 4) & 0x0F);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_SET);
Delay_us(1);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_RESET);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_DATA_PINS, data & 0x0F);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_SET);
Delay_us(1);
GPIO_WriteBit(LCD1602_GPIO, LCD1602_E_PIN, Bit_RESET);
Delay_us(50);
}
//LCD1602设置光标位置函数
void LCD1602_SetCursor(uint8_t x, uint8_t y)
{
uint8_t addr = 0;
if (y == 0) {
addr = 0x00 + x;
} else {
addr = 0x40 + x;
}
LCD1602_WriteCmd(0x80 + addr);
}
//LCD1602清屏函数
void LCD1602_Clear(void)
{
LCD1602_WriteCmd(0x01);
}
//LCD1602显示字符串函数
void LCD1602_DisplayString(char* str)
{
while (*str) {
LCD1602_WriteData(*str++);
}
}
//LCD1602显示数字函数
void LCD1602_DisplayNum(uint16_t num)
{
char str[6];
sprintf(str, "%d", num);
LCD1602_DisplayString(str);
}
```
delay.h文件:
```c
#ifndef __DELAY_H__
#define __DELAY_H__
#include "stm32f10x.h"
void Delay_us(uint32_t us);
void Delay_ms(uint16_t ms);
#endif
```
delay.c文件:
```c
#include "delay.h"
volatile uint32_t g_Ticks;
void SysTick_Handler(void)
{
g_Ticks++;
}
void Delay_us(uint32_t us)
{
uint32_t ticks = us * (SystemCoreClock / 1000000);
uint32_t start = g_Ticks;
while ((g_Ticks - start) < ticks);
}
void Delay_ms(uint16_t ms)
{
while (ms--) {
Delay_us(1000);
}
}
```
says.h文件:
```c
#ifndef __SAYS_H__
#define __SAYS_H__
#include "stm32f10x.h"
void SaysHello(void);
#endif
```
says.c文件:
```c
#include "says.h"
#include "lcd1602.h"
void SaysHello(void)
{
LCD1602_DisplayString("Hello, World!");
}
```
BH1750读取光照值函数,.c和.h的代码
BH1750读取光照值的函数通常会在一个单独的`.c`文件中实现,因为需要操作硬件。假设你使用的是基于I2C的BH1750FVI传感器,下面是一个简化的`.c`文件示例,包括头文件(`bh1750.h`)定义:
**bh1750.h (头文件)**:
```c
#ifndef BH1750_H
#define BH1750_H
#include "stm32f4xx_hal.h"
typedef enum { CMD_MEASUREMENT = 0x12 } Command;
extern I2C_HandleTypeDef hi2c;
extern uint16_t LightLevel;
// 定义函数原型
uint16_t ReadLightFromBH1750();
#endif /* BH1750_H */
```
**bh1750.c (实现文件)**:
```c
#include "bh1750.h"
static const uint8_t BH1750_I2C_ADDRESS = 0x23; // BH1750传感器的I2C地址
// 实现ReadLightFromBH1750函数
uint16_t ReadLightFromBH1750() {
uint16_t lightLevel = 0;
if (HAL_I2C_IsDeviceReady(&hi2c,延时等待时间) == HAL_OK) {
// 开始I2C传输
__HAL_I2C_START(&hi2c);
HAL_I2C_Master_Transmit(&hi2c, BH1750_I2C_ADDRESS, (uint8_t*)&Command::CMD_MEASUREMENT, 1, 1000);
HAL_Delay(10); // 等待测量结果
HAL_I2C_Master_Receive(&hi2c, BH1750_I2C_ADDRESS, (uint8_t*)&lightLevel, 2, 1000);
__HAL_I2C_STOP(&hi2c);
// 将高8位和低8位转换为16位整数
LightLevel = (lightLevel << 8) | HAL_I2C_Mem_Read8(&hi2c, BH1750_I2C_ADDRESS, 1, 1, 1000);
}
return LightLevel;
}
```
在这个例子中,`hi2c`是I2C HAL句柄,`LightLevel`是全局变量用来存储读取的光照值。`ReadLightFromBH1750`函数首先检查I2C是否准备好,然后发送测量命令、等待响应,然后读取两个字节的数据。
在应用程序的`.c`文件中,你需要先初始化I2C,并创建`hi2c`句柄,例如:
```c
// 其他初始化代码...
I2C_HandleTypeDef hi2c;
__HAL_RCC_I2C1_CLK_ENABLE();
hi2c.Instance = I2C1;
hi2c.Init.ClockSpeed = 100000;
hi2c.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c.Init.OwnAddress1 = I2C_OA_NOADDR;
hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c) != HAL_OK) {
// 处理I2C初始化失败
}
```
在main.c或其他合适的地方调用`ReadLightFromBH1750()`函数即可获取光照值。同时,别忘了在适当位置将结果传递给显示模块。
阅读全文